我对结束语很陌生,也许这是一个微不足道的问题,但我还没有找到答案。
我期待着实现一个clojurescript来跟踪鼠标并在鼠标位置呈现一个点,如下所示:
https://jsbin.com/gejuz/1/edit?html,output
Js代码:
function() {
"use strict";
document.onmousemove = handleMouseMove;
function handleMouseMove(event) {
var dot, eventDoc, doc, body, pageX, pageY;
event = event || window.event; // IE-ism
// If pageX/Y aren't available and clientX/Y
// are, calculate pageX/Y - logic taken from jQuery
// Calculate pageX/Y if missing and clientX/Y available
if (event.pageX == null && event.clientX != null) {
eventDoc = (event.target && event.target.ownerDocument) || document;
doc = eventDoc.documentElement;
body = eventDoc.body;
event.pageX = event.clientX +
(doc && doc.scrollLeft || body && body.scrollLeft || 0) -
(doc && doc.clientLeft || body && body.clientLeft || 0);
event.pageY = event.clientY +
(doc && doc.scrollTop || body && body.scrollTop || 0) -
(doc && doc.clientTop || body && body.clientTop || 0 );
}
// Add a dot to follow the cursor
dot = document.createElement('div');
dot.className = "dot";
dot.style.left = event.pageX + "px";
dot.style.top = event.pageY + "px";
document.body.appendChild(dot);
}到目前为止,我确实获得了鼠标坐标(多亏了这个问题Tracking mouse in clojurescript / reagent / reagi?)。但是我没有在网页上渲染这个点。
文本代码:
(def mouse-coordinates (reagent/atom {:x 100 :y 100}))
(defn dot [x y]
[:div {:style {:left (str x "px")
:top (str y "px")
:width "2px"
:height "2px"
:background-clor "black"
:position "absolute"}}])
(def do-dot (reagent/reactify-component dot))
(defn mouse-move []
[:body
{:onMouseMove (fn [event]
(swap! mouse-coordinates assoc :x (.-clientX event))
(swap! mouse-coordinates assoc :y (.-clientY event))
(reagent/create-element do-dot
#js{:x (int (:x @mouse-coordinates))
:y (int (:y @mouse-coordinates))})
)}
[:p "x: " (int (:x @mouse-coordinates))]
[:p "y: " (int (:y @mouse-coordinates))]
])
(reagent/render-component [mouse-move]
(. js/document (getElementById "app")))任何帮助都是非常感谢的。提前谢谢你。
发布于 2019-08-26 21:39:24
与在onMouseMove事件中创建元素不同,您可以将dot组件作为呈现代码的一部分。它将获取对reagent/atom的更改,就像两个p元素所做的那样:
[:p "x: " (int (:x @mouse-coordinates))]
[:p "y: " (int (:y @mouse-coordinates))]
[dot (int (:x @mouse-coordinates)) (int (:y @mouse-coordinates))]还有一个错误::background-clor -> :background-color。这两个变化应该足以使点出现。
还有一些其他的事情可以帮助简化代码:
如果传入数字,style属性将默认为像素。
因此,可以这样编写dot组件:
(defn dot [x y]
[:div {:style {:left x
:top y
:width 2
:height 2
:background-color "black"
:position "absolute"}}])reset!对swap!
mouse-coordinates具有非常特定的用途,所以在onMouseMove事件中使用reset!而不是swap!更简洁:(reset! mouse-coordinates {:x (.-clientX event) :y (.-clientY event)})以地图形式传递组件道具
(defn dot [{:keys [x y]}]
...)
[dot @mouse-coordinates]最后的代码看起来如下所示:
(def mouse-coordinates (reagent/atom {:x 100 :y 100}))
(defn dot [{:keys [x y]}]
[:div {:style {:left x
:top y
:width 2
:height 2
:background-color "black"
:position "absolute"}}])
(defn mouse-move []
[:body
{:onMouseMove (fn [event]
(reset! mouse-coordinates {:x (.-clientX event) :y (.-clientY event)}))}
[:p "x: " (:x @mouse-coordinates)]
[:p "y: " (:y @mouse-coordinates)]
[dot @mouse-coordinates]])UPDATE:当我第一次回答这个问题时,我没有意识到每个点都应该是持久的。下面是关于如何实现这一目标的更新代码(附带注释):
使用坐标集合
(def mouse-coordinates (r/atom []))
(defn dot [{:keys [x y]}]
[:div {:style {:left x
:top y
:width 2
:height 2
:background-color "black"
:position "absolute"}}])
(defn mouse-move []
[:div
{:onMouseMove (fn [event]
(let [x (.-clientX event)
y (.-clientY event)
;; If there's already a dot in an identical location, don't add it. This saves unnecessary work and
;; means we can use [x y] as our unique key for our collection.
coords-already-exist? (not (empty? (filter #(and (= (:x %) x) (= (:y %) y)) @mouse-coordinates)))]
(when-not coords-already-exist?
;; conj the new coordinate to the collection.
(swap! mouse-coordinates #(conj % {:x (.-clientX event) :y (.-clientY event)})))))}
[:p "x: " (:x @mouse-coordinates)]
[:p "y: " (:y @mouse-coordinates)]
;; Loop through the coordinates.
(for [{:keys [x y]} @mouse-coordinates]
[dot
;; Important: we give each dot a unique key.
{:key [x y]
:x x
:y y}])])正如注释中提到的,呈现集合的重要之处在于为每个项目提供一个唯一的键。这意味着在创建新的坐标时,React知道添加一个新的子元素,而不是重新呈现每个dot。更多信息可以在下面的React文档中找到:https://reactjs.org/docs/lists-and-keys.html#keys
https://stackoverflow.com/questions/57654246
复制相似问题