最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Dynamically changing a checkbox doesn't trigger onChange? - Stack Overflow

programmeradmin2浏览0评论

Note: jQuery is not an option.

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:

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. 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. I want one listener for a checkbox change event. Again, jQuery is not an option, I need vanilla JS.

EDIT: Sorry if I did not make this more clear, but I want to avoid adding plexity 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).

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:

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);

Note: jQuery is not an option.

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:

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. 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. I want one listener for a checkbox change event. Again, jQuery is not an option, I need vanilla JS.

EDIT: Sorry if I did not make this more clear, but I want to avoid adding plexity 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).

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:

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);
Share Improve this question edited Aug 7, 2014 at 18:45 user439299 asked Aug 1, 2014 at 15:06 user439299user439299 8414 gold badges12 silver badges24 bronze badges 0
Add a ment  | 

4 Answers 4

Reset to default 6

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

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)

FIDDLE


EDIT

I want to avoid adding plexity 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).

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')
  2. Use onclick in your html, not js. Example: <div onclick="doSomething()"></div>
  3. Just use an if/else statement for the check/uncheck:

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

I think jQuery have a change event. And you don't use it in the good way.

Read this page: http://api.jquery./change/

and this: jQuery checkbox change and click event

When any change occurs in the checkbox, jQuery event function is called. And then you can write anything in this event function

You can invoke/trigger an event but its not as easy as it seems, especially when you have to deal with 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();
};
发布评论

评论列表(0)

  1. 暂无评论