Создать код вызова метода javascript с помощью макроса ClojureScript? - PullRequest
1 голос
/ 27 марта 2012

Я использую 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)

Но я какое-то время играл с макросами и не смог добиться этого эффекта.Частично проблема заключается в том, что имена методов и точечная запись работают странно, и я даже не уверен, возможно ли это.

Какие-нибудь советы, как это работает?Спасибо!

1 Ответ

2 голосов
/ 27 марта 2012

Помните, что объекты 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)))
...