Bug Tracker

Opened 12 years ago

Closed 12 years ago

Last modified 12 years ago

#9011 closed feature (wontfix)

Allow $() to handle properly an array of jQuery objects as first argument

Reported by: xavierm02 Owned by: xavierm02
Priority: low Milestone: 1.next
Component: core Version: git
Keywords: Cc:
Blocked by: Blocking:

Description

Adding feature: $( [ $('<p></p>'), $('<span></span>') ] ); is now allowed and returns the same thing as $('<p></p>').add($('<span></span>'));. Although it was already possible, doing it with a large set of element implied a lot of calls to $().add.

Bug found here: http://stackoverflow.com/questions/5823776/jquery-append-doesnt-work-with-arrays-of-disconected-dom-nodes/5823999#5823999

Full jQuery file can be found here: https://gist.github.com/raw/947169/6a9711ead197e17a636d7c43b72dc8efd7a6baec/jQuery.js

Pull request: https://github.com/jquery/jquery/pull/359

Ticket that would be solved by implementing this: http://bugs.jquery.com/ticket/8897

Change History (15)

comment:1 Changed 12 years ago by xavierm02

Fiddle showing the bug: http://jsfiddle.net/xavierm02/dH2Fp/

comment:2 Changed 12 years ago by dmethvin

I know the example must be from something more complex, but I'll ask anyway. Why not just do $('<p></p><span></span>') since it is shorter and supported all the way back to jQuery 1.0? Is there some real-life code that shows how this would be useful?

comment:3 Changed 12 years ago by xavierm02

Well I don't really know I'm just the guy who helped on stackoverflow... And I don't often use jQuery so I can't really help...

Maybe this:

var elements = []; for ( var i = 0; i < 10; ++i ) {

elements.push( $('<li>' + i + '</li>') );

} $("ul").append(elements);

I'll think in case I find something looking useful :-°

comment:4 Changed 12 years ago by xavierm02

Fiddle showing the change makes it work: http://jsfiddle.net/xavierm02/mzmpC/

Last edited 12 years ago by xavierm02 (previous) (diff)

comment:5 Changed 12 years ago by domenic@…

(I'm the guy from StackOverflow.)

The use is:

var lis$ = $("selector").map(function () {
    return $("<li />");
});

So basically any time you use .map() and return a jQuery object.

lis$ currently contains a jQuery object that will fail whenever you try to do anything with it (e.g. append, as in ticket 8897), because it was created using $([$("<li />"), $("<li />"), ...])

comment:6 Changed 12 years ago by dmethvin

Owner: set to xavierm02
Status: newpending

@domenic, then why not do this, which works for all versions of jQuery?

var lis$ = $("selector").map(function () {
    return $("<li />")[0];
});

comment:7 Changed 12 years ago by Rick Waldron

Component: unfiledcore
Priority: undecidedlow

I'm with dmethvin on this, https://github.com/jquery/jquery/pull/359#issuecomment-1072291 best as a plugin, but drop it into the 1.7 feature request form anyway. Be sure to reference this ticket

comment:8 Changed 12 years ago by xavierm02

Status: pendingnew

@dmethvin: Well that works in this case because you've got only one element but if you've got 2 or more, it fails (or is harder to do).

comment:9 Changed 12 years ago by anonymous

@dmethvin, that works for single-element creation, yes, but if I did instead, say, return $("anotherSelectorThatCouldReturnZeroOrMoreElements") it will fail.

Besides, it seems very strange that jQuery wants me to work outside of its framework. I'm using its map function on a jQuery object, but that map function doesn't want my callback to work with jQuery objects, it wants it to work with native DOM element objects.

comment:10 Changed 12 years ago by ajpiano

If you create multiple top level elements, you can return yourjQueryobject.get() and return the whole array, which will be flattened by .map.

I think there is a lot of oppositions to land support for this. jQuery has a lot of signatures as it is, and the need to pass an array of jQuery objects is just not something that I've seen come up with any regularity over the last several years of looking at a lot of jQuery code.

Furthermore, there's the issue that creating elements in the .map() loop is not, itself, the most performant way to create many elements - it's wiser to create a string and concatenate and insert it all in one go, if possible.

Even furthermore, you could also do this "within" the jQuery framework by using the add method to push each of the newly created jQuery objects into the jQuery object you ultimately plan on appending.

So between the fact that we haven't seen much of a demand for this before, the added complexity it adds to the method signature, the fact that it perhaps encourages suboptimal practises, the performance implications for already existing signatures like arrayOfDomElements, and the fact that there are certainly ways to achieve this functionality already, I hope you understand where the reticence expressed here and on the pull request is coming from.

comment:11 Changed 12 years ago by xavierm02

The problem with add is that you should have to call it many times.

comment:12 Changed 12 years ago by dmethvin

Resolution: wontfix
Status: newclosed

@xavierm02, ajpiano described plenty of good options and we're hesitant to add anything to $() since it's heavily used.

comment:13 Changed 12 years ago by xavierm02

Then what about adding a method such as addSeveral or addArray that would allow to do that?

comment:14 Changed 12 years ago by dmethvin

#9379 is a duplicate of this ticket.

comment:15 Changed 12 years ago by Timmy Willison

#9647 is a duplicate of this ticket.

Note: See TracTickets for help on using tickets.