Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find an element in a jQuery object built from a string of HTML

Tags:

jquery

dom

I would like to be able to build a jQuery object from a string of HTML and to search inside directly.

Example:

htmlString = '<h3>Foo</h3><div class="groups"></div>'
$html      = $(htmlString)
$groups    = $html.find('.groups') // Returns []. WTF?

I would expect that find actually finds the div element.

If you want to know more about the context of my question, I develop a Backbone app and to render certain Views I have things like that:

render: ->
  $html   = $(@template(vehicle: @vehicle))
  $groups = $()

  _(@groups).each (group)=>
    subview = new App.Views.AttributesGroup(group: group, vehicle: @vehicle)
    $groups = $groups.add(subview.render().el)

  $(@el).html($html)
  $(@el).find('.groups').replaceWith($groups)
  @

I'm looking for a more elegant way to achieve the same result.

Thanks!


Thanks Matt, it is very clear. I feel stupid for not having thought of this subtlety about descendent and siblings.

So I refactored my code:

render: ->
  $html   = $(@template(vehicle: @vehicle))
  $groups = $html.filter('.groups')

  _(@groups).each (group)=>
    subview = new App.Views.AttributesGroup(group: group, vehicle: @vehicle)
    $groups.append(subview.render().el)

  $(@el).html($html)
  @

Now there is only one DOM insertion and the code looks clearer to me.

like image 662
Romain Tribes Avatar asked May 03 '12 10:05

Romain Tribes


1 Answers

This is because find() searches the descendants of the elements in the jQuery object, but the .groups element is an element in the jQuery object so won't be matched.

Instead, you need to use filter() to search the current elements.

htmlString = '<h3>Foo</h3><div class="groups"></div>'
$html      = $(htmlString)
$groups    = $html.filter('.groups');

However if you then had the htmlString of <h3><span class="bar">Foo</span></h3><div class="groups"></div>, you wouldn't find .bar; this would be a find() call.

So you'll need to check for both;

htmlString = '<h3>Foo</h3><div class="groups"></div>'
$html      = $(htmlString)
$groups    = $html.find('.groups').add($html.filter('.groups'));   
like image 67
Matt Avatar answered Nov 15 '22 07:11

Matt