要点:如果传递第二个参数,则第一个参数中的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>
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>
解决方法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更重要.