如何将选项对象作为参数传递给在jQuery()的第二个参数处设置的方法? [英] How to pass options objects as parameters to method set at second parameter of jQuery()?

查看:57
本文介绍了如何将选项对象作为参数传递给在jQuery()的第二个参数处设置的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

jQuery()处:

重要提示:如果传递了第二个参数,则第一个参数中的HTML字符串必须表示一个没有属性的简单元素. 从jQuery 1.4开始,任何 val css 文本宽度高度偏移量.

Important: If the second argument is passed, the HTML string in the first argument must represent a simple element with no attributes. As of jQuery 1.4, any event type can be passed in, and the following jQuery methods can be called: val, css, html, text, data, width, height, or offset.

自jQuery 1.8起 any (已加重)可以将jQuery实例方法(一种jQuery.fn方法)用作传递给该对象的对象的属性.第二个参数:

As of jQuery 1.8, any (emphasis added) jQuery instance method (a method of jQuery.fn) can be used as a property of the object passed to the second parameter:

animate作为属性传递时,该元素似乎会立即设置css属性

When passing animate as a property, the element appears to immediately set the css properties

var div = $("<div></div>", {
     id: "foo",
     "class": "a",
     animate: {
        fontSize:"22px"
     },
     data: {
        fontSize: "12px"
     },
     text: "click",
     on: {
       "click": function(e) {
         $(this).css($(this).data())
       }
     }
   });

   $("body").append(div);

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>

尝试通过两种方式设置animateduration

Attempted to set the duration of animate two ways

  animate: {fontSize:"22px", duration:5000}

似乎无法识别duration属性的

which does not appear to recognize the duration property , and

  animate: {fontSize:"22px", {duration:5000}}

Uncaught SyntaxError: Unexpected token {错误记录到console.

设置css:{transition: font-size 5s}确实会返回预期结果

While setting css:{transition: font-size 5s} does return expected results

var div = $("<div></div>", {
     id: "foo",
     "class": "a",
     animate: {
       fontSize:"22px"},
     data: {
       fontSize: "12px"
     },
     css:{
       transition: "font-size 5s"
     },
     text: "click",
     on: {
       "click": function(e) {
         $(this).css($(this).data())
       }
     }
   });

   $("body").append(div);

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>

应该可以将options对象传递给animate方法 直接.

it should be possible to pass the options object to the animate method directly.

问题:

如何将其他属性传递给animate或其他接受多个对象属性作为参数的jQuery方法;例如durationstep.animate()方法的第二个参数中定义的.animate()方法?

How to pass additional properties to animate , or other jQuery methods that accept multiple object properties as parameters; for example duration or step to the .animate() method defined at second parameter to jQuery() ?

推荐答案

<动画>动画方法的默认持续时间为400毫秒.而且,如果您运行发布的第一个代码段,则会看到CSS在短时间内(0.4s)处于动画状态.

The default duration for the animate method is 400ms. And if you run the first snippet you posted, you'll see the CSS is animated for that short period (0.4s).

但是持续时间的特定值只能通过所有可用的jQuery方法签名中的第二个参数传递给 animate .

But a specific value for duration can only be passed via the second argument to animate in all available jQuery method signatures.

jQuery不支持将多个参数传递给在普通对象中指定为属性的函数,该函数作为第二个参数传递给 jQuery().

jQuery has no support for passing more than one argument to functions specified as properties in the plain object that is passed as second argument to jQuery().

jQuery v1.12.0来源中摘录的代码片段中可以看出这一点 a>,靠近2912行:

This can be seen from this code snippet taken from the jQuery v1.12.0 sources, near line 2912:

// HANDLE: $(html, props)
if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
    for ( match in context ) {

        // Properties of context are called as methods if possible
        if ( jQuery.isFunction( this[ match ] ) ) {
            this[ match ]( context[ match ] );   // <-------------

        // ...and otherwise set as attributes
        } else {
            this.attr( match, context[ match ] );
        }
    }
}

因此无法以这种方式将持续时间传递给 .animate ,因此-对于 .animate -默认持续时间为400ms将适用.

So there is no way to pass a duration to .animate in that way, and so -- in the case of .animate -- the default duration of 400ms will apply.

当然可以选择将默认持续时间更改为所需的持续时间,并在$(html, plainobject)调用后立即将其恢复:

There is of course the option to change the default duration to the desired duration and restore it right after the $(html, plainobject) call:

$.fx.speeds._default = 5000; // change default
var div = $("<div></div>", {
    animate: {
        fontSize:"100px",
    },
    text: "animated text",
});
$.fx.speeds._default = 400; // restore;

$("body").append(div);

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

但是您可以更好地链接动画方法:

But then you can better chain the animate method:

var div = $("<div></div>", {
    text: "animated text",
}).animate({
    fontSize:"100px",
}, 5000);

$("body").append(div);

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

您还可以定义一个插件,该插件将为每个方法接受一个参数数组,而不仅仅是一个参数:

You could also define a plug-in that will accept an array of arguments for each method, instead of just one argument:

$.fn.multiargs = function(arg) {
    for (key in arg) {
        $.fn[key].apply(this, arg[key]);
    }
};

现在,您可以使用2nd-arg-object来完成所有操作,并使用数组作为method-properties的值:

Now you can use the 2nd-arg-object to do it all, using arrays as values for the method-properties:

$.fn.multiargs = function(arg) {
    for (var key in arg) {
        $.fn[key].apply(this, arg[key]);
    }
    return this;
};

var div = $("<div></div>", {
    multiargs: {
        text: ["animated text"],
        animate: [{
            fontSize:"100px",
        }, {
            duration: 5000,
            done: function() {
                $(this).text('Done');
            }
        }]
    }
});

$("body").append(div);

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

如果我的答案开头引用的jQuery代码将被修改,以使这一行:

If the jQuery code quoted at the start of my answer would be modified so that this line:

        this[ match ].apply(this, context[ match ]);

...已被替换为

        if ( jQuery.isArray( context[ match ] ) ) {
            this[ match ].apply(this, context[ match ]);
        } else {
            this[ match ]( context[ match ] );
        }

那么你可以这样写:

var div = $("<div></div>", {
    text: "animated text",
    animate: [{
        fontSize:"100px",
    }, {
        duration: 5000,
        done: function() {
            $(this).text('Done');
        }
    }]
});

您将获得与解决方法3相同的结果.

And you would get the same results as in workaround 3.

但是请注意,当jQuery方法确实需要获取数组作为第一个参数时,它可能会产生不良影响.因此,此代码需要更多调整才能正确处理此类情况.

Note however that it might have undesired effects when a jQuery method really needs to get an array as the first argument. So this code would need some more tweaking to deal with such situations correctly.

还请注意,如果要使用jQuery的修改版,则每当要升级到较新的jQuery版本时,都需要重新应用该更改.

Also note that if you would use a modified version of jQuery, you'll need to reapply that change whenever you want to upgrade to a newer jQuery version.

您可以在运行时替换 $.fn.init ,对于它提供的所有其他功能,您可以依靠它的原始版本:

You could replace $.fn.init at run-time, and for all other functionality it provides you could rely on the original version of it:

var prev_$_init = $.fn.init;
var init = jQuery.fn.init = function( selector, context, root ) {
    var match, elem,
        // redefine regexes that are private to jQuery:
        rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
        rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );

    // Handle HTML strings
    if ( typeof selector === "string" ) {
        if ( selector[ 0 ] === "<" &&
            selector[ selector.length - 1 ] === ">" &&
            selector.length >= 3 ) {

            // Assume that strings that start and end with <> are HTML and skip the regex check
            match = [ null, selector, null ];

        } else {
            match = rquickExpr.exec( selector );
        }

        // Match html or make sure no context is specified for #id
        if ( match && ( match[ 1 ] || !context ) ) {

            // HANDLE: $(html) -> $(array)
            // Patch: do not treat jQuery object as context here:
            if ( match[ 1 ] && !(context instanceof jQuery)) {
                // Option to run scripts is true for back-compat
                // Intentionally let the error be thrown if parseHTML is not present
                // Patch: simplify this call, as context is not jQuery:
                jQuery.merge( this, jQuery.parseHTML(
                    match[ 1 ],
                    document,
                    true
                ) );

                // HANDLE: $(html, props)
                if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
                    for ( match in context ) {

                        // Properties of context are called as methods if possible
                        if ( jQuery.isFunction( this[ match ] ) ) {
                            // Patch:
                            if ( jQuery.isArray( context[ match ] ) ) {
                                this[ match ].apply(this, context[ match ]);
                            } else {
                                this[ match ]( context[ match ] );
                            }

                        // ...and otherwise set as attributes
                        } else {
                            this.attr( match, context[ match ] );
                        }
                    }
                }

                return this;
            }
        }  
    }
    // Patch: forward call to original fn.init
    return prev_$_init.apply(this, arguments);
};
init.prototype = jQuery.fn;
    
var div = $("<div></div>", {
    text: "animated text",
    animate: [{
        fontSize:"100px",
    }, {
        duration: 5000,
        done: function() {
            $(this).text('Done');
        }
    }]
});

$("body").append(div);

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

这可行,但是它从原始的 $.fn.init 代码中复制了很多代码,并且需要重新定义jQuery库在 $.fn之外定义的一些私有变量.初始化方法.我在修改原始代码的地方用路径"标记了注释.

This works, but this copies quite some code from the original $.fn.init code and needs to redefine some private variables which the jQuery library defines outside of the $.fn.init method. I marked in comments with "Path" where I modified the original code.

很明显, $.fn.init 并非旨在像这样被否决.

It is clear that $.fn.init was not designed to be overruled like this.

最后,我觉得这种方法的缺点比解决方法3带来的优势更为重要.

Concluding, I feel the downsides of this approach are more important than the advantages it brings over workaround 3.

这篇关于如何将选项对象作为参数传递给在jQuery()的第二个参数处设置的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆