【问题标题】:Prevent onclick from firing防止 onclick 触发
【发布时间】:2016-11-04 14:30:36
【问题描述】:

我正在处理 html 中的表单提交。请看下面的代码

<form id="form1">
 <button id="btn1" onclick="clicked();">Submit</button>
</form>
<script>
    $("#btn1").click(function (event) {
        alert("event triggered");
        if(some_condition == true){
             // stop firing onclick method but it always submits the form
             event.stopImmediatePropogation(); // not working
             event.preventDefault(); // not working
             event.stopPropogation(); // not working it's for bubbled events
         }
     });
     function clicked(){ alert("clicked me"); }
</script>

我想阻止clicked() 函数触发,该函数附加到内联onclick 属性。我想运行我的 jquery click 函数,如果出现问题,我不想触发 onclick,但它总是运行 clicked() 函数。任何人都可以帮助我。任何帮助是极大的赞赏。

【问题讨论】:

  • 来自onclick 属性的clicked() 函数是否运行first?如果您使用 jQuery,为什么还要有一个内联 onclick 属性?使用.click() 函数绑定两个处理程序,您首先绑定的任何一个都可以调用stopImmediatePropogation() 以防止第二个运行。 (或者将它们组合成一个处理程序。)
  • @nnnnnn 抱歉,“onclick”是自动生成的代码,我们无法删除 onclick 事件,如果我们想附加事件,请通过 jquery 添加它们,但我们无法随时删除 onclick 并注意“onclick”事件处理程序最后运行
  • stopPropogation 打错了,应该是stopPropagation

标签: javascript jquery


【解决方案1】:

onxyz 处理程序相对于动态附加处理程序的调用顺序因浏览器而异,因此您的处理程序可能不会在原始处理程序之前运行。

为了解决这个问题,您保存并删除 onclick 处理程序:

var btn = $("#btn1");
var clickHandler = btn[0].onclick;
btn[0].onclick = false;

然后,在您的处理程序中,如果您希望调用该函数,则调用它:

clickhandler.call(this, event);

例子:

// Get the button
var btn = $("#btn1");

// Save and remove the onclick handler
var clickHandler = btn[0].onclick;
btn[0].onclick = false;

// Hook up your handler
$("#btn1").click(function(event) {
  alert("event triggered");
  if (!confirm("Allow it?")) {
    // Disallowed, don't call it
    alert("stopped it");
  } else {
    // Allowed, call it
    clickHandler.call(this, event);
  }
});

// The onclick handler
function clicked() {
  alert("clicked me");
}
<form id="form1" onsubmit="return false">
  <button id="btn1" onclick="clicked();">Submit</button>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

【讨论】:

  • 正确。或者,更好的是,转储内联 onclick 处理程序并使用单个函数,或者使用 jQuery 绑定两个函数。
  • @nnnnnn:确实。我假设这是代码被添加到由于某种原因他们无法更改该 HTML 的地方。 (令人惊讶的是有多少这样的问题。)
  • 是的,OP 刚刚在回应我在问题下的评论时确认了这种情况。
  • 我也有同样的想法,但我想是否有任何解决方法,但我相信它会增加理解代码的开销,将 onclick 内联附加到 html 并通过 js 将其设置为 false 并使用 .call 运行它(另一种方法)。那不是很混乱吗?代码可读性可能会让新手感到困惑?
  • @user3205479:你必须做你必须做的事。如果您一开始就被 onclick 处理程序所困扰,那么这几乎是您解决浏览器差异的唯一方法。我不认为代码特别令人困惑,但是如果需要,您可以使用 cmets 来帮助以后来的人。
【解决方案2】:

试试event.stopPropagation() api docs

【讨论】:

  • 它不起作用,它用于冒泡事件而不是相同元素
  • 你注册了两个监听器。
  • OP 已经尝试过stopImmediatePropogation(),它将完成stopPropagation() 所做的一切以及更多。
  • onclick 不是一个监听器,它是一个附加的处理程序,唯一的方法是设置为 onclick=null;但是如何在不设置为 null 的情况下停止从事件侦听器触发内联事件
  • 要求是内联的“onclick”事件,必须有它的要求。
【解决方案3】:

如果条件为真,则删除“onclick”属性

if (some_condition == true) {
    $("#btn1").removeAttr('onclick').click(function(event) {
        alert("event triggered");

        //do something
    });
}


function clicked() {
    alert("clicked me");
}

【讨论】:

    【解决方案4】:

    我正在分享一个快速解决方法,但不知道为什么您无法添加逻辑来停止添加您所说的自动添加的“onclick="clicked();”代码。

    我建议您隐藏 id 为“btn1”的按钮。添加样式显示:无。您不需要为此准备就绪功能,只需将样式属性添加到按钮 btn1 或者如果这也无法直接使用,则使用 jQuery 来准备好发布文档。 读 : How to change css display none or block property using Jquery?

    然后使用 jQuery 向表单添加一个新按钮,其 id 为“btn2”,并添加注册 btn2 点击事件。在表单加载后执行此操作。

    <form id="form1">
    <div id="newbut">
    <button id="btn1" onclick="clicked();">Submit</button>
    </div>
    </form>
    
    jQuery("#newbut").html('<button id="btn2">Submit</button>');
    $(document).on('click', '#btn2', function(){ 
         // Your Code
     });
    

    如何注册新按钮的点击事件请参考以下网址:

    Adding click event for a button created dynamically using jQuery jquery - Click event not working for dynamically created button

    【讨论】:

      【解决方案5】:

      你不能在一个函数中进行条件检查和 clicked() 逻辑吗?即

      <script>
       function clicked() { 
           if(some_condition == true){
               return;
           }
           alert("clicked me");
       }
      </script>
      

      【讨论】: