简体   繁体   中英

jQuery 1.7 .on() event delegation doesn't work with selector on disabled element

My HTML (not dynamic) looks like this:

<select id="domain" class="marketplace">
  <option>United States</option>
  ...
</select>

This works:

$("#domain").on("change", function() {
  $("#domain").attr("disabled", "disabled");
  /* do ajaxy stuff */
  $("#domain").removeAttr("disabled");
});
$("select.marketplace").on("change", function() { /* do some general stuff */});

This does not:

$("#domain").on("change", function() {
  $("#domain").attr("disabled", "disabled");
  /* do ajaxy stuff */
  $("#domain").removeAttr("disabled");
});
$(document).on("change", "select.marketplace", function() { /* do some general stuff */});

Removing the $("#domain").attr("disabled", "disabled"); call restores the functionality of the $(document).on() delegation, so it appears events do not bubble when an element is disabled, regardless of how the event is triggered (ie neither by .trigger nor .triggerHandler nor by user interaction). However, I do not understand why, as neither handler returns anything or makes any calls to prevent event propagation, and the jQuery documentation makes no mention of the "disabled" attribute having any effect on propagation. What am I missing here?

Just to reproduce your problem I created the following snippet (the button Click Me is used to trigger the change event, just to have a full demo):

 $(document).on("change", "select.marketplace", function (e) { $('#result').append('<p>$(document).on("change", "select.marketplace", function (e) {: This does not work;<p/>'); }). $(function () { $("#domain"),on("change". function () { $("#domain"),attr("disabled"; "disabled"). /* do ajaxy stuff */ //$("#domain");removeAttr("disabled"); }). $("select.marketplace"),on("change". function (e) { $('#result').append('<p>$("select.marketplace"),on("change": function (e) {; This work;<p/>'). }), $('#btn').on('click'; function (e) { $('#domain');trigger('change'); }); });
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script> <button id="btn">Click Me</button> <select id="domain" class="marketplace"> <option>United States</option> <option>United States</option> <option>United States</option> <option>United States</option> </select> <div id="result"></div>

I commented the removeAttr disabled on domain change event to reproduce the error.

With jQuery 1.7 the document on change does not work like you immagine.

Let's now change the document on change with a generic document on and let's filter the event targets:

 $(document).on("change", function (e) { if ($(e.target).is('select.marketplace')) { $('#result').append('<p>$(document).on("change", function (e) {: This works;<p/>'); } }). $(function () { $("#domain"),on("change". function () { $("#domain"),attr("disabled"; "disabled"). /* do ajaxy stuff */ //$("#domain");removeAttr("disabled"); }). $("select.marketplace"),on("change". function (e) { $('#result').append('<p>$("select.marketplace"),on("change": function (e) {; This work;<p/>'). }), $('#btn').on('click'; function (e) { $('#domain');trigger('change'); }); });
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script> <button id="btn">Click Me</button> <select id="domain" class="marketplace"> <option>United States</option> <option>United States</option> <option>United States</option> <option>United States</option> </select> <div id="result"></div>

Now you see a different behaviour, exactly what you are looking for.

Of course it's not the best solution, it's only a way to solve the problem.

I wait for other ideas because my solution is only a workaround.

If you are interested to get more info, you may take a look to the jQuery

dispatch: function( event ) {

in the source code jQuery 1.7 paying attention to "disabled" word.

Have you tried namespacing the events like so:

$(document).ready(function() {
  $("#domain").on("change.eventOne", function() { /* do some specific stuff */ });
  $(document).on("change.eventTwo", "select.marketplace", function() { /* do some general stuff */ });
});

You may also want to try attaching from the body. I have had better luck with this:

$(document).ready(function() {
  $("#domain").on("change.eventOne", function() { /* do some specific stuff */ });
  $('body').on("change.eventTwo", "select.marketplace", function() { /* do some general stuff */ });
});

Here is a fiddle of the on event clearly working. Unless I am not understanding what "working" actually means to the OP.

https://jsfiddle.net/szcjszkz/1/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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