Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery find not working in top-level elements if not added to DOM

I'm loading some HTML with jQuery asynchronously:

$.get(path, {}, function (data) {
    var result = $(data);
    var resultSelector = result.find(selector);
});

result is a valid HTML that contains my selector (in my specific case, "#UsersAndRolesResults").

I can see that it contains when I simply type result into the console, it's there exactly with the same ID, no typos or anything.

However, result.find(selector) returns 0 elements.

In my specific example, this is result:

enter image description here

And:

enter image description here

Why?

UPDATE: I can query for other elements that are inside #UsersAndRolesResults with their ID tag and they are returned correctly. I also cannot query any other top-level elements in the result. I think there is an issue with querying top-level elements inside the result.

UPDATE 2: Just try $('<div id="target"></div>').find("#target") and you will get 0 results, where you should obviously get the div.

like image 218
Can Poyrazoğlu Avatar asked Jun 26 '16 03:06

Can Poyrazoğlu


Video Answer


2 Answers

No. This is not bug, this is behavior defined in jQuery.

find() is used to select the elements which are inside the element on which find is called. In your case, the element is not children of the selector, so find will not work.

Example:

<div id="container">
    <div class="message">Hello World!</div>
    <div>Bye World</div>
</div>

JavaScript:

$('#container').find('.message');

This will select the element having class message and which is inside the element having ID container.

But, if you use find, it'll return nothing i.e. empty array since there is no element #container inside #container.

$('#container').find('#container');

Your code is equivalent to this ^^^.


If you want, you can use filter. filter will go through each element and check if this matches the selector, if it then the element is added to the result set.

$('#container').filter('#container');

This'll give you complete element.

like image 173
Tushar Avatar answered Sep 19 '22 02:09

Tushar


It seems to be a design decision with jQuery. Top-level elements in an AJAX result are not queried correctly with find. Interesting.

I've solved my problem with a workaround by creating a dummy div element, encapsulating my result inside that element, and then querying that dummy element. It worked:

var t = $("<div>")
t.append(result);
t.find("#UsersAndRolesResults"); //this one returned my object correctly

For a simple example, try:

$('<div id="target"></div>').find("#target");

You will get 0 results.

Try:

$('<div><div id="target"></div></div>').find("#target")

And you'll get the correct result.

like image 31
Can Poyrazoğlu Avatar answered Sep 22 '22 02:09

Can Poyrazoğlu