Skip to main content

Bug Tracker

Side navigation

#9011 closed feature (wontfix)

Opened April 28, 2011 09:16PM UTC

Closed April 29, 2011 03:05PM UTC

Last modified March 14, 2012 05:31AM UTC

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

Attachments (0)
Change History (15)

Changed April 28, 2011 09:28PM UTC by xavierm02 comment:1

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

Changed April 28, 2011 09:33PM UTC by dmethvin comment:2

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?

Changed April 28, 2011 09:42PM UTC by xavierm02 comment:3

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 :-°

Changed April 28, 2011 09:49PM UTC by xavierm02 comment:4

_comment0: Fiddle showing the change makes it work: http://jsfiddle.net/xavierm02/mzmpC/1304027407901327
_comment1: Fiddle showing the change makes it work: http://jsfiddle.net/xavierm02/mzmpC/11304027455931047

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

Changed April 28, 2011 09:56PM UTC by [email protected] comment:5

(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 />"), ...])

Changed April 29, 2011 12:42AM UTC by dmethvin comment:6

owner: → xavierm02
status: newpending

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

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

Changed April 29, 2011 01:53AM UTC by rwaldron comment:7

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

Changed April 29, 2011 07:23AM UTC by xavierm02 comment:8

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).

Changed April 29, 2011 02:24PM UTC by anonymous comment:9

@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.

Changed April 29, 2011 02:42PM UTC by ajpiano comment:10

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.

Changed April 29, 2011 02:47PM UTC by xavierm02 comment:11

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

Changed April 29, 2011 03:05PM UTC by dmethvin comment:12

resolution: → wontfix
status: newclosed

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

Changed April 29, 2011 03:12PM UTC by xavierm02 comment:13

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

Changed May 22, 2011 04:18AM UTC by dmethvin comment:14

#9379 is a duplicate of this ticket.

Changed June 22, 2011 07:44PM UTC by timmywil comment:15

#9647 is a duplicate of this ticket.