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 .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'));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With