使用函数更新jQuery的data()方法中的值设置等效于匿名函数的变量,而不是返回值

时间:2013-05-17 16:01:55

标签: javascript jquery

我回答了这个问题:Manipulate Custom Values with jQuery

使用这个jQuery:

$('img').attr('u', function(i,u) {
    /* i is the index of the current image among all the images returned by the selector,
       u is the current value of that attribute */
    return u.slice(0, -1) + (parseInt(u.replace(/\D/g,''), 10) + 1);
});

Link to answerJS Fiddle demo from that answer

但后来我觉得我应该展示如何正确地做到这一点,'使用HTML5下允许的自定义data-*属性(而不是无效的,尽管是功能性的自定义属性),所以我将HTML改编为:

<img src="http://placekitten.com/400/500" class="className" click="" id='button4' data-u="button6" data-r="button5" data-l="ele1" data-d="" />

(不,我不知道click属性的意图是什么,或者为什么会这样做,所以我不管它。)

并测试了以下jQuery:

$('img').data('u', function(i,u) {
    /* i is the index of the current image among all the images returned by the selector,
       u is the current value of that attribute */
    return u.slice(0, -1) + (parseInt(u.replace(/\D/g,''), 10) + 1);
});

$('img').each(function(){
    console.log($(this).data('u'));
});

JS Fiddle demo

现在,使用data()方法我意识到属性不会被更新,这就是为什么我使用console.log()来确认更新的值,然而输出是匿名函数本身,而不是我希望从函数返回的值。我意识到这不太可能是一个错误,并且可能是预期的行为,但有没有办法使用匿名函数来更新属性,例如,在attr()中使用的方式{ {1}}等等。?

3 个答案:

答案 0 :(得分:1)

基本上你的期望是错误的。

jQuery的.data根本不修改元素的数据属性;它只是通过自己选择的机制将您提供的数据与元素相关联。

实施故意未指定,.data根本不处理此数据;你把东西放进去,当你后来要求它时,你就会得到它。从jQuery的角度来看,数据是完全不透明的。

.data确实提供了来自其HTML data-属性的元素相关数据的预填充作为便利功能,但这不是它的主要任务。当然,在这种情况下,数据的不透明性仍然得到支持:当您要求数据时,您会准确地回复HTML中指定的内容。

答案 1 :(得分:1)

data和许多其他jquery函数(例如attr和许多其他函数)之间的区别在于data可以存储任何类型的对象。 attr只能存储字符串值。因此,想要使用data存储函数是完全有效的。

如果jquery团队要为data制作类似的签名,他们需要以某种方式区分想要存储函数和想要评估函数。它可能会让人感到困惑,因此他们只是没有执行该功能的能力。

我认为你能做的最好就是使用each

答案 2 :(得分:1)

如果您需要此功能,可以轻松添加:

$.fn.fdata = function( name, callback ) {
    return this.each( function( i, element ) {
        var $element = $(element);
        var data = callback( i, $element.data(name) );
        $element.data( name, data );
    });
};

现在您可以使用$(sel).fdata( name, callback );并在回调中执行您想要的操作。

扩展现有的$().data()方法以添加回调功能可能很诱人,但正如其他人指出的那样,这会破坏依赖于能够将函数引用存储为数据的任何其他代码。

当然,也可能只是添加这个.fdata()方法可能会破坏其他代码 - 如果页面上的某些其他代码也尝试在其自己的插件中使用相同的方法名称。因此,将它作为一个简单的函数可能更明智。代码几乎完全相同:

function updateData( selector, name, callback ) {
    $(selector).each( function( i, element ) {
        var $element = $(element);
        var data = callback( i, $element.data(name) );
        $element.data( name, data );
    });
}