5

我想使用 jQuery 选择并返回搜索到的文本。

问题是; 部分文本可能位于或其他内联元素中,因此在此文本中<span>搜索时: ,您不会得到任何匹配项,而文本对人们来说是不间断的。'waffles are tasty''I'm not sure about <i>cabbages</i>, but <b>waffles</b> <span>are</span> <i>tasty</i>, indeed.'

让我们以这个 HTML 为例:

<div id="parent">
  <span style="font-size: 1.2em">
    I
  </span>
  like turtles 
  <span>
    quite a
  </span>
  lot, actually.

  <span>
    there's loads of
  </span>
  tortoises over there, OMG

  <div id="child">
    <span style="font-size: 1.2em">
      I
    </span>
    like turtles 
    <span>
      quite a
    </span>
    lot, actually.

    TURTLES!
  </div>
</div>

使用这个(或类似的)JavaScript:

$('div#parent').selectText({query: ['i like', 'turtles', 'loads of tortoises'], caseinsensitive: true}).each(function () {
  $(this).css('background-color', '#ffff00');
});
//The (hypothetical) SelectText function would return an array of wrapped elements to chain .each(); on them

你会想要产生这个输出:(显然没有评论)

<div id="parent">
  <span style="font-size: 1.2em">
    <span class="selected" style="background-color: #ffff00">
      I
    </span> <!--Wrap in 2 separate selection spans so the original hierarchy is disturbed less (as opposed to wrapping 'I' and 'like' in a single selection span)-->
  </span>
  <span class="selected" style="background-color: #ffff00">
    like
  </span>
  <span class="selected" style="background-color: #ffff00"> <!--Simple match, because the search query is just the word 'turtles'-->
    turtles
  </span> 
  <span>
    quite a
  </span>
  lot, actually.

  <span>
    there's
    <span class="selected" style="background-color: #ffff00">
      loads of
    </span> <!--Selection span needs to be closed here because of HTML tag order-->
  </span>
  <span class="selected" style="background-color: #ffff00"> <!--Capture the rest of the found text with a second selection span-->
    tortoises
  </span>
  over there, OMG

  <div id="child"> <!--This element's children are not searched because it's not a span-->
    <span style="font-size: 1.2em">
      I
    </span>
    like turtles 
    <span>
      quite a
    </span>
    lot, actually.

    TURTLES!
  </div>
</div>

(假设的)SelectText函数会将所有选定的文本包装在<span class="selected">标签中,无论搜索的部分是否位于其他内联元素(如<span>、'' 等)中。它不会搜索 child<div>的内容,因为那不是内联元素。

有没有一个 jQuery 插件可以做这样的事情?(将搜索查询包装在 span 标签中并返回它们,不知道找到的文本的某些部分是否可能位于其他内联元素中?)

如果没有,如何创建这样的功能?这个函数有点像我正在寻找的东西,但是当找到的文本的一部分嵌套在其他内联元素中时,它不会返回所选范围和中断的数组。

任何帮助将不胜感激!

4

5 回答 5

4

小菜一碟!看到这个

折叠符号:

$.each(
    $(...).findText(...), 
    function (){
        ...
    }
);

内嵌符号:

$(...).findText(...).each(function (){
        ...
    }
);
于 2013-11-02T02:39:56.450 回答
3

三个选项:

这个答案更详细地介绍了前两个选项:

https://stackoverflow.com/a/5887719/96100

于 2013-10-31T22:05:19.190 回答
1

因为我现在正好在做类似的事情,如果你想看看我对“选项 3”的解释的开始,我想我会分享这个,主要特点是所有文本遍历节点,而不更改现有标签。尚未在任何不寻常的浏览器上进行测试,因此此浏览器不提供任何保证!

function DOMComb2 (oParent) {
    if (oParent.hasChildNodes()) {
        for (var oNode = oParent.firstChild; oNode; oNode = oNode.nextSibling) {
            if (oNode.nodeType==3 && oNode.nodeValue) { // Add regexp to search the text here
                var highlight = document.createElement('span');
                highlight.appendChild(oNode.cloneNode(true));
                highlight.className = 'selected';
                oParent.replaceChild(highlight, oNode);

                // Or, the shorter, uglier jQuery hybrid one-liner
                // oParent.replaceChild($('<span class="selected">' + oNode.nodeValue + '</span>')[0], oNode);
            }
            if (oNode.tagName != 'DIV') { // Add any other element you want to avoid
                DOMComb2(oNode);
            }
        }
    }
}

然后用 jQuery 有选择地搜索东西:

$('aside').each(function(){
    DOMComb2($(this)[0]);
});

当然,如果你的旁白中有旁白,那么奇怪的事情可能会发生。

(DOMComb 函数改编自 Mozilla 开发参考站点 https://developer.mozilla.org/en-US/docs/Web/API/Node

于 2013-11-01T00:31:45.933 回答
0

我写了一个草稿作为小提琴。主要步骤:

我为 jQuery 制作了一个插件

$.fn.selectText = function(params){
    var phrases = params.query, 
        ignorance = params.ignorecase;
        wrapper = $(this);
    . . .
    return(wrapper);
};

现在我可以将选择称为$(...).selectText({query:["tortoise"], ignorance: true, style: 'selection'});

我知道你想在函数调用之后有迭代器,但在你的情况下这是不可能的,因为迭代器必须返回有效的 jQuery 选择器。例如: word <tag>word word</tag> word不是有效的选择器。

在清理包装器的内容后,为每个搜索makeRegexp()制作个人正则表达式。

每个搜索到的 html 源代码都转到emulateSelection()然后wrapWords()

主要思想是包裹在<span class="selection">...</span>每一个不被标签分隔的短语中,而不是分析整个节点树。

笔记:

<b><i>...不适用于 html 中的标签。您必须对其进行正则表达式字符串的更正。我不保证它可以与 unicode 一起使用。但谁知道...

于 2013-10-31T23:02:35.007 回答
0

据我了解,我们谈论的是迭代器,例如$.each($(...).searchText("..."),function (str){...});.

查看大卫赫伯特劳伦斯的诗:

<div class="poem"><p class="part">I never saw a wild thing<br /> 
sorry for itself.<br /> 
A small bird will drop frozen dead from a bough<br />
without ever having felt sorry for itself.<br /></p></div>

实际上,渲染后浏览器会这样理解:

<div class="poem">
<p class="part">
<br>I never saw a wild thing</br> 
<br>sorry for itself.</br> 
<br>A small bird will drop frozen dead from a bough</br>
<br>without ever having felt sorry for itself.</br> 
</p>
</div>

例如,我在寻找短语:"wild thing sorry for". 因此,我必须强调摘录:

wild thing</br><br>sorry for

我不能像这样包装它<span>wild thing</br><br>sorry for</span>,然后通过一些临时 id="search-xxxxxx" 创建 jQuery 选择器,然后将其返回 - 这是错误的 html。我可以像这样包装每段文字:

<span search="search-xxxxx">wild thing</span></br><br><span search="search-xxxxx">sorry for</span>

然后我必须调用一些函数并返回 jQuery 选择器数组:

return($("[search=search-xxxxx]"));

现在我们有两个“结果”:a)“野物”;b) “对不起”。真的是你想要的吗?

或者

您必须编写自己的each()函数,就像另一个 jQuery 插件一样:

$.fn.eachSearch = function(arr, func){
    ...
};

其中 arr 将不是选择器数组,而是选择器数组的数组,例如:

arr = [
    {selector as whole search},
    {[{selector as first part of search]}, {[selector as second part of search]}},
    ...    
]
于 2013-11-01T18:40:21.040 回答