she*_*hen 5 html javascript css
我有这个草图应用程序,它允许用户通过按下和移动鼠标来绘制一些图片。
/* create grids in canvas */
const initCanvas = function() {
const canvas = document.querySelector('.canvas');
/* clear old canvas if any */
canvas.innerHTML = '';
/* create new canvas */
let row = parseInt(document.querySelector('textarea.canvasRow').value);
let column = parseInt(document.querySelector('textarea.canvasColumn').value);
if (!row || !column) return;
canvas.style['grid-template-columns'] = `repeat(${column}, 1fr)`;
canvas.style['grid-template-rows'] = `repeat(${row}, 1fr)`;
for (let i = 0; i < (row * column); i++) {
let cell = document.createElement('div');
cell.classList.add('cell');
cell.draggable = false; // prevent cell from being dragged
cell.addEventListener('mousedown', draw, false);
cell.addEventListener('mouseenter', draw, false); // mouseenter is better than mouseover
canvas.appendChild(cell);
}
}
/* mousedown event handler on canvas */
const toDraw = function(e) {
// e.preventDefault(); // !IMPORTANT: inhibit some browser's default drag & drop behaviors
isDrawing = true;
}
/* mouseenter event handler on each cell */
const draw = function(e) {
// e.preventDefault(); // !IMPORTANT: inhibit some browser's default drag & drop behaviors
if (isDrawing) {
this.style['background-color'] = color;
}
}
/* mouseup event handler on whole document */
const stopDrawing = function(e) {
isDrawing = false;
e.stopPropagation();
}
/* variables */
let color = 'black';
let isDrawing = false;
/* canvas init */
const initCanvasBtn = document.querySelector('.initCanvas');
initCanvasBtn.addEventListener('click', initCanvas);
/* draw */
const canvas = document.querySelector('.canvas');
canvas.draggable = false; // prevent canvas from being dragged
canvas.addEventListener('mousedown', toDraw, true); // capture must be true. canvas must turn on "isDrawing" before cell capture the mousedown event.
document.addEventListener('mouseup', stopDrawing, true); // document element handle this. no need to notify children.Run Code Online (Sandbox Code Playgroud)
textarea.canvasRow,
textarea.canvasColumn {
width: 4rem;
height: 1rem;
}
.initCanvas {
width: 4rem;
height: 2rem;
border: 1px solid black;
}
.canvas {
height: 50vw;
width: 50vw;
border: 1px solid black;
display: grid;
}
.cell {
background-color: #F5F5F5;
border: 1px solid #EBEBEB;
}Run Code Online (Sandbox Code Playgroud)
<textarea class="canvasRow">16</textarea>
<textarea class="canvasColumn">16</textarea>
<div class="initCanvas">Create canvas</div>
<div class="canvas"></div>Run Code Online (Sandbox Code Playgroud)
根据MDN Web Docs:draggable,为了防止元素被拖动,我将和draggable的属性都设置为。canvascellfalse
cell.draggable = false;
canvas.draggable = false;
Run Code Online (Sandbox Code Playgroud)
但是我测试的时候,有1/20或者1/30的情况下,no-drop会出现光标图标,我的mouseup事件就会肿起来。这意味着drag operation发生了意外的事情。
根据MDN Web Docs:HTML Drag and Drop API,我绑定了一个侦听器dragstart和drag事件。然后调试器Event Listener Breakpoint显示,当错误发生时,drag和dragstart事件都被触发。

在之前的另一个问题中:“mousedown”和“mousemove”会改变光标图标以及如何防止它?,@skmail 建议我添加preventDefault()事件mousedown。
有用!drag事件dragstart消失了。但我还是想知道:为什么当元素配置为 时,仍然可以触发drag事件?dragstartdraggable=false我的意思是除了数百个空的之外几乎什么都没有div。而且它们都是不可拖动的`...我真的很困惑。
如果您能进一步解释为什么preventDefault()可以解决这个问题,那就太好了?目前,我唯一确定的是,这种意外情况drag operation是由浏览器的默认设置触发的。有人有什么提示吗?
不幸的是,这种行为没有标准化。这是发生的事情:
当您第一次在画布上绘画时,将选择 div 内的(空)文本节点。浏览器单独处理选择,因此它们不受draggable 属性的控制。如果从选区内部拖动,则会触发拖动事件。preventDefault()onmousedown只是阻止这种选择的发生。
对于您的情况,更简单的解决方案是添加user-select: none;到 .canvas。(不要忘记添加webkit-Safari 浏览器)。
一个相关但更复杂的情况是当您在可拖动 div 顶部有一个文本输入时。在这种情况下,正确设置逻辑非常重要,这样选择拖动就不会被误解为正在拖动的 div。
| 归档时间: |
|
| 查看次数: |
811 次 |
| 最近记录: |