2012-03-27 4 views
1

私はClojureScriptを使用して、どのブラウザ固有のバージョンの 'requestAnimationFrame'メソッドが定義されているかを検出しています。私は、次のコードを使用します。ClojureScriptマクロを使ってjavascriptメソッド呼び出しコードを生成しますか?

(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

.... JavaScriptのオブジェクトも連想ハッシュされているので、このようなものは、マクロ(未テスト)に頼ることなく動作する必要があることを忘れないでください'options'の最初の要素がnilの時は常に' setTimeout'関数が働きます。 –

+0

@PhilipKそのように見えますが、そうではありません。 options内の関数を呼び出す結果は、それらが存在しない場合は定義されていません.nilではありません。リストが空になるまではゼロになりません。 – mrmekon

答えて

2

私はひどくあなたのコードを誤読していない限り、あなたは常に戻ります

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

ああ、それは私が知らなかった重要なトリックです!私は彼らが辞書としてアクセスできることを知らなかった。ありがとう! – mrmekon

関連する問題