首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在vanilla JavaScript和jQuery中禁用按钮

在vanilla JavaScript和jQuery中禁用按钮
EN

Stack Overflow用户
提问于 2016-08-06 21:44:38
回答 4查看 14.7K关注 0票数 19

香草JavaScript

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

代码语言:javascript
复制
button.disabled = state;

这在人类尝试单击按钮和以编程方式单击按钮时都有效:

代码语言:javascript
复制
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
代码语言:javascript
复制
<input type="button" id="myButton" value="button" onClick="alert('Hello')"/>

这在使用MouseEvent接口时也适用:

代码语言:javascript
复制
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
代码语言:javascript
复制
<input type="button" id="myButton" value="button" onClick="alert('Hello')"/>

jQuery

不过,我似乎不能用jQuery做同样的事情:

代码语言:javascript
复制
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"
代码语言:javascript
复制
<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”的输出顺序是错误的。

我能想出的模拟普通JavaScript版本行为的最简单代码是:

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

当然,要实现像禁用按钮这样简单的功能,需要极其复杂和“老套”的代码。

我的问题

  • 为什么jQuery -不像普通的JS -在禁用按钮时不禁用事件?
  • 这是jQuery中的错误还是功能?
  • is something I'm jQuery有更简单的方法在jQuery中获得预期的行为吗?
EN

回答 4

Stack Overflow用户

发布于 2016-08-13 12:14:34

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

将属性事件侦听器定义为命名函数,其中可以传递this,以便在调用或未调用alert()的情况下检查if条件下的disabled属性。

使用.attr("disabled", "disabled")在元素处设置disabled,使用.removeAttr("disabled")删除属性;使用.attr("onclick", null)删除事件属性onclick处理程序;使用.attr("onclick", "handleClick(true)")重置事件属性。

代码语言:javascript
复制
<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>

票数 2
EN

Stack Overflow用户

发布于 2016-08-09 02:45:54

如果你看一下jquery-1.12.4.js的以下几行:

代码语言:javascript
复制
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" ) ) {

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

代码语言:javascript
复制
$(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();
  });
});
代码语言:javascript
复制
<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>

当然,如果像这样附加事件:

代码语言:javascript
复制
$('#btn').on("click", function() {
    alert("world");
});

这种行为是不同的,看起来很奇怪。

票数 1
EN

Stack Overflow用户

发布于 2016-08-08 23:54:05

使用.prop()是正确的方法。我认为问题出在你“测试”它的方式上。在这个示例中,无论处理程序是通过onclick还是通过jquery附加的,都可以使用切换按钮正确地禁用/启用按钮。

代码语言:javascript
复制
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();
    
  });

})
代码语言:javascript
复制
<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"/>

另一个显而易见的解决方案是只使用普通的javascript。仅仅因为您正在使用jQuery并不意味着所有的事情都必须使用它来完成。有一些事情在没有jQuery的情况下也可以做。

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38804924

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档