8

阅读 jQueryUI 对话框代码,我发现 jQuery .attr()方法有一些未记录的行为:

<button id="btn1">1</button>
<button id="btn2">2</button>

$(function() {
    var props = {
        text: 'Click it!',
        click: function () {
            console.log('Clicked btn:', this);
        }
    };

    $('#btn1').attr(props, true);    // Changes #btn1 inner text to 'Click it!' 
                                     // and adds click handler
    $('#btn2').attr(props);          // Leaves #btn2 inner text as it is and fires 
                                     // click function on document ready
});
  • 你能解释一下它是如何工作的吗?为什么要设置true为属性值对映射后的第二个参数?
  • 我可以在我的项目中安全地使用此功能吗?
4

3 回答 3

3

我在这里稍微猜测一下,因为我不熟悉 jQuery 源代码。jQuery.attr调用jQuery.access,jQuery.access 函数上方的注释如下:

// Multifunctional method to get and set values of a collection
// The value/s can optionally be executed if it's a function

经过进一步调查,该text()函数还调用jQuery.access

    attr: function( name, value ) {
        return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
    },
    .........
    text: function( value ) {
        return jQuery.access( this, function( value ) {
        ......
    },

您正在使用 attr 设置文本和事件处理程序,这不是 attr 的用途。然而,他们似乎都在使用相同的函数来完成工作,所以使用未记录的参数只是偶然地给你预期的行为。

我认为依靠未记录的行为来完成您在此处尝试执行的操作是不可靠的,因为将来对 jQuery 的任何升级都可能破坏您的代码。

于 2012-10-18T12:59:31.583 回答
2

查看 jQuery 1.8.2 代码,true参数最终到达变量pass中的一行:

exec = pass === undefined && jQuery.isFunction( value );

如果设置,告诉 jQuery 检查检查属于键的值,如果它是一个函数,则立即调用它。因此click: function(...)将调用该函数,而不是注册该函数。

这似乎是.method(function() { ... }各种 jQuery 函数版本的工作方式,即那些不是为属性传递特定值,而是传递一个函数,该函数本身传递原始值,并将其返回值分配给相关属性。

我可以在我的项目中安全地使用此功能吗?

我不会,直到它被记录下来。

于 2012-10-18T13:00:40.507 回答
0

这是一个有趣的。我不能假装告诉你/为什么/它可以这样工作,我认为甚至可能有理由将此作为错误报告提交给 jQuery,因为他们记录的行为并没有像我预期的那样出现.

在这个页面上,下面的引用出现在底部: http ://api.jquery.com/attr/

"注意:如果在 setter 函数中没有返回任何内容(即 function(index, attr){}),或者如果返回 undefined,则当前值不会更改。这对于仅在满足某些条件时选择性地设置值很有用。”

这导致我在 jsFiddle 上玩了一些:http: //jsfiddle.net/mori57/GvLcE/

请注意,与他们的文档相反,案例 8 和 9 返回 null 或不返回任何内容。看看 Alnitak 提到的内容,这似乎是有道理的,因为他们的测试/实际上/只是验证它/是一个函数/而不是该函数返回的内容(.isFunction 应该只返回真/假,这与说返回的值是真/假)。

然而,最后,我同意 Alnitak 和 bcoughlan 的观点,即这不是你应该依赖的功能,尽管我要补充一点,除了它不稳定之外,因为它可能会在未来的 jQuery 版本中发生变化,它依赖于未记录功能的黑客也是一种不好的做法,因为您今天编写的代码的未来开发人员(包括您,在 2-4 个月内!)很容易忘记它的存在,或者为什么它是这样设置的. 最好是明确的,并使用文档中的功能,以便您自己和其他人清楚您的代码打算做什么。

于 2012-10-18T13:19:09.273 回答