jQuery: The Write Less, Do More JavaScript Library

how to add elements to a jQuery object without copying it

View: New views
5 Messages — Rating Filter:   Alert me  

how to add elements to a jQuery object without copying it

by ~flow :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


i seem to remember i asked this question before, but am unable to
retrieve that post---given a jQuery object with a collection of DOM
nodes, how can i append another DOM node (like `[].push()` would do)
to that collection without breaking object identity? i need

  var t = $( '.foo' );
  var s = t;
  t.push( '.bar' ); // should now like like $( '.foo,.bar' )
  assert( s === t, 'object identity broken' )

any ideas what to write for `$().push`?

cheers & ~flow

Re: how to add elements to a jQuery object without copying it

by ricardobeat :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


a jQuery object is not a real array. The add() function does what you
want:

var foobar = $('.foo').add('.bar');

If you want to add elements manually use:

var $foo = $('.foo');
$foo[ ++$foo.length ] = $('.bar')[0];

- ricardo

On Sep 23, 4:35 pm, "~flow" <wolfgang.l...@...> wrote:

> i seem to remember i asked this question before, but am unable to
> retrieve that post---given a jQuery object with a collection of DOM
> nodes, how can i append another DOM node (like `[].push()` would do)
> to that collection without breaking object identity? i need
>
>   var t = $( '.foo' );
>   var s = t;
>   t.push( '.bar' ); // should now like like $( '.foo,.bar' )
>   assert( s === t, 'object identity broken' )
>
> any ideas what to write for `$().push`?
>
> cheers & ~flow

Re: how to add elements to a jQuery object without copying it

by ~flow :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


thanx a lot, i think i’ve got it.

actually, the first part of your answer does not work for me---with
`add`, a new collection is returned. this breaks object identity
(hence, you cannot keep a reference from another variable to the
jQuery object in question once you've done `add`).

the second suggestion does work; however, the pre-incrementing index
has to be written as a post-incrementing index, like this:

  var t = $( '.foo' );
  var s = t;
  t[ t.length++ ] = $Q( '.bar' )[ 0 ]; // should now like like $
( '.foo,.bar' )
  assert( s === t, 'object identity broken' )

because we need exactly `t.length` as the target index, as indices
start at 0. (jQuery, unlike the standard Array object, would not
appear to accept assignments to unassigned indices greater than the
length of the object; if done, the result is an `undefined`  value
augmented to the jQuery object, but the assignment’s right hand side
gets lost.)

thanx again!

cheers & ~flow


Re: how to add elements to a jQuery object without copying it

by ~flow :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


oops, little typo---got to use `$Q` instead of `$` in my project.
wrote an extension method:

jQuery.fn.push = function( selector_or_nodes ) {
  //  Given a selector or a jQuery object, append all of the nodes to
the current jQuery object.
  var nodes = $is_string( selector_or_nodes )?
$Q( selector_or_nodes ) : selector_or_nodes;
  var node_count = nodes.length;
  for( var i = 0; i < node_count; i++ ) {
    this[ this.length++ ] = nodes[ i ] }; };

so if that should work, you can now say

  t.push( $( '.bar' ) );

and, in fact

  t.push( '.bar' );

while keeping the jQuery object identical.

Re: how to add elements to a jQuery object without copying it

by Michael Geary-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


> From: ~flow
>
> the second suggestion does work; however, the
> pre-incrementing index has to be written as a
> post-incrementing index, like this:
>
>   var t = $( '.foo' );
>   var s = t;
>   t[ t.length++ ] = $Q( '.bar' )[ 0 ]; // should now like
> like $ ( '.foo,.bar' )
>   assert( s === t, 'object identity broken' )
>
> because we need exactly `t.length` as the target index, as
> indices start at 0. (jQuery, unlike the standard Array
> object, would not appear to accept assignments to unassigned
> indices greater than the length of the object; if done, the
> result is an `undefined`  value augmented to the jQuery
> object, but the assignment's right hand side gets lost.)

That can't possibly be right (the part in parentheses). I think you're
misunderstanding a fundamental bit of JavaScript.

I didn't see what code you tried that failed, but if you still have it and
want to understand the *real* reason it failed, post it and I'll explain it.

If it's the code from Ricardo's message:

$foo[ ++$foo.length ] = $('.bar')[0];

then you're right, that needs to use a postincrement. But the reason it
doesn't work as expected is simply that it assigns into an array element
index one greater than it should.

-Mike