当没有拖动发生时,鼠标事件不会触发
问题描述:
我有一个程序this fiddle,有时mouseup
事件不会触发。通过在我的mousedown函数中调用e.preventDefault()
,并添加一个dragend
事件侦听器,我尝试了一切可以做到的操作来防止拖动,方法是在每个元素上放置draggable="false"
。但是,dragend
事件不会触发,并且mouseup仍然无法触发。任何帮助,将不胜感激。当没有拖动发生时,鼠标事件不会触发
答
问题在于附加到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, "&").replace(/</g, "<").replace(/>/g, ">") + "</" + 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()',
mouseup事件肯定是触发的,你可以看到这个,如果你添加一个console.log语句给你的鼠标向上事件监听器(这种习惯会使调试比你的小提琴中的方法更容易)。 dragend事件仅在元素被定义为可拖动时触发。 – bryan60
我可以复制这个问题,当我点击鼠标之间事件不会触发的图块之间的灰色空间时。 –
当鼠标向上移动时,鼠标上移事件肯定会触发。问题在于代码中的其他地方。 – bryan60