Необходимо изменить событие изменения флажка, чтобы реагировать на изменение проверенного состояния, выполненного программно

(jQuery 1.4.4) У меня есть флажок, который имеет прослушиватель .change(), который отлично работает, когда пользователь нажимает этот флажок, но теперь мне также нужно, чтобы он срабатывал, когда я программно менял флажок в jQuery, используя .attr('checked', 'checked'). Я с удовольствием использую другие методы для этой работы. Спасибо.

$('#foo').attr('checked', 'checked'); // programmatically change the checkbox to checked, this checks the box alright

$('#foo').change( function() {
  // this works when user checks the box but not when the above code runs
}

Ответы

Ответ 1

Используйте jquery click(), чтобы изменить состояние флажка, а не изменять его атрибут.

Не имея всей вашей разметки, я не уверен, насколько это подходит, но я недавно использовал этот метод для хорошего эффекта.

Ответ 2

Если вы используете jQuery > 1.6, вы можете сделать это довольно разумно, указав attrHook;

jQuery.attrHooks.checked = {
    set: function (el, value) {
        if (el.checked !== value) {
            el.checked = value;
            $(el).trigger('change');
        }
    }
};

Как указано в комментариях, if избегает запускать событие change, если новое значение совпадает со старым значением.

... Хотя вы все равно должны использовать prop(), поэтому он должен быть:

jQuery.propHooks.checked = {
    set: function (el, value) {
        if (el.checked !== value) {
            el.checked = value;
            $(el).trigger('change');
        }
    }
};

Вы можете видеть, как это работает здесь; http://jsfiddle.net/2nKPY/

Для jQuery < 1.6 (или если вам не нравится добавление propHook), лучше всего вы можете переопределить метод attr() (или upgrade:));

(function () {
    var existingAttr = jQuery.fn.attr;

    jQuery.fn.attr = function (attr) {
        var result = existingAttr.apply(this, arguments);

        if (result instanceof jQuery && attr == "checked") { // If we're dealing with a check-set operation.
            result.trigger('change');
        }

        return this;
    };    

}());

Здесь вы можете увидеть это

Ответ 3

Как насчет:

$('some selector').trigger('click');

Ответ 4

Это будет срабатывать только тогда, когда значение проверки действительно изменится. В ответе Мата он будет срабатывать, даже если для этого флажка присваивается одинаковое значение.

$.propHooks.checked = {
    set: function (el, value) {
        if (el.checked !== value) {
            trigger = true;
        } else {
            trigger = false;
        }
        el.checked = value;
        if (trigger) {
            $(el).trigger('change');
        }
    }
};

Ответ 5

Если у вас есть относительно новая версия JQuery, вы можете использовать функцию .prop(), чтобы программно изменить этот флажок:

$(".myCheckbox").prop("checked", true);
$(".myCheckbox").prop("checked", false);

Ответ 6

Я работаю над плагином, который меняет изображения на основе состояния флажка, и я тоже сталкивался с этой проблемой.

Чтобы усложнить мне ситуацию, многие из ранее существовавшего кода, с которым я работаю (работая вокруг?;)), ожидают, что события изменения будут происходить только от взаимодействия с пользователем, поэтому запуск щелчка(), когда флажок должен be программно отмечен/не установлен, вызывает другие события, которые не должны срабатывать (эти другие обработчики должны выполняться только тогда, когда пользователь изменяет значение).

Решением, на котором я остановился, было привязка обработчика обновления образа к событию "change" и специальному событию, которое я назвал "updateicon". Затем, в propHooks.checked.set(), я запускаю это событие "updateicon". Это приводит к тому, что icon-updater может изменить значок так же, как когда пользователь нажимает на вход, но не приводит к пропуску пропущенных обработчиков изменений/кликов.

Связывание обработчика событий:

input.on("change updateicon", toggleIconVisibility);

Ключ изменения свойства:

jQuery.propHooks.checked = {
    set: function (el, value) {
        el.checked = value;
        $(el).trigger('updateicon');
    }
};

Примечание. В моем последнем черновике кода я запускаю $(el).filter( ".ifiedified" ). trigger ( "updateicon" ), чтобы запускать только "updateicon" для элементов, которые были "отображены" "моим плагином