为什么在mouseup事件上触发了mousedown事件?

时间:2020-06-01 02:11:13

标签: javascript html css

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

我在容器div中创建了一个50x50的div网格。容器div监听mousedown事件,然后调用startDrawing函数,填充用户悬停的框。它还会监听mousedown事件,以便在释放鼠标时调用stopDrawing函数,并停止填充框。

所有这些工作都很好,但是有时,当我开始按住鼠标左键绘制一条线时,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>

1 个答案:

答案 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}}