Динамическое изменение значения существующего обработчика событий

Краткая предыстория: я обновляю существующий код, чтобы отделить обработчики событий от html-объектов, а затем в функции onload назначаю все необходимые обработчики.

$('input[name^="interactiveElement_"]').each(function() {
    var fieldName = "interactiveElement_";
    var elementNumber = $(this).attr("name").substring(fieldName.length,$(this).attr("name").indexOf("_",fieldName.length));
    var subElementNumber = $(this).attr("name").substring((fieldName+itemNumber+'_').length,$(this).attr("name").lastIndexOf('_'));
    var rowNumber = $(this).attr("name").substring($(this).attr("name").lastIndexOf('_')+1);

    $(this).on("click.custNamespace", function() {
        updateThisElementsMetadata(elementNumber, subElementNumber, rowNumber);
        updatePreview(elementNumber);
    });
});

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

Прежде чем отделить события, я делал это следующим образом:

var regex = /([^0-9]+[0-9]+[^0-9a-zA-Z]+[0-9]+[^0-9a-zA-Z]+)([0-9]+)([^0-9]+)?/g; 
$(element).attr("onclick",
                $(element)
                    .attr("onclick")
                    .replace(regex, "$1"+newValue+"$3"));

и так далее для каждого возможного события, которое могут иметь эти элементы.

Но теперь, используя jQuery on(event, handler), я больше не вижу, что такое обработчик.

Я пробовал это (после этого вопроса - Получить значение текущего обработчика событий с помощью jQuery):

jQuery._data(element).events.click[0].handler 

Но это возвращает функцию с именами переменных, а не со значениями.

function () {
    updateThisElementsMetadata(elementNumber, subElementNumber, rowNumber);
    updatePreview(elementNumber);
}

Где я бы надеялся:

function () {
    updateThisElementsMetadata(1, 2, 1);
    updatePreview(1);
}

Глядя в журнал консоли, я вижу, что jQuery._data(element).events.click[0] имеет значения в обработчике => ‹ область действия › => Closure, но не похоже, что для доступа к этому есть точечная нотация или даже массив, который я могу динамически циклически перебирать.

Если вы скажете мне, что это невозможно, я мог бы изменить все аргументы функций просто на $(this) и разобрать из них необходимые значения в каждой функции, или, я думаю, у меня могла бы быть вспомогательная функция... но если бы я мог сохраните настройку, аналогичную той, что была там, это облегчило бы кривую обучения других разработчиков.

Окончательное решение

Чтобы уменьшить дублирование кода, я создал функцию/объект Javascript, который анализирует необходимую информацию из тега имени/идентификатора (вместо атрибутов данных для уменьшения избыточной информации). Всякий раз, когда запускается обработчик событий, он сначала анализирует необходимые значения, а затем запускает функцию с ними.

$('input[name^="interactiveElement_"]').on("click.custNamespace", function() {
    var inputField = inputFieldClass(this);
    updateThisElementsMetadata(inputField.elementNumber, inputField.subElementNumber, inputField.rowNumber);
    updatePreview(inputField.elementNumber);
});


var inputFieldClass = function(field) {
    var fieldIdentity = $(field).attr("name") === undefined ?  $(field).attr("id") :  $(field).attr("name");
    var fieldName = fieldIdentity.substring(0,fieldIdentity.indexOf("_")),
        elementNumber = fieldIdentity.substring(fieldName.length + 1,fieldIdentity.indexOf("_",fieldName.length + 1)),
        subElementNumber = fieldIdentity.substring((fieldName+'_'+elementNumber+'_').length,fieldIdentity.lastIndexOf('_')),
        rowNumber = fieldIdentity.substring(fieldIdentity.lastIndexOf('_')+1);

    return {
        fieldName : fieldName,
        elementNumber : elementNumber,
        subElementNumber : subElementNumber,
        rowNumber : rowNumber,
        getInputName : function () {
            return this.name + "_" + this.elementNumber + "_" + this.subElementNumber + "_" + this.rowNumber;
        }
    };
};

person Ivonne    schedule 13.07.2013    source источник
comment
Я мог бы изменить аргументы всех функций просто на $(this) и извлечь из него необходимые значения в каждой функции — сделайте это, и вы окажете услугу другим разработчикам. На самом деле, вам вообще не нужны никакие аргументы, this автоматически доступен в обработчиках. Более того, вы можете привязать все обработчики сразу, либо делегировать один обработчик общему предку.   -  person bfavaretto    schedule 13.07.2013
comment
Да, наверное, ты прав. Что касается этого аргумента, я думаю, что мне нужно явно указать функцию, чтобы она принимала его, когда, например: somefucntion() в foreach вызывает otherfunction(), где otherfunction() также вызывается в обработчике. Или я ошибаюсь, предполагая, что foreach не передает это другой функции?   -  person Ivonne    schedule 15.07.2013


Ответы (1)


То, что я предлагал в комментариях, было примерно так:

$('input[name^="interactiveElement_"]').on("click.custNamespace", function() {

    var fieldName = "interactiveElement_";
    var elementNumber = $(this).attr("name").substring(fieldName.length,$(this).attr("name").indexOf("_",fieldName.length));
    var subElementNumber = $(this).attr("name").substring((fieldName+itemNumber+'_').length,$(this).attr("name").lastIndexOf('_'));
    var rowNumber = $(this).attr("name").substring($(this).attr("name").lastIndexOf('_')+1);

    updateThisElementsMetadata(elementNumber, subElementNumber, rowNumber);
    updatePreview(elementNumber);
});

Кроме того, вместо того, чтобы анализировать все из name элемента, вы можете использовать атрибуты data-, чтобы сделать его чище (например, data-element-number="1" и т. д.).

person bfavaretto    schedule 15.07.2013
comment
Это очень похоже на то, что я сделал прошлой ночью. Я опубликую то, что я сделал, как часть моего вопроса выше. Хотя это не обязательно отвечает на вопрос о динамическом изменении значений в обработчике событий, я думаю, что ключевой ответ здесь заключается в том, что изменение данных должно быть либо в имени/идентификаторе, либо в атрибутах данных, поскольку эти значения могут изменяться динамически. - person Ivonne; 16.07.2013