有什么简单的方法可以延迟:on-click
事件,以便先检测是否触发了:on-double-click
事件?
[:div {:on-click (fn [e]
;; listen to double-click event, within 500ms,
;; if so on-double-click-fn,
;; if not, on-click-fn
)
:on-double-click (fn [e]
;; on-click-fn
)}]
Thanks!
First attempt:
(defn sleep [timeout]
(let [maxtime (+ (.getTime (js/Date.)) timeout)]
(while (< (.getTime (js/Date.)) maxtime))))
[:div {:on-click (fn [e] (sleep 500) (print "single-clicked"))
:on-double-click (fn [e] (print "double-clicked"))}]
第二次尝试:
(def state (atom {:click-count 0}))
(defn handle-click [e click-fns-map]
(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"
编辑:
根据 Taylor Wood 的回答,这里提供了一个抽象层,它包装了HTML元素参数并为您覆盖了: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 (fn [e]
(when (compare-and-set! waiting? false true)
(js/setTimeout
(fn [] (when @waiting?
(on-click %)
(reset! waiting? false)))
300)))
:on-double-click (fn [e]
(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"]