禁用vanilla JavaScript和jQuery

时间:2016-08-06 13:44:38

标签: javascript jquery event-handling dom-events jquery-events

Vanilla JavaScript

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

button.disabled = state;

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

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
<input type="button" id="myButton" value="button" onClick="alert('Hello')"/>

使用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
<input type="button" id="myButton" value="button" onClick="alert('Hello')"/>

的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"
<script src="https://code.jquery.com/jquery-1.12.2.min.js"></script>
<input type="button" id="myButton" value="button" onClick="alert('Hello')"/>

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
<script src="https://code.jquery.com/jquery-1.12.2.min.js"></script>
<input type="button" id="myButton" value="button" onClick="alert('Hello')"/>

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

我的问题

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

4 个答案:

答案 0 :(得分:2)

为了达到预期的结果,您可以在jQuery触发的.isTrigger处理程序中使用click来确定事件是否由javascript触发,而不是用户操作。

将属性事件侦听器定义为命名函数,如果调用this或未调用disabled,则if可以在alert()条件下检查.attr("disabled", "disabled")属性。< / p>

使用disabled在元素.removeAttr("disabled")设置.attr("onclick", null)以删除属性; onclick删除事件属性.attr("onclick", "handleClick(true)")处理程序; <script src="https://code.jquery.com/jquery-3.1.0.js"></script> <input type="button" id="myButton" value="button" onclick="handleClick(this)" /> <script> function handleClick(el) { if (el.disabled !== "disabled") alert("Hello") } var button = $("#myButton"); button.on("click", function(e) { console.log(e); if (e.isTrigger !== 3 && !e.target.disabled) alert("world"); }); button.attr("disabled", "disabled"); button.attr("onclick", null); button.click(); // no output setTimeout(function() { button.removeAttr("disabled"); button.attr("onclick", "handleClick(button[0])"); button.click(); // Output : "world" and "Hello" // click button during 9000 between `setTimeout` calls // to call both jQuery event and event attribute }, 1000); setTimeout(function() { button.attr("disabled", "disabled"); button.attr("onclick", null); button.click(); // no output }, 10000); </script>重置事件属性。

dict1 = {'A': {'val1': '5', 'val2': '1'},
  'B': {'val1': '10', 'val2': '10'},
  'C': {'val1': '15', 'val3': '100'}

答案 1 :(得分:1)

如果您在这些方面看一下jquery-1.12.4.js

handlers: function( event, handlers ) {
    var i, matches, sel, handleObj,
        handlerQueue = [],
        delegateCount = handlers.delegateCount,
        cur = event.target;

    // Support (at least): Chrome, IE9
    // Find delegate handlers
    // Black-hole SVG <use> instance trees (#13180)
    //
    // Support: Firefox<=42+
    // Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
    if ( delegateCount && cur.nodeType &&
        ( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {

        /* jshint eqeqeq: false */
        for ( ; cur != this; cur = cur.parentNode || this ) {
            /* jshint eqeqeq: true */

            // Don't check non-elements (#13208)
            // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
            if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {

根据委托类型,您会看到不同的事件处理:

$(document).on("click", '#btn', function() {
  console.log("world");
});


$(function () {
  $('#btnToggle').on('click', function(e) {
    $('#btn').prop('disabled', !$('#btn').prop('disabled'));
  });
  
  
  $('#btnTestClick').on('click', function(e) {
    $('#btn').click();
  });
});
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>

<button id="btn">Click  Me</button>
<button id="btnToggle">Enable/Disable button</button>
<button id="btnTestClick">Test Click</button>

当然,如果你附上如下事件:

$('#btn').on("click", function() {
    alert("world");
});

行为不同,看起来很奇怪。

答案 2 :(得分:0)

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

&#13;
&#13;
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();
    
  });

})
&#13;
<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"/>
&#13;
&#13;
&#13;

另一个明显的解决方案是使用vanilla javascript。仅仅因为你使用jQuery并不意味着一切都必须&#34;必须&#34;用它完成。如果没有jQuery,有些事情可以做得很好。

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

答案 3 :(得分:0)

你直接调用点击功能3次(button.click())无论属性如何都会触发。

disabled属性仅响应单击事件。

请参阅更新的示例:

&#13;
&#13;
    var button = $("#myButton");
var button2 = $("#myButton2");

button.prop("disabled", false);

button.on("click", function() {
    alert("world");
   button2.prop("disabled", false);
});

button2.prop("disabled", true); 

button2.on("click", function() {
    alert("world");
   button.prop("disabled", true);
});
&#13;
<script src="https://code.jquery.com/jquery-1.12.2.min.js"></script>
<input type="button" id="myButton" value="button" onClick="alert('Hello')"/>
<input type="button" id="myButton2" value="button2" />
&#13;
&#13;
&#13;