禁用vanilla JavaScript和jQuery中的按钮

Joh*_*ers 16 javascript jquery event-handling dom-events jquery-events

香草JavaScript

在vanilla JavaScript中,可以使用以下语句轻松启用和禁用按钮:

button.disabled = state;
Run Code Online (Sandbox Code Playgroud)

当人类尝试单击按钮并以编程方式单击按钮时,这都适用:

var button = document.getElementById('myButton');

button.addEventListener('click', function() {
    alert('world');
});

button.disabled = true;
button.click(); // No output
button.disabled = false;
button.click(); // Output : "Hello" and "world
button.disabled = true;
button.click(); // No output
Run Code Online (Sandbox Code Playgroud)
<input type="button" id="myButton" value="button" onClick="alert('Hello')"/>
Run Code Online (Sandbox Code Playgroud)

这在使用MouseEvent界面时也有效:

var button = document.getElementById('myButton');

var click = new MouseEvent("click", {
    "view": window
});

button.addEventListener('click', function() {
    alert('world');
});

button.disabled = true;
button.dispatchEvent(click); // No output
button.disabled = false;
button.dispatchEvent(click); // Output : "Hello" and "world
button.disabled = true;
button.dispatchEvent(click); // No output
Run Code Online (Sandbox Code Playgroud)
<input type="button" id="myButton" value="button" onClick="alert('Hello')"/>
Run Code Online (Sandbox Code Playgroud)


jQuery的

我似乎无法用jQuery做同样的事情:

var button = $("#myButton");

button.on("click", function() {
    alert("world");
});

button.prop("disabled", true);
button.click(); // Output : "world" and "Hello"
button.prop("disabled", false);
button.click(); // Output : "world" and "Hello"
button.prop("disabled", true);
button.click(); // Output : "world" and "Hello"
Run Code Online (Sandbox Code Playgroud)
<script src="https://code.jquery.com/jquery-1.12.2.min.js"></script>
<input type="button" id="myButton" value="button" onClick="alert('Hello')"/>
Run Code Online (Sandbox Code Playgroud)

双方button.prop("disabled", true);button.attr("disabled", true);简单地改变disabled了按钮元素的属性,但没有禁用实际点击事件.这意味着button.click();即使按钮被禁用,也会在调用时触发事件!

另外,"world"和"Hello"以错误的顺序输出.

我可以用来模拟vanilla JavaScript版本行为的最简单代码是:

var button = $("#myButton");

button.on("click", function() {
    alert("world");
});

button.disable = (function() {
    var onclick = null;
    var click = [];
    return function(state) {
        if(state) {
            this.prop('disabled', true);
            if(this.prop('onclick') !== null) {
                onclick = this.prop('onclick');
                this.prop('onclick', null);
            }
            var listeners = $._data(this.get()[0], "events");
            listeners = typeof listeners === 'undefined' ? [] : listeners['click'];
            if(listeners && listeners.length > 0) {
                for(var i = 0; i < listeners.length; i++) {
                    click.push(listeners[i].handler);
                }
                this.off('click');
            }
        } else {
            this.removeProp('disabled');
            if(onclick !== null) {
                this.prop('onclick', onclick);
                onclick = null;
            }
            if(click.length > 0) {
                this.off('click');
                for(var i = 0; i < click.length; i++) {
                    this.on("click", click[i]);
                }
                click = [];
            }
        }
    }
})();

button.disable(true);
button.click(); // No output
button.disable(false);
button.click(); // Output : "Hello" and "world
button.disable(true);
button.click(); // No output
Run Code Online (Sandbox Code Playgroud)
<script src="https://code.jquery.com/jquery-1.12.2.min.js"></script>
<input type="button" id="myButton" value="button" onClick="alert('Hello')"/>
Run Code Online (Sandbox Code Playgroud)

当然,这是一个荒谬的复杂和"hacky"代码,可以实现像禁用按钮一样简单的功能.


我的问题

  • 为什么jQuery - 不像vanilla JS - 在禁用按钮时不会禁用事件?
  • 这被认为是jQuery中的错误或功能吗?
  • 我有什么东西可以俯瞰吗?
  • 有没有更简单的方法来获得jQuery中的预期行为?

mcg*_*hix 0

使用 .prop() 是正确的方法。我认为问题在于你“测试”它的方式。请参阅此示例,其中使用切换按钮正确禁用/启用按钮,无论处理程序是通过 onclick 还是使用 jquery 附加。

window.testFunc = function(event) {
  if (!$('#myButton2').prop('disabled')) {
     alert("hello");
     console.log("hello");
  }
}

$(document).ready(function() {
  var button = $("#myButton2");

  button.on("click", function(event) {
    if (!$(this).prop('disabled')) {
        alert("world");    
        console.log("world");
    }
  });

  $('#toggleButton').click(function() {
	  $('#myButton1').prop('disabled', !$('#myButton1').prop('disabled'));
      $('#myButton2').prop('disabled', !$('#myButton2').prop('disabled'));
  });
  
  $('#tester').click(function() {
  	$('#myButton1').click();
    $('#myButton2').click();
    
  });

})
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" id="myButton1" value="vanilla button (hello)" onclick="window.testFunc(event)"/>
<input type="button" id="myButton2" value="jquery button (world)"/>
<input type="button" id="toggleButton" value="toggle disabled"/>
<input type="button" id="tester" value="test the buttons"/>
Run Code Online (Sandbox Code Playgroud)

另一个明显的解决方案是只使用普通的 javascript。仅仅因为您使用 jQuery 并不意味着所有事情都“必须”使用它来完成。有些事情不用 jQuery 也可以完成。

编辑:我编辑了显示如何防止 jquery 的 .click() 实际触发警报的代码片段。