要点:如果传递第二个参数,则第一个参数中的HTML字符串必须表示没有属性的简单元素.从jQuery 1.4开始,可以传入任何event type,并且可以调用以下jQuery方法:val,css,html,text,data,width,height或offset.
从jQuery 1.8开始,任何(强调添加)jQuery实例方法(jQuery.fn的方法)都可以用作传递给第二个参数的对象的属性:
将animate作为属性传递时,该元素似乎立即设置css属性
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>
尝试以两种方式设置动画的持续时间
animate: {fontSize:"22px",duration:5000}
似乎没有识别持续时间属性,和
animate: {fontSize:"22px",{duration:5000}}
记录Uncaught SyntaxError:Unexpected token {error to console.
设置css:{transition:font-size 5s}确实会返回预期的结果
var div = $("<div></div>",animate: {
fontSize:"22px"},data: {
fontSize: "12px"
},css:{
transition: "font-size 5s"
},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方法
直.
题:
如何将其他属性传递给动画或其他接受多个对象属性作为参数的jQuery方法;例如,在jQuery()的第二个参数中定义的.animate()方法的持续时间或步骤?
解决方法
但是持续时间的特定值只能通过第二个参数传递给所有可用的jQuery方法签名中的动画.
jQuery不支持将多个参数传递给在作为第二个参数传递给jQuery()的普通对象中指定为属性的函数.
这可以从这个代码片段中看到,该代码片段取自jQuery v1.12.0 sources附近的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的情况下 – 默认持续时间为400毫秒.
解决方法1:覆盖默认值
当然可以选择将默认持续时间更改为所需的持续时间,并在$(html,plainobject)调用之后立即恢复:
$.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>
但是你可以更好地链接animate方法:
解决方法2:链接动画调用
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>
解决方法3:创建插件
您还可以定义一个插件,该插件将接受每个方法的参数数组,而不只是一个参数:
$.fn.multiargs = function(arg) {
for (key in arg) {
$.fn[key].apply(this,arg[key]);
}
};
现在,您可以使用2nd-arg-object完成所有操作,使用数组作为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>
解决方法4:修补jQuery库
如果在我的答案开头引用的jQuery代码将被修改,以便这行:
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>",animate: [{
fontSize:"100px",{
duration: 5000,done: function() {
$(this).text('Done');
}
}]
});
并且您将获得与变通方法3相同的结果.
但请注意,当jQuery方法确实需要将数组作为第一个参数时,它可能会产生不良影响.所以这段代码需要进行一些调整才能正确处理这种情况.
另请注意,如果您要使用jQuery的修改版本,则只要您想要升级到更新的jQuery版本,就需要重新应用该更改.
解决方法5:在运行时重新定义$.fn.init
您可以在运行时替换$.fn.init,并且对于它提供的所有其他功能,您可以依赖它的原始版本:
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>",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.init方法之外定义的一些私有变量.我在评论中用“Path”标记,我修改了原始代码.
很明显,$.fn.init并没有像这样被推翻.
最后,我觉得这种方法的缺点比它带来的优势3更重要.