Good catch - and thanks for the patch! I just landed the improvement:
http://dev.jquery.com/ticket/4884
I made one minor tweak to the patch: In the case where .attr("name",
function(){}) occurs the jQuery.isFunction(value) check is cached (rather
than occurring at every iteration in the array).
Thanks again!
--John
On Fri, Jul 10, 2009 at 7:17 PM, David Flanagan <[email protected]>wrote:
> The 1.3.3pre version of the attr() method doesn't handle object
> arguments where property values are functions in the same way that 1.3.2
> does (and the way that the docs say it should). I think because in the
> code reorganization the jQuery.prop() helper function went away. I
> believe that a very similar bug exists in the css() method, but I
> haven't looked closely enough at it.
>
> I can't figure out how to submit a bug report against 1.3.3pre, so I'm
> posting this here. Let me know if I should file it as a bug against
> some other version on the tracker.
>
> I've attached a patch to src/attributes.js and also to
> tests/unit/attributes.js
>
> In my patch I also try to optimze the (I assume common) case where
> attr() is called with two arguments. It no longer creates and then
> iterates over a new object in this case. But it does make the code
> slightly longer.
>
> David Flanagan
>
> >
>
> Index: test/unit/attributes.js
> ===================================================================
> --- test/unit/attributes.js (revision 6415)
> +++ test/unit/attributes.js (working copy)
> @@ -68,12 +68,15 @@
> });
>
> test("attr(Hash)", function() {
> - expect(1);
> + expect(3);
> var pass = true;
> jQuery("div").attr({foo: 'baz', zoo: 'ping'}).each(function(){
> if ( this.getAttribute('foo') != "baz" &&
> this.getAttribute('zoo') != "ping" ) pass = false;
> });
> ok( pass, "Set Multiple Attributes" );
> + equals( jQuery('#text1').attr({'value': function() { return
> this.id; }})[0].value, "text1", "Set attribute to computed value #1" );
> + equals( jQuery('#text1').attr({'title': function(i) { return i;
> }}).attr('title'), "0", "Set attribute to computed value #2");
> +
> });
>
> test("attr(String, Object)", function() {
> @@ -334,9 +337,9 @@
> e.toggleClass(false);
> e.toggleClass();
> ok( e.is(".testD.testE"), "Assert class present (restored from
> data)" );
> -
> -
>
> +
> +
> // Cleanup
> e.removeClass("testD");
> e.removeData('__className__');
> Index: src/attributes.js
> ===================================================================
> --- src/attributes.js (revision 6415)
> +++ src/attributes.js (working copy)
> @@ -1,34 +1,30 @@
> jQuery.fn.extend({
> attr: function( name, value ) {
> - var options = name, isFunction = jQuery.isFunction( value
> );
> + var elem, options;
>
> - if ( typeof name === "string" ) {
> - // Are we setting the attribute?
> - if ( value === undefined ) {
> + if ( typeof name === "string" ) { // A single attribute
> + if ( value === undefined ) { // Query it on
> first element
> return this.length ?
> jQuery.attr( this[0], name ) :
> null;
> -
> - // Convert name, value params to options hash
> format
> - } else {
> - options = {};
> - options[ name ] = value;
> + } else { // Set it on
> all elements
> + for ( var i = 0, l = this.length; i < l;
> i++ ) {
> + elem = this[i];
> + if ( jQuery.isFunction(value) )
> + value = value.call(elem,i);
> + jQuery.attr( elem, name, value );
> + }
> }
> - }
> -
> - // For each element...
> - for ( var i = 0, l = this.length; i < l; i++ ) {
> - var elem = this[i];
> -
> - // Set all the attributes
> - for ( var prop in options ) {
> - value = options[prop];
> -
> - if ( isFunction ) {
> - value = value.call( elem, i );
> + } else { // Multiple
> attributes to set on all
> + options = name;
> + for ( var i = 0, l = this.length; i < l; i++ ) {
> + elem = this[i];
> + for ( name in options ) {
> + value = options[name];
> + if ( jQuery.isFunction(value) )
> + value = value.call(elem,i);
> + jQuery.attr( elem, name, value );
> }
> -
> - jQuery.attr( elem, prop, value );
> }
> }
>
> @@ -258,4 +254,4 @@
> // Using attr for specific style information is now
> deprecated. Use style insead.
> return jQuery.style(elem, name, value);
> }
> -});
> \ No newline at end of file
> +});
>
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"jQuery Development" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/jquery-dev?hl=en
-~----------~----~----~----~------~----~------~--~---