问题
I'm having trouble getting the 'touch' or 'changedTouches' list out of the touchstart event in Domina.
Here's my :require stuff:
(ns myproj
(:require-macros [hiccups.core :as h])
(:require [domina :as dom]
[hiccups.runtime :as hiccupsrt]
[domina.events :as ev]
[cljs.reader :refer [read-string]]
[wsosc :as wo]
[clojure.browser.repl :as repl]
))
And here's my touchstart event handler:
(defn touchstart [evt]
; store event in an atom for repl access
(swap! de (fn [x] evt))
; print something to html to show a result (no console on the phone)
(dom/set-text! (dom/by-id "result") (str "blah" evt))
; hopefully someday extract touch coordinates here.
(let [rct (.getBoundingClientRect (dom/by-id "osccanvas"))
;touchlist1 (get evt "changedTouches")
;touchlist2 (.changedTouches evt)
;touchlist3 (.-changedTouches evt)
;kies (keys evt)]
wat (:type evt) ; this works
;wat (ev/raw-event evt) ; this works
;touchlist (.-changedTouches evt)]
;touch (.item touchlist 1)]
]
(dom/set-text! (dom/by-id "result") (str "touchstart touch:" wat))))
'de' is an atom that I'm trying to use for debug. I'm able to get the :type from the event but that's about it. Pretty much none of the other commented things work, except for ev/raw-event. raw-event returns an object that is fairly incrutable from the repl, at least for me. If I swap! de with the raw-event it looks like this:
ClojureScript:myproj>@de
#<[object Object]>
I have no idea how extract information from this, it seems pretty unresponsive to things like (keys x) or (.keys x), etc.
What is also strange is that I can call (:type evt) in the above function, but if I assign evt to de I can't do the same thing with the 'de' atom at the repl, ie (:type @de).
回答1:
Ok after much frustration I finally got things to work. It turns out there are a number of layers at work which I was not really aware of (and didn't WANT to be aware of!). The main thing is that there was no touch information in the domina touch event object - that gets stripped out even before domina gets the event. Its like this:
original browser event -> google closure library -> domina library -> my code
And the google closure (not clojure, its javascript) library actually strips out the touch information, so its not available in the event object that I get. Thanks, google. However, the original event is still accessible, its just two layers down. The code looks like this:
(defn touchstart [evt]
(let [wat (ev/raw-event evt)
touches (.-changedTouches (.getBrowserEvent wat))
touch (.item touches 0)
]
(domousedown (.-clientX touch) (.-clientY touch))
))
So I use Domina's raw-event function to get the google closure version of the event ('wat'). But that doesn't have the touch info either. I have to go one more level with getBrowserEvent, and then I can call the changedTouches method as documented here:
https://developer.mozilla.org/en-US/docs/DOM/TouchEvent
And the last piece of the puzzle was detecting whether a touchscreen is present in the first place, so I can set up the right event functions for that. This non-clojure hack does the job:
(if (js* "'ontouchstart' in window")
<set up touch events>
<set up non-touch events>)
I tried various permutations of clojure syntax here but nothing seemed to work for me. Open to suggestions on that.
来源:https://stackoverflow.com/questions/15732028/clojurescript-touch-events-and-domina