【问题标题】:Dynamically Modifying Value of an Existing Event Handler动态修改现有事件处理程序的值
【发布时间】:2013-07-13 03:36:59
【问题描述】:

快速背景:我正在更新现有代码以将事件处理程序与 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) 我不再能看到处理程序是什么。

我已经尝试过了(在这个问题之后 - 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] 在 handler => => Closure 中有值,但似乎没有点符号可以访问它,甚至没有我可以访问的数组动态循环。

如果你告诉我这是不可能的,我可以将所有函数的 args 更改为 $(this) 并在每个函数中解析出必要的值,或者我想我可以有一个辅助函数.. . 但是,如果我可以保持与现有的设置类似的设置,它将简化其他开发人员的学习曲线。

最终解决方案

为了减少重复代码,我创建了一个 Javascript 函数/对象,它从名称/id 标记中解析出必要的信息(而不是 data- 属性以减少冗余信息)。每当触发事件处理程序时,它将首先解析出必要的值,然后运行带有它们的函数。

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

【问题讨论】:

  • “我可以将所有函数的参数更改为 $(this) 并在每个函数中解析出必要的值” - 这样做,你会帮其他开发者一个忙.实际上,您根本不需要任何参数,this 在处理程序中自动可用。此外,您可以一次绑定所有处理程序,或将单个处理程序委托给一个共同的祖先。
  • 是的,你可能是对的。关于这个 arg,我认为,我必须显式设置函数以接受它,例如:foreach 中的 somefucntion() 调用 anotherfunction(),其中 anotherfunction() 也在处理程序中调用。或者,我假设 foreach 没有将其传递给另一个函数是错误的?

标签: javascript jquery jquery-events jquery-on


【解决方案1】:

我在 cmets 中的建议是这样的:

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

此外,您可以使用data- 属性使其更简洁(例如data-element-number="1" 等),而不是从元素的name 中解析所有内容。

【讨论】:

  • 这和我昨晚做的很相似。我将在上面的问题中发布我所做的事情。虽然这不一定回答在事件处理程序中动态更改值的问题,但我认为这里的关键答案是更改数据必须在 name/id 或 data-attribute 中,因为这些值可以动态更改。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多