Generate javascript method call code with ClojureScript macro?

冷暖自知 提交于 2019-12-23 03:31:04

问题


I am using ClojureScript to detect which browser-specific version of 'requestAnimationFrame' method is defined. I use the following code:

(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)))

This works fine, and it's not terrible, but I would really like to be able to put the method names in a list, i.e.

'(requestAnimationFrame webkitRequestAnimationFrame ...)

And then call a macro for each symbol in the list to generate the anonymous function code.

I would like something to work like so:

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

But I played around with macros for a while, and was unable to achieve this effect. Part of the problem is that method names and the dot notation work strangely, and I'm not even sure if this is possible.

Any tips to get this working? Thanks!


回答1:


Remember that javascript objects are also associative hashes, so something like this should work without resorting to macros (untested)....

(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)))


来源:https://stackoverflow.com/questions/9894572/generate-javascript-method-call-code-with-clojurescript-macro

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!