【问题标题】:onmousedown event object behaving strangelyonmousedown 事件对象行为异常
【发布时间】:2017-03-05 05:45:56
【问题描述】:
<!doctype html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>testing</title>
        </head>
        <body>
            <input type="checkbox" id="test">
            <script>
                var t = document.getElementById("test");
                t.onmousedown = function(e) {
                    if (e.button === 0)
                        t.checked = true;
                    else if (e.button === 2)
                        t.checked = false;

                    alert(e.button);
                }
            </script>
        </body>
    </html>

如果我将 alert(e.button); 行保留在原处,则单击复选框的行为将按预期进行:所有左键单击都选中该复选框,所有右键单击都取消选中该复选框。

如果我删除代码alert(e.button);,那么突然之间,左键单击将选中然后立即取消选中该复选框,右键单击只会打开上下文菜单。

为什么会这样?以及我可以做些什么来让它表现得像我在第一段中描述的那样但没有alert(e.button);

【问题讨论】:

  • e.preventDefault()? mousedown 事件不会导致复选框发生变化,只有“click”事件会发生变化,即在同一元素上的 mousedown 和 mouseup 事件。 alert() 会破坏这一点并阻止默认点击的发生。
  • 不,不幸的是这仍然会导致问题
  • 您可以尝试取消click 事件。但是(除了出于兴趣)你为什么要这样做?更改标准控件行为会让用户感到困惑,如果无法通过键盘或一键鼠标使用控件,则会导致辅助功能失败。
  • @Manuel 为什么要覆盖复选框的默认功能?如果用户一直左键单击控件并且没有任何反应,用户会不会感到困惑?
  • 这说明了为什么警报不利于调试。

标签: javascript html checkbox


【解决方案1】:

您可以尝试将点击事件分隔为onlick(用于左键单击)和oncontextmenu(用于右键单击)。 还要记住return false; 以防止显示内容菜单。

var t = document.getElementById("test");

t.onclick = function(e) {
  t.checked = true;
}
t.oncontextmenu = function(e){
  t.checked = false;
  return false;
}
                
  <html>
      <head>
          <meta charset="utf-8">
          <title>testing</title>
      </head>
      <body>
          <input type="checkbox" id="test">
      </body>
  </html>

【讨论】:

  • 谢谢,但您能否解释一下为什么我最初遇到的问题甚至会这样?导致脚本行为发生如此巨大变化的 alert 命令有什么特别之处?
  • @Manuel 请看我的回答,我只是添加了详细的解释。
  • 谢谢@DineiRockenbach。解释是一个很好的接触。我也在找那个。
【解决方案2】:

解释行为

来自W3 schools onmousedown Event

onmousedown 事件相关的事件顺序(对于左/中鼠标 按钮):

  1. onmousedown
  2. onmouseup
  3. 点击

onmousedown 事件相关的事件顺序(对于右边 鼠标按钮):

  1. onmousedown
  2. onmouseup
  3. 上下文菜单

浏览器“检查”onclick 事件的复选框,您可以看到onmousedown 事件在此之前发生。

alert(e.button) 触发时,下一个事件的流程被消息框中断,因此onclick 事件永远不会发生,您的代码通过设置checked 属性来检查复选框。当您没有alert(e.button) 时,您的代码会选中复选框,然后onclick 事件会立即取消选中它。

解决方案

请看Ngoan Tran's answer,他的解决方案比这个好很多。

一种解决方案可能是在复选框上方创建一个 clicable div,尽管这可能会引发可用性问题。

.container-div {
  position:relative;
}
.clicable-div {
  position:absolute;
  height:100%;
  width:100%;
  top:0;
  left:0;
  z-index:1;
}
<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>testing</title>
    </head>
    <body>
        <div class="container-div">
          <div class="clicable-div" id="clicable"></div>
          <input type="checkbox" id="test">
        </div>
        <script>
            var t = document.getElementById("clicable");
            var c = document.getElementById("test");
            t.onmousedown = function(e) {
                if (e.button === 0)
                    c.checked = true;
                else if (e.button === 2)
                    c.checked = false;
            };
            //Disables the contextual menu on right button click!
            t.oncontextmenu = function() {
              return false;
            };
        </script>
    </body>
</html>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多