当没有拖动发生时,鼠标事件不会触发

当没有拖动发生时,鼠标事件不会触发

问题描述:

我有一个程序this fiddle,有时mouseup事件不会触发。通过在我的mousedown函数中调用e.preventDefault(),并添加一个dragend事件侦听器,我尝试了一切可以做到的操作来防止拖动,方法是在每个元素上放置draggable="false"。但是,dragend事件不会触发,并且mouseup仍然无法触发。任何帮助,将不胜感激。当没有拖动发生时,鼠标事件不会触发

+0

mouseup事件肯定是触发的,你可以看到这个,如果你添加一个console.log语句给你的鼠标向上事件监听器(这种习惯会使调试比你的小提琴中的方法更容易)。 dragend事件仅在元素被定义为可拖动时触发。 – bryan60

+0

我可以复制这个问题,当我点击鼠标之间事件不会触发的图块之间的灰色空间时。 –

+0

当鼠标向上移动时,鼠标上移事件肯定会触发。问题在于代码中的其他地方。 – bryan60

问题在于附加到innerHTML的,mysvg.innerHTML +=会(如discused here)删除事件监听器在文件停止你的鼠标释放事件FIRI NG。

通过在您setMoveOnBoard功能与mysvg.insertAdjacentHTML('beforeend',更换mysvg.innerHTML +=可以保留鼠标抬起事件侦听器,如insertAdjacentHTML()不破坏DOM树。

例子:

function makeSVGTag(tagName, properties) { 
 
    var keys = Object.keys(properties); 
 
    var ret = "<" + tagName; 
 
    for (var i = 0; i < keys.length; i++) { 
 
    ret += " " + keys[i] + '="' + properties[keys[i]] + '"'; 
 
    } 
 
    ret += "/>"; 
 
    return ret; 
 
} 
 

 
function makeSVGTagContent(tagName, properties, content) { 
 
    var keys = Object.keys(properties); 
 
    var ret = "<" + tagName; 
 
    for (var i = 0; i < keys.length; i++) { 
 
    ret += " " + keys[i] + '="' + properties[keys[i]] + '"'; 
 
    } 
 
    ret += ">" + content.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</" + tagName + ">"; 
 
    return ret; 
 
} 
 

 
function setMoveOnBoard(color1, color2, color3, color4, symbol1, symbol2, x, y) { 
 
    mysvg.insertAdjacentHTML('beforeend', makeSVGTag("rect", { 
 
    height: 10, 
 
    width: 10, 
 
    stroke: color2, 
 
    "stroke-width": 2, 
 
    x: Number(x) + 3, 
 
    y: Number(y) + 3, 
 
    fill: color1, 
 
    class: "move move-display", 
 
    "data-index": (Number(y)/16) * 15 + Number(x)/16, 
 
    draggable: false 
 
    })); 
 
    mysvg.insertAdjacentHTML('beforeend', makeSVGTagContent("text", { 
 
    x: Number(x) + 4, 
 
    y: Number(y) + 10, 
 
    "font-family": "Verdana", 
 
    "font-size": 10, 
 
    stroke: "none", 
 
    fill: color3, 
 
    class: "move-symbol move-symbol1 move-display", 
 
    "data-index": (Number(y)/16) * 15 + Number(x)/16, 
 
    draggable: false 
 
    }, symbol1)); 
 
    mysvg.insertAdjacentHTML('beforeend', makeSVGTagContent("text", { 
 
    x: Number(x) + 4, 
 
    y: Number(y) + 10, 
 
    "font-family": "Verdana", 
 
    "font-size": 10, 
 
    stroke: "none", 
 
    fill: color4, 
 
    class: "move-symbol move-symbol2 move-display", 
 
    "data-index": (Number(y)/16) * 15 + Number(x)/16, 
 
    draggable: false 
 
    }, symbol2)); 
 
} 
 
var config = { 
 
    color1: "#f00", 
 
    color2: "#000", 
 
    color3: "#0f0", 
 
    color4: "#00f", 
 
    symbol1: ">", 
 
    symbol2: "<" 
 
}; 
 
var mode = "add"; 
 

 
function toggleMove(i) { 
 
    if (getMove(i)[0]) { 
 
    mode = "remove"; 
 
    getMove(i)[0].remove(); 
 
    getMove(i)[1].remove(); 
 
    getMove(i)[2].remove(); 
 
    } else { 
 
    mode = "add"; 
 
    setMoveOnBoard(config.color1, config.color2, config.color3, config.color4, config.symbol1, config.symbol2, mysvg.children[i].getAttribute("x"), mysvg.children[i].getAttribute("y")); 
 
    } 
 
} 
 

 
function changeMove(i) { 
 
    if (mode == "add") { 
 
    setMoveOnBoard(config.color1, config.color2, config.color3, config.color4, config.symbol1, config.symbol2, mysvg.children[i].getAttribute("x"), mysvg.children[i].getAttribute("y")); 
 
    } else { 
 
    if (typeof getMove(i)[0].remove == "function") { 
 
     getMove(i)[0].remove(); 
 
    } 
 
    if (typeof getMove(i)[1].remove == "function") { 
 
     getMove(i)[1].remove(); 
 
    } 
 
    if (typeof getMove(i)[2].remove == "function") { 
 
     getMove(i)[2].remove(); 
 
    } 
 
    } 
 
} 
 
var mouseDown = false; 
 
document.body.addEventListener("mouseup", function() { 
 
    mouseDown = false; 
 
    mode = "add"; 
 
}); 
 
document.body.addEventListener("dragend", function() { 
 
    mouseDown = false; 
 
    mode = "add"; 
 
}); 
 

 
function getMove(index) { 
 
    var ret = [, , ]; 
 
    var moveList = mysvg.getElementsByClassName("move"); 
 
    for (var i = 0; i < moveList.length; i++) { 
 
    if (moveList[i].getAttribute("data-index") == index) { 
 
     ret[0] = moveList[i]; 
 
    } 
 
    } 
 
    moveList = mysvg.getElementsByClassName("move-symbol1"); 
 
    for (var i = 0; i < moveList.length; i++) { 
 
    if (moveList[i].getAttribute("data-index") == index) { 
 
     ret[1] = moveList[i]; 
 
    } 
 
    } 
 
    moveList = mysvg.getElementsByClassName("move-symbol2"); 
 
    for (var i = 0; i < moveList.length; i++) { 
 
    if (moveList[i].getAttribute("data-index") == index) { 
 
     ret[2] = moveList[i]; 
 
    } 
 
    } 
 
    return ret; 
 
} 
 

 
function tileClick(i, e) { 
 
    e.preventDefault(); 
 
    mouseDown = true; 
 
    if (i != 112) { 
 
    toggleMove(i); 
 
    } 
 
} 
 

 
function tileDrag(i, e) { 
 
    if (mouseDown && i != 112) { 
 
    changeMove(i); 
 
    } 
 
} 
 
window.tileClick = tileClick; 
 
window.tileDrag = tileDrag; 
 
for (var i = 0; i < 225; i++) { 
 
    mysvg.innerHTML += makeSVGTag("rect", { 
 
    height: 16, 
 
    width: 16, 
 
    stroke: "#888", 
 
    "stroke-width": 1, 
 
    x: (i % 15) * 16, 
 
    y: Math.floor(i/15) * 16, 
 
    fill: i % 2 ? "#eee" : "#fff", 
 
    onmousedown: 'tileClick(' + i + ', event)', 
 
    onmouseover: 'tileDrag(' + i + ', event)', 
 
    class: "tile", 
 
    "data-index": i, 
 
    draggable: false 
 
    }); 
 
} 
 
mysvg.innerHTML += makeSVGTag("circle", { 
 
    cx: 120, 
 
    cy: 120, 
 
    r: 5, 
 
    class: "piece", 
 
    "data-index": 112, 
 
    draggable: false 
 
});
text { 
 
    -webkit-touch-callout: none; 
 
    -webkit-user-select: none; 
 
    -khtml-user-select: none; 
 
    -moz-user-select: none; 
 
    -ms-user-select: none; 
 
    user-select: none; 
 
}
<svg width="251" height="251" id="mysvg" style="padding-left:2px;padding-top:2px;" class="board" draggable="false"> 
 
</svg> 
 
<p> 
 
    Console: 
 
</p> 
 
<textarea id="evalconsole"></textarea> 
 
<button onclick="returnstatement.innerText=eval(evalconsole.value)"> 
 
    Eval! 
 
</button> 
 
<p id="returnstatement"></p>

希望这有助于!

+0

感谢您的帮助! – Aplet123

不知道为什么瓷砖之间点击使鼠标松开,以不火,但你可以通过移动鼠标松开funcion到它自己的功能,并增加了窗口,并将其设置为事件监听器解决这个问题:

function mouseUp() { 
    console.log('mouse up'); 
    mouseDown = false; 
    mode = "add"; 
} 
document.body.addEventListener("mouseup", mouseUp); 
window.mouseUp = mouseUp; 

,然后将其添加到瓷砖的onmouseup事件:

onmouseup: 'mouseUp()',