2013-07-13 2 views
1

Быстрый исходный код: я обновляю существующий код для разделения обработчиков событий из 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's on (event, handler), у меня больше нет видимости того, что является обработчиком.

Я попытался это (по этому вопросу - Get value of current event handler using 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] имеет значения в обработчике => < область видимости функции> => Закрытие, но это не кажется например, есть точка нотации для доступа к ней или даже массив, который я могу динамически прокручивать.

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

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

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

$('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; 
     } 
    }; 
}; 
+0

«Я мог бы изменить все аргументы функций только $ (this) и разобрать необходимые значения из него в каждой функции» - сделайте это, вы будете делать другие разработчики. На самом деле вам вообще не нужны какие-либо аргументы, 'this' автоматически доступен в обработчиках. Кроме того, вы можете сразу связать все обработчики или делегировать один обработчик общему предку. – bfavaretto

+0

Да, вы, вероятно, правы. Что касается этого аргумента, я думаю, что я должен явно установить функцию, чтобы принять его, например, например: somefucntion() в foreach вызывает другую функцию(), где другая функция() также вызывается в обработчике.Или, я ошибаюсь, полагая, что foreach не передает это другой функции? – Ivonne

ответ

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", и т.д.).

+1

Это очень похоже на то, что я делал прошлой ночью. Я опубликую то, что я сделал, как часть моего вопроса выше. Хотя это не обязательно отвечает на вопрос о динамически меняющихся значениях в обработчике событий, я думаю, что главный ответ здесь заключается в том, что изменение данных должно быть либо в имени/id, либо в атрибутах данных, поскольку эти значения могут быть изменены динамически. – Ivonne