我一直在进行Odin project的etch-a-sketch项目,在实现mousedown
和mouseup
事件监听器时遇到了一些奇怪的行为。
我在容器div中创建了一个50x50的div网格。容器div监听mousedown
事件,然后调用startDrawing
函数,填充用户悬停的框。它还会监听mousedown
事件,以便在释放鼠标时调用stopDrawing
函数,并停止填充框。
所有这些工作都很好,但是有时,当我开始按住鼠标左键绘制一条线时,div框会变得“被抓”。此后,在鼠标左键仍然按下的情况下,将鼠标悬停在框上时,框不会被填充。然后,当我释放鼠标时,它开始绘制。这就像是在意外“抓图”之后切换了行为,但是在下一次按下鼠标时,它又开始正常工作。
这可能比自己亲自看要难解释,所以下面是我的代码以及指向相应密码笔的链接。
我曾尝试使用谷歌搜索来查找如何消除这种“抓人”行为,但是我并没有真正发现任何东西,可能是因为我什至都不知道要搜索哪些关键字。
有人可以解释正在发生的事情,并提供一些有关如何解决此问题的信息吗?
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>
答案 0 :(得分:1)
这里发生的是mousedown + mousemove的默认行为是发起抓取。
当然,在某个时候,浏览器会在页面中选择一些内容并开始抓取。
避免这种情况的解决方案是告诉浏览器您的代码确实处理了该事件,因此不应执行其通常的行为。您可以通过调用Event::preventDefault()
方法来实现:
#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>
{{1}}