leo*_*bot 2 clojure clojurescript reagent
:on-click如果:on-double-click事件被触发,有什么简单的方法来延迟事件首先查看?
[:div {:on-click "listen to double-click event, within 500ms,
if so on-double-click-fn,
if not, on-click-fn"
:on-double-click "on-click-fn"}]
Run Code Online (Sandbox Code Playgroud)
谢谢!
第一次尝试:
(defn sleep [timeout]
(let [maxtime (+ (.getTime (js/Date.)) timeout)]
(while (< (.getTime (js/Date.)) maxtime))))
[:div {:on-click #(do (sleep 500) (print "single-clicked"))
:on-double-click #(print "double-clicked")}]
Run Code Online (Sandbox Code Playgroud)
第二次尝试:
(def state (atom {:click-count 0}))
(defn handle-click [e click-fns-map]
(do (swap! state update :click-count inc)
(sleep 500)
(let [click-count (get @state :click-count)]
(swap! state assoc :click-count 0)
(cond
(= click-count 1) ((:on-single-click click-fns-map) e)
(> click-count 1) ((:on-double-click click-fns-map) e)))))
[:div
{:on-mouse-down
(fn [e]
(handle-click
e
{:on-single-click #(print "single-click")
:on-double-click #(print "double-click")}))}]
;;=> "single-click"
;;=> "single-click"
Run Code Online (Sandbox Code Playgroud)
编辑:
基于已接受的答案,这里是一个抽象包装html元素args和覆盖:on-click并:on-double-click为您.
(defn ensure-single-double-click
[{:keys [on-click on-double-click] :as args}]
(let [waiting? (atom false)]
(merge
args
{:on-click #(when (compare-and-set! waiting? false true)
(js/setTimeout (fn [] (when @waiting?
(on-click %)
(reset! waiting? false)))
300))
:on-double-click #(do (reset! waiting? false)
(on-double-click %))})))
[:a (ensure-single-double-click
{:style {:color "blue"} ;; this works
:on-click #(print "single-click")
:on-double-click #(print "double-click")})
"test"]
Run Code Online (Sandbox Code Playgroud)
这是一种方法:
(defn slow-link [text single-click-fn double-click-fn]
(let [waiting? (atom false)]
[:a {:on-click #(when (compare-and-set! waiting? false true)
(js/setTimeout (fn [] (when @waiting?
(single-click-fn %)
(reset! waiting? false)))
500))
:on-double-click #(do (reset! waiting? false)
(double-click-fn %))}
text]))
[slow-link "Test" #(prn "single-click") #(prn "double-click")]
Run Code Online (Sandbox Code Playgroud)
这将启动一个JS计时器,它将在500ms后执行给定的函数.该函数检查waiting?在超时过去时我们是否还在进行另一次单击,如果是,则执行single-click-fn.如果我们不是waiting?那个意味着双击事件已经发生,重置waiting?为false并调用double-click-fn.
该:on-click处理器使用compare-and-set,如果我们在一个很没有只采取行动waiting?的状态,避免了三/四击等一些活泼的行为