简体   繁体   English

为什么我的jQuery搜索功能只能运行一次?

[英]Why does my jQuery search functionality only work once?

I have a piece of code which will search for then scroll to and highlight a piece of text 我有一段代码将进行搜索,然后滚动到并突出显示一段文本

jsFiddle: http://jsfiddle.net/z7fjW/137/ jsFiddle: http : //jsfiddle.net/z7fjW/137/

However, this piece of functionality will only work once, then no more searches can be performed. 但是,此功能只能使用一次,然后无法再执行搜索。 It doesn't seem to be removing the previously highlighted search sp perhaps something to do with this part? 它似乎并没有删除先前突出显示的搜索sp,也许与此部分有关?

$('.highlighted').removeClass('highlighted');     //Remove old search highlights
                $(selector).html($(selector).html()
                    .replace(searchTermRegEx, "<span class='highlighted'>"+searchTerm+"</span>"));

I'm not quite sure what's causing this so anybody help would be appreciated. 我不太确定是什么原因造成的,因此请大家提供帮助。

Thanks. 谢谢。

Here: http://jsfiddle.net/z7fjW/682/ 此处: http//jsfiddle.net/z7fjW/682/

This is super weird, i can't understand it. 这太奇怪了,我听不懂。 I found a workaround using delegated events, but will keep investigating until i find the reason the event only fires once. 我发现了使用委派事件的解决方法,但会一直进行调查,直到我找到事件仅触发一次的原因。

$('body').on('click','#search-button',function() {
        if(!searchAndHighlight($('#search-term').val())) {
            alert("No results found");
        }
    });

EDIT: ok!! 编辑:好的! Once i figured it out it becomes fairly obvious. 一旦我弄清楚,它就变得很明显。 With this code 有了这个代码

$(selector).html($(selector).html()
                    .replace(searchTermRegEx, "<span class='highlighted'>"+searchTerm+"</span>"));

The selector is set to body. selector设置为主体。 You then call html() on the entire body, only to reinsert the same html with the addition of the span . 然后,您在整个正文上调用html() ,只是在重新插入相同的html的同时添加了span The click listener was bound to the #search-button element. 点击监听器已绑定到#search-button元素。 Because you overwrote the entire html of the body, you also overwrote the click listener. 因为您覆盖了正文的整个html,所以您也覆盖了Click侦听器。 The tricky part for me was that the html looked exactly the same in the Chrome inspector, so it wasn't immediately obvious that the listener was unbound. 对我而言,最棘手的部分是html在Chrome检查器中看起来完全相同,因此并没有立即清楚侦听器未绑定。

This explains why my workaround worked, because with event delegation the listener is attached to the body , when it detects a click, only then does jquery look for #search-button . 这解释了为什么我的解决方法起作用的原因,因为有了事件委派,侦听器会附加到body ,当检测到单击时,jquery才查找#search-button

I would avoid rewriting the entire html of the body.. because it causes headaches like this. 我会避免重写身体的整个html。因为这样会引起头痛。 Try using this instead, 尝试改用这个

var selector = selector || "#bodyContainer";   

Now you only overwrite #bodyContainer , instead of the entire body html. 现在,您只覆盖#bodyContainer ,而不是整个html。 With this you can also use your original event listener. 这样,您还可以使用原始的事件侦听器。

Relevant Docs: http://api.jquery.com/html/#html2 相关文档: 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. 使用.html()设置元素的内容时,该元素中的所有内容都将被新内容完全替换。 Additionally, jQuery removes other constructs such as data and event handlers from child elements before replacing those elements with the new content. 此外,在用新内容替换那些元素之前,jQuery从子元素中删除了其他构造,例如数据和事件处理程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM