javascript - 没有拖动发生时不触发 Mouseup 事件

标签 javascript html

我在 this fiddle 有一个程序有时 mouseup 事件不会触发。我尽我所能来防止拖动,方法是在每个元素上放置 draggable="false",在我的 mousedown 函数中调用 e.preventDefault(),并添加一个dragend 事件监听器。但是,dragend 事件没有触发,mouseup 仍然无法触发。任何帮助将不胜感激。

最佳答案

问题在于附加到 innerHTML,mysvg.innerHTML += 将(如讨论的 here )删除文档中的事件监听器,停止触发鼠标事件。

通过在您的 setMoveOnBoard 函数中将 mysvg.innerHTML += 替换为 mysvg.insertAdjacentHTML('beforeend',,您可以像 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>

希望这对您有所帮助!

关于javascript - 没有拖动发生时不触发 Mouseup 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46001588/

相关文章:

php - 图像原始数据的强制下载在 android 2.3 上损坏

javascript - 如何在 Javascript 中获取 C# 枚举

javascript - 如何在不使用 onclick 或 onmousedown 的情况下从 anchor 的 href 属性中停止事件传播

php - <p> 文本上的滚动条

php - 在不刷新页面的情况下如何使用ajax/jQuery显示数据库中的值

javascript - 使用 jquery 将 dt/dd 列表转换为 li 列表?

javascript - chart.js 我的数据不符合标签,

javascript - 在 Extjs 的外部 html 中使用脚本

javascript - 更改复选框上的变量值

javascript - getElementById 具有模型中的唯一 id