clojurescript: touch events and Domina

二次信任 提交于 2019-12-11 00:45:14

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!