重要提示:如果传递了第二个参数,则第一个参数中的HTML字符串必须表示一个没有属性的简单元素。从jQuery 1.4开始,可以传入任何事件类型,并且可以调用以下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>
试图设置duration
的animate
两种方式
animate: {fontSize:"22px", duration:5000}
似乎无法识别该duration
属性,并且
animate: {fontSize:"22px", {duration:5000}}
将Uncaught SyntaxError: Unexpected token {
错误记录到console
。
虽然设置css:{transition: font-size 5s}
确实会返回预期结果
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
直接传递给方法。
问题:
如何将其他属性传递给animate
或接受多个对象属性作为参数的其他jQuery方法;例如,duration
还是第二个参数定义step
的.animate()
方法jQuery()
?
动画方法的默认持续时间为400毫秒。而且,如果您运行发布的第一个代码段,则会看到CSS在短时间内(0.4s)处于动画状态。
但是持续时间的特定值只能通过第二个参数传递,以在所有可用的jQuery方法签名中进行动画处理。
jQuery不支持将多个参数传递给在普通对象中指定为属性的函数,该函数作为第二个参数传递给jQuery()。
这可以从第2912行附近的jQuery v1.12.0来源的代码片段中看出:
// 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持续时间。
当然,可以选择将默认持续时间更改为所需的持续时间,并在$(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>
但是,您可以更好地链接动画方法:
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>
您还可以定义一个插件,该插件将为每个方法接受一个参数数组,而不仅仅是一个参数:
$.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>
如果我的答案开头引用的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>", {
text: "animated text",
animate: [{
fontSize:"100px",
}, {
duration: 5000,
done: function() {
$(this).text('Done');
}
}]
});
并且您将获得与解决方法3相同的结果。
但是请注意,当jQuery方法确实需要获取数组作为第一个参数时,它可能会产生不良影响。因此,此代码需要更多调整才能正确处理此类情况。
还要注意,如果要使用jQuery的修改版本,则每当要升级到较新的jQuery版本时,都需要重新应用该更改。
您可以在运行时替换$ .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>", {
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.init方法之外定义的一些私有变量。我在注释中用“路径”标记了修改原始代码的位置。
显然,$。fn.init并非像这样被否决。
最后,我觉得这种方法的缺点比解决方法3带来的优势更为重要。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句