繁体   English   中英

为什么我的 mousedown 事件会在 mouseup 事件上触发?

[英]Why is my mousedown event triggered on a mouseup event?

我一直在研究Odin 项目的 etch-a-sketch 项目,在实现mousedownmouseup事件侦听器时遇到了一些奇怪的行为。

我在容器 div 中创建了一个 50x50 的 div 网格。 容器 div 监听mousedown事件,在此事件上它调用startDrawing function,填充用户悬停的框。 它还监听mousedown事件,因此当释放鼠标时,将stopDrawing function 并停止填充框。

所有这些都工作得很好,但有时当我按住鼠标左键开始画一条线时,盒子 div 变成了“抓取”。 此后,在按住左键的情况下拖动鼠标时,将鼠标悬停在框上时不会填充框。 然后当我释放鼠标时,它开始绘图。 就好像在意外“抓取”后切换了行为,但在下一次鼠标按下时,它又开始正常运行。

这可能比自己看更难解释,所以下面是我的代码以及相应代码笔的链接。

我试过用谷歌搜索找出如何消除这种“抓取”行为,但我还没有真正找到任何东西,可能是因为我什至不知道要搜索什么关键字。

有人可以解释发生了什么并提供一些有关如何解决此问题的信息吗?

Etch-a-Sketch Codepen

 const GRID_SIZE = 50; for(let i = 0; i < GRID_SIZE * GRID_SIZE; i++){ const container = document.getElementById('container'); let div = document.createElement('div'); div.classList.add('box'); container.appendChild(div); } function fillBox(e){ this.classList.add('filled'); } function clearGrid(){ const boxes = document.querySelectorAll('.box'); boxes.forEach(box => box.classList.remove('filled')); } function startDrawing(){ // console.log("start drawing"); const boxes = document.querySelectorAll('.box'); boxes.forEach(box => box.addEventListener('mouseover', fillBox)); } function stopDrawing(){ // console.log("stop drawing"); const boxes = document.querySelectorAll('.box'); boxes.forEach(box => box.removeEventListener('mouseover', fillBox)); } const container = document.querySelector('#container'); container.addEventListener('mousedown', startDrawing); container.addEventListener('mouseup', stopDrawing); const button = document.querySelector('#clear-grid-btn'); button.onclick = clearGrid;
 #container{ width: 500px; display: grid; grid-template-columns: repeat(50, 10px); grid-template-rows: repeat(50, 10px); border: solid; border-color: black; margin:auto; }.box{ width: 10px; height: 10px; }.box:hover{ background-color: blue; }.filled{ background-color: blue; } #clear-grid-btn{ display:block; margin:auto; margin-top: 10px; }
 <,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width. initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="etch-a-sketch.css"> </head> <body> <div id="container"></div> <button id="clear-grid-btn">Clear grid</button> </body> <script src="etch-a-sketch.js"></script> </html>

这里发生的是 mousedown + mousemove 的默认行为是启动抓取。
当然,在某些时候,浏览器会 select 页面中的一些内容并开始抓取它。

避免这种情况的解决方案是告诉浏览器您的代码确实处理了该事件,因此不应执行其通常的行为。 您可以通过调用Event::preventDefault()方法来做到这一点:

 const GRID_SIZE = 50; for(let i = 0; i < GRID_SIZE * GRID_SIZE; i++){ const container = document.getElementById('container'); let div = document.createElement('div'); div.classList.add('box'); container.appendChild(div); } function fillBox(evt){ evt.preventDefault(); // tell the browser we handle that event this.classList.add('filled'); } function clearGrid(){ const boxes = document.querySelectorAll('.box'); boxes.forEach(box => box.classList.remove('filled')); } function startDrawing(evt){ evt.preventDefault(); // tell the browser we handle that event // console.log("start drawing"); const boxes = document.querySelectorAll('.box'); boxes.forEach(box => box.addEventListener('mouseover', fillBox)); } function stopDrawing(evt){ evt.preventDefault(); // tell the browser we handle that event // console.log("stop drawing"); const boxes = document.querySelectorAll('.box'); boxes.forEach(box => box.removeEventListener('mouseover', fillBox)); } const container = document.querySelector('#container'); container.addEventListener('mousedown', startDrawing); container.addEventListener('mouseup', stopDrawing); const button = document.querySelector('#clear-grid-btn'); button.onclick = clearGrid;
 #container{ width: 500px; display: grid; grid-template-columns: repeat(50, 10px); grid-template-rows: repeat(50, 10px); border: solid; border-color: black; margin:auto; }.box{ width: 10px; height: 10px; }.box:hover{ background-color: blue; }.filled{ background-color: blue; } #clear-grid-btn{ display:block; margin:auto; margin-top: 10px; }
 <,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width. initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="etch-a-sketch.css"> </head> <body> <div id="container"></div> <button id="clear-grid-btn">Clear grid</button> </body> <script src="etch-a-sketch.js"></script> </html>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM