bragboy bragboy - 4 months ago 15
jQuery Question

jQuery: Inconsistent behavior of find between div and tbody

I am using the

find
selector in jQuery by Id. It is behaving differently in case of a
div
vs
tbody
. This is a bigger problem - for the sake of clarity here is the reduced version of my original issue

HTML

<div id='iamdiv'>HELLO</div>
<table>
<tbody id='iamtbody'>
<tr><td>HELLO TOO</td></tr>
</tbody>
</table>
<input type='text' id='div'/>
<input type='text' id='tbody'/>


JS

$(document).ready(function() {
var allcontent = $($('body').html()); // I am deliberately doing this to input a HTML String.
var $divcontent = allcontent.find('#iamdiv');
$('#div').val($divcontent.html());
var $tbodycontent = allcontent.find('#iamtbody');
$('#tbody').val($tbodycontent.html());
});


Fiddle: https://jsfiddle.net/bragboy/Lt8nua10/1/

My objective here is to display the raw html in the input text boxes, however only the tbody one is getting displayed and not the div. If I use a
filter
method instead of
find
- it works for div but not the tbody.

My objective is to have one consistent way of fetching for both tbody and div.

Answer

Two issues:

  1. find looks for descendant elements, but #iamdiv is a top-level entry in your allcontents jQuery object.

  2. You're duplicating the elements in the

    var allcontent = $($('body').html());
    

    line, which I'm fairly sure isn't what you want to do. (You've said that's on purpose, to simulate parsing HTML from elsewhere.)

You've said your goal is to use find in both use case (rather than using filter in one and find in the other). To do that, you need to have something else as the root of your allcontent.

You've also said that for some reason you can't change the

var allcontent = $($('body').html());

line, even just to

var allcontent = $("<body>").append($('body').html());

That's okay, you can still add a new root element by adding a line after it, like this:

allcontent = $("<body>").append(allcontent);

Live example:

$(document).ready(function() {
  var allcontent = $($("body").html()); // You've said we can't change this
  // The added line:
  allcontent = $("<body>").append(allcontent);
  var $divcontent = allcontent.find('#iamdiv');
  $('#div').val($divcontent.html());
  var $tbodycontent = allcontent.find('#iamtbody');
  $('#tbody').val($tbodycontent.html());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id='iamdiv'>HELLO</div>
<table>
  <tbody id='iamtbody'>
    <tr><td>HELLO TOO</td></tr>
  </tbody>
</table>
<input type='text' id='div'/>
<input type='text' id='tbody'/>

Comments