简体   繁体   English

动态更改复选框不会触发onChange?

[英]Dynamically changing a checkbox doesn't trigger onChange?

Note: jQuery is not an option. 注意:jQuery不是一个选项。

I want to detect a change in the state of a checkbox, but the onChange event doesn't seem to fire when I do this: 我想检测复选框状态的变化,但是当我这样做时,onChange事件似乎没有触发:

document.getElementById('myCheckBox').addEventListener('change',function() {
    console.log('Changed!');
});
document.getElementById('someLink').onClick = function() {
    // toggle checkbox
    document.getElementById('myCheckBox').checked = !document.getElementById('myCheckBox').checked;
};

When I click #someLink the change event is not fired. 当我单击#someLink时,不会触发更改事件。 I could add another listener to #myLink, but then if I add other links that check the same box I have to add more listeners. 我可以为#myLink添加另一个监听器,但是如果我添加其他检查同一个框的链接,我必须添加更多的监听器。 I want one listener for a checkbox change event. 我想要一个监听器来进行复选框更改事件。 Again, jQuery is not an option, I need vanilla JS. 同样,jQuery不是一个选项,我需要vanilla JS。

EDIT: Sorry if I did not make this more clear, but I want to avoid adding complexity to each link that will check this box. 编辑:对不起,如果我没有说清楚,但我想避免增加每个链接的复杂性,将检查此框。 So ideally (and maybe the answer is that this is impossible) I don't want to have to alter the link/click logic at all. 理想情况下 (也许答案是这是不可能的)我根本不想改变链接/点击逻辑。 I want to be able to change the .checked property anywhere in the code and have it be detected without additional logic at each change (if possible). 我希望能够在代码中的任何位置更改.checked属性,并在每次更改时检测它而无需额外的逻辑(如果可能)。

UPDATE: 更新:

Okay so there is apparently no way to do this nicely without altering the onClick logic, so (like some kind of animal) I ended up brute forcing the problem as follows: 好的,所以显然没有办法在不改变onClick逻辑的情况下很好地做到这一点,所以(就像某种动物一样)我最终蛮力强迫问题如下:

function mySentinel() {
    if(document.getElementById('myCheckBox').checked) {
        console.log("I've been checked!");
        return;
    }
    setTimeout("mySentinel()",100);
}
// then call this somewhere in the on document load section...
mySentinel();

You can add some sort of timeout if you want also: 如果您还需要,可以添加某种超时:

function mySentinel(var i) {
    if(document.getElementById('myCheckBox').checked) {
        console.log("I've been checked!");
        return;
    }
    if(i <= 0) {
        console.log("Time out. Still not checked");
    }
    i--;
    setTimeout("mySentinel("+i+")",100);
}
// then call this somewhere in the on document load section...
// 60 second timeout (some math can make the argument look nicer)
mySentinel(600);

That is correct, changing the value or checked state of an input programatically does not fire the event handlers. 这是正确的,以编程方式更改输入的值或检查状态不会触发事件处理程序。

You'll have to trigger the event as well with javascript 您还必须使用javascript触发事件

document.getElementById('myCheckBox').addEventListener('change',function() {
    console.log('Changed!');
});

document.getElementById('someLink').onclick = function() {
    var box = document.getElementById('myCheckBox')
    box.checked = !box.checked;

    if ("createEvent" in document) {
        var evt = document.createEvent("HTMLEvents");
        evt.initEvent("change", false, true);
        box.dispatchEvent(evt);
    } else {
        box.fireEvent("onchange");
    }
};

and note that's it's onclick (all lowercase) 并注意它是onclick (全部小写)

FIDDLE 小提琴


EDIT 编辑

I want to avoid adding complexity to each link that will check this box. 我想避免为每个链接添加复杂性来检查此框。
So ideally ... I don't want to have to alter the link/click logic at all. 理想情况......我根本不想改变链接/点击逻辑。
I want to be able to change the .checked property anywhere in the code and have it be detected without additional logic at each change (if possible). 我希望能够在代码中的任何位置更改.checked属性,并在每次更改时检测它而无需额外的逻辑(如果可能)。

And that's not really possible, without using horrible hacks with intervals etc. When the checked state is changed programatically the event handler isn't triggered at all, because that would really be a huge issue in most cases, and much harder to work around the opposite scenario, where you just trigger the event handler manually instead, and that is really the only way to do it. 如果没有使用间隔等可怕的黑客攻击,这是不可能的。当以编程方式更改检查状态时,根本不会触发事件处理程序,因为在大多数情况下这确实是一个很大的问题,并且更难以解决相反的情况,你只需手动触发事件处理程序,这是唯一的方法。

Of course, you can make it a lot more convenient using classes and external function and such 当然,你可以使用类和外部函数等方便它

document.getElementById('myCheckBox').addEventListener('change',function() {
    console.log('Changed!');
});

var links = document.querySelectorAll('.someLinkClass');

for (var i = links.length; i--;) {
    links[i].addEventListener('click', triggerChange, false);
}


function triggerChange() {
    var box = document.getElementById('myCheckBox')
    box.checked = !box.checked;

    if ("createEvent" in document) {
        var evt = document.createEvent("HTMLEvents");
        evt.initEvent("change", false, true);
        box.dispatchEvent(evt);
    } else {
        box.fireEvent("onchange");
    }
};

and anytime you add a link, you just add that class 无论何时添加链接,您只需添加该类

<a href="#" class="someLinkClass">Change the checkbox</a>
<a href="#" class="someLinkClass">Change the checkbox again</a>
<a href="#" class="someLinkClass">Change the checkbox even more</a>

etc. 等等

  1. If you want to add more links that will trigger the checkbox, create a class name for them and use getElementByClass('classname') 如果要添加更多将触发复选框的链接,请为它们创建类名并使用getElementByClass('classname')
  2. Use onclick in your html, not js. 在你的HTML中使用onclick,而不是js。 Example: <div onclick="doSomething()"></div> 示例: <div onclick="doSomething()"></div>
  3. Just use an if/else statement for the check/uncheck: 只需使用if / else语句进行检查/取消选中:

     if(document.getElementById('myCheck').checked){document.getElementById("myCheck").checked = false;} else{document.getElementById("myCheck").checked = true;} 

You can invoke/trigger an event but its not as easy as it seems, especially when you have to deal with internet explorer. 您可以调用/触发事件,但它并不像看起来那么容易,尤其是当您必须处理Internet Explorer时。

The cleanest solution is to put your event into its own function, then call it where you need it. 最干净的解决方案是将您的事件放入其自己的功能中,然后在您需要的地方调用它。

function handleEvent(){
    console.log('Changed!');
}

documentent.getElementById('myCheckBox').addEventListener('change',function() {
    handleEvent()
});
document.getElementById('someLink').onClick = function() {
    // toggle checkbox
    document.getElementById('myCheckBox').checked = !document.getElementById('myCheckBox').checked;
    handleEvent();
};

I think jQuery have a change event. 我认为jQuery有一个改变事件。 And you don't use it in the good way. 而你并没有以良好的方式使用它。

Read this page: http://api.jquery.com/change/ 阅读本页: http//api.jquery.com/change/

and this: jQuery checkbox change and click event 并且: jQuery复选框更改并单击事件

When any change occurs in the checkbox, jQuery event function is called. 当复选框中发生任何更改时,将调用jQuery事件函数。 And then you can write anything in this event function 然后你可以在这个事件函数中写任何东西

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM