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.
This is because
find()searches the descendants of the elements in the jQuery object, but the.groupselement is an element in the jQuery object so won’t be matched.Instead, you need to use
filter()to search the current elements.However if you then had the
htmlStringof<h3><span class="bar">Foo</span></h3><div class="groups"></div>, you wouldn’t find.bar; this would be afind()call.So you’ll need to check for both;