【问题标题】:Generate javascript method call code with ClojureScript macro?使用 ClojureScript 宏生成 javascript 方法调用代码?
【发布时间】:2012-03-27 17:28:39
【问题描述】:

我正在使用 ClojureScript 来检测定义了哪个浏览器特定版本的“requestAnimationFrame”方法。我使用以下代码:

(defn animationFrameMethod []
  (let [window (dom/getWindow)
        options (list #(.-requestAnimationFrame window)
                      #(.-webkitRequestAnimationFrame window)
                      #(.-mozRequestAnimationFrame window)
                      #(.-oRequestAnimationFrame window)
                      #(.-msRequestAnimationFrame window))]
    ((fn [[current & remaining]]
       (cond
        (nil? current) #((.-setTimeout window) % (/ 1000 30))
        (fn? (current)) (current)
        :else (recur remaining)))
     options)))

这很好用,而且并不可怕,但我真的希望能够将方法名称放在一个列表中,即

'(requestAnimationFrame webkitRequestAnimationFrame ...)

然后为列表中的每个符号调用一个宏来生成匿名函数代码。

我想要这样的工作:

user> (def name webkitRequestAnimationFrame)
user> (macroexpand '(macros/anim-method name window))
#(.-webkitRequestAnimationFrame window)

但是我玩了一段时间的宏,并没有达到这个效果。部分问题是方法名称和点符号的工作方式很奇怪,我什至不确定这是否可能。

有什么技巧可以让它工作吗?谢谢!

【问题讨论】:

  • 除非我严重误读了您的代码,否则只要 options 的第一个元素为 nil,您将始终返回 setTimeout 函数。
  • @PhilipK 看起来会,但事实并非如此。如果它们不存在,则调用选项中的函数的结果是未定义的,而不是零。在列表为空之前它不会为 nil。

标签: html canvas macros clojure clojurescript


【解决方案1】:

请记住,javascript 对象也是关联哈希,所以这样的事情应该可以在不求助于宏的情况下工作(未经测试)......

(def method-names ["requestAnimationFrame"
                   "webkitRequestAnimationFrame"
                   "mozRequestAnimationFrame"
                   "oRequestAnimationFrame" 
                   "msRequestAnimationFrame"])

(defn animationFrameMethod []
  (let [window (dom/getWindow)
        options (map (fn [n] #(aget window n)) method-names)]
    ((fn [[current & remaining]]
       (cond
        (nil? current) #((.-setTimeout window) % (/ 1000 30))
        (fn? (current)) (current)
        :else (recur remaining)))
     options)))

【讨论】:

  • 啊哈哈,这是一个我不知道的重要技巧!我没有意识到它们可以作为字典访问。谢谢!
猜你喜欢
  • 2017-11-04
  • 1970-01-01
  • 2012-09-10
  • 2018-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多