Check it out here: http://jsfiddle.net/z7fjW/682/
This situation is really strange to me, I can't quite wrap my head around it. I did manage to come up with a workaround using delegated events, but I'm determined to keep digging until I uncover why the event is only triggering once.
$('body').on('click','#search-button',function() {
if(!searchAndHighlight($('#search-term').val())) {
alert("No results found");
}
});
UPDATE: Ah-ha!! Once I finally cracked the code, it all makes sense. Look at this snippet
$(selector).html($(selector).html()
.replace(searchTermRegEx, "<span class='highlighted'>"+searchTerm+"</span>"));
The selector
is targeting the body. By calling html()
on the entire body, you essentially replace the existing html with the same content plus the span
tags. The click listener was attached to the #search-button
, but gets overwritten because of the full html replacement. The tricky part for me was that the html appeared identical in the Chrome inspector, making it tough to realize the listener was no longer active.
This is why my workaround functioned, since event delegation attaches the listener to the body
, which then looks for #search-button
upon a click.
My suggestion is to avoid completely rewriting the body's html.. it just leads to headaches like this. Consider using this approach instead,
var selector = selector || "#bodyContainer";
This way, you only replace the content within #bodyContainer
, rather than the entire body html. This also allows you to keep your original event listener in place.
Helpful Resources: http://api.jquery.com/html/#html2
When .html() is used to set an element's content, any content that was in that element is completely replaced by the new content. Additionally, jQuery removes other constructs such as data and event handlers from child elements before replacing those elements with the new content.