我正在使用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)
但是我玩了一段时间的宏,并且无法实现这种效果。部分问题是方法名称和点符号工作奇怪,我甚至不确定这是否可行。
有任何提示让这个工作?谢谢!
答案 0 :(得分:2)
请记住,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)))