11

是否可以在 Safari/Firefox/Chrome 中使用 Javascript 在特定 div 容器中搜索给定的文本字符串。我知道您可以使用它window.find(str)来搜索整个页面,但是否可以将搜索区域仅限于 div?

谢谢!

4

8 回答 8

7

一旦你查找了你的div(你可以通过document.getElementById或任何其他 DOM 函数,这里的各种规格),你可以使用textContentinnerText来查找div. 然后你可以用它indexOf来查找字符串。

或者,在较低级别,您可以使用递归函数搜索窗口中的所有文本节点,这听起来比实际复杂得多。基本上,从你的目标div(这是一个Element)开始,你可以遍历它childNodes并搜索它们的nodeValue字符串(如果它们是Texts)或递归到它们(如果它们是Elements)。

"foo"诀窍是在这个标记中找不到一个简单的版本:

<p><span>fo</span>o</p>

...因为两个Text节点都没有nodeValuewith "foo"(其中一个有"fo",另一个"o")。

于 2013-02-28T18:06:34.740 回答
2

根据您要执行的操作,有一种有趣的方法可以做到这一点(确实需要一些工作)。

首先,搜索从用户最后点击的位置开始。因此,要获得正确的上下文,您可以强制单击 div。这会将内部指针放在 div 的开头。

然后,您可以像往常一样使用 window.find 来查找元素。它将突出显示并移至找到的下一个项目。您可以创建自己的对话框并处理 find 返回的 true 或 false,以及检查位置。所以举个例子,你可以保存当前的滚动位置,如果下一个返回的结果在 div 之外,你就恢复滚动。此外,如果它返回 false,那么您可以说没有找到结果。

您还可以显示默认搜索框。在这种情况下,您可以指定起始位置,但不能指定结束位置,因为您失去了控制。

一些示例代码可帮助您入门。如果有足够的兴趣,我也可以尝试放置一个 jsfiddle。

句法:

window.find(aStringToFind, bCaseSensitive, bBackwards, bWrapAround, bWholeWord, bSearchInFrames, bShowDialog);

例如,要开始在 myDiv 中搜索,请尝试

document.getElementById("myDiv").click(); //Place cursor at the beginning
window.find("t", 0, 0, 0, 0, 0, 0); //Go to the next location, no wrap around

您可以设置一个模糊(失去焦点)事件处理程序,让您知道何时离开 div,以便停止搜索。

要保存当前滚动位置,请使用 document.body.scrollTop。如果它试图跳出 div,您可以将其设置回来。

希望这可以帮助!〜技术老兄

于 2014-09-04T03:25:07.183 回答
1

根据其他答案,您将无法为此使用该window.find功能。好消息是,您不必完全自己编写程序,因为现在有一个名为 rangy 的库在这方面有很大帮助。因此,由于代码本身有点太多,无法将粘贴复制到此答案中,因此我将仅参考可以在此处找到的 rangy 库的代码示例。查看代码你会发现

 searchScopeRange.selectNodeContents(document.body);

你可以用它代替

 searchScopeRange.selectNodeContents(document.getElementById("content"));

仅在内容 div 中专门搜索。

于 2014-08-28T17:19:21.363 回答
1

如果您仍在寻找某些东西,我想我找到了一个不错的解决方案;

这是:https ://www.aspforums.net/Threads/211834/How-to-search-text-on-web-page-similar-to-CTRL-F-using-jQuery/

我正在努力删除 jQuery (wip):codepen.io/eloiletagant/pen/MBgOPB 希望还不算太晚:)

于 2018-07-10T07:48:11.293 回答
0

这是我对 jquery 的处理方式:

var result = $('#elementid').text().indexOf('yourtext') > -1

它将返回 true 或 false

于 2014-09-04T05:30:09.097 回答
0
var elements = [];
$(document).find("*").filter(function () {
  if($(this).text().contains(yourText))
    elements.push($(this));
});
console.log(elements);

I didn't try it, but according the jQuery documentation it should work.

于 2014-09-03T06:19:58.343 回答
0

您可以使用Window.find()搜索页面中的所有匹配项并Node.contains()过滤掉不合适的搜索结果。
以下是如何查找和突出显示特定元素中所有出现的字符串的示例:

var searchText = "something"
var container = document.getElementById("specificContainer");
// selection object
var sel = window.getSelection()
sel.collapse(document.body, 0)
// array to store ranges found
var ranges = []
// find all occurrences in a page
while (window.find(searchText)) {
    // filter out search results outside of a specific element
    if (container.contains(sel.anchorNode)){
        ranges.push(sel.getRangeAt(sel.rangeCount - 1))
    }
}   
// remove selection
sel.collapseToEnd()

// Handle ranges outside of the while loop above.
// Otherwise Safari freezes for some reason (Chrome doesn't).
if (ranges.length == 0){
    alert("No results for '" + searchText + "'")
 } else {
    for (var i = 0; i < ranges.length; i++){
        var range = ranges[i]
        if (range.startContainer == range.endContainer){
            // Range includes just one node
            highlight(i, range)
        } else {
            // More complex case: range includes multiple nodes
            // Get all the text nodes in the range
            var textNodes = getTextNodesInRange(
                                range.commonAncestorContainer,
                                range.startContainer,
                                range.endContainer) 

            var startOffset = range.startOffset
            var endOffset = range.endOffset
            for (var j = 0; j < textNodes.length; j++){
                var node = textNodes[j]
                range.setStart(node, j==0? startOffset : 0)
                range.setEnd(node, j==textNodes.length-1? 
                                       endOffset : node.nodeValue.length)
                highlight(i, range)
            }
        }
    }
}

function highlight(index, range){
    var newNode = document.createElement("span")
    // TODO: define CSS class "highlight"
    // or use <code>newNode.style.backgroundColor = "yellow"</code> instead
    newNode.className = "highlight"
    range.surroundContents(newNode)
    // scroll to the first match found
    if (index == 0){
        newNode.scrollIntoView()
    }
}

function getTextNodesInRange(rootNode, firstNode, lastNode){
    var nodes = []
    var startNode = null, endNode = lastNode
    var walker = document.createTreeWalker(
            rootNode,
            // search for text nodes
            NodeFilter.SHOW_TEXT,
            // Logic to determine whether to accept, reject or skip node.
            // In this case, only accept nodes that are between
            // <code>firstNode</code> and <code>lastNode</code>
            {
                acceptNode: function(node) {
                    if (!startNode) {
                        if (firstNode == node){
                            startNode = node
                            return NodeFilter.FILTER_ACCEPT
                        }
                        return NodeFilter.FILTER_REJECT
                    }

                    if (endNode) {
                        if (lastNode == node){
                            endNode = null
                        }
                        return NodeFilter.FILTER_ACCEPT
                    }

                    return NodeFilter.FILTER_REJECT
                 }
            },
            false
        )

    while(walker.nextNode()){
        nodes.push(walker.currentNode);
    }
    return nodes;
}

对于Range对象,请参阅https://developer.mozilla.org/en-US/docs/Web/API/Range
有关TreeWalker对象,请参阅https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker

于 2019-09-24T12:41:15.043 回答
-2

也许你试图不使用 jquery ......但如果没有,你可以使用它$('div:contains(whatyouarelookingfor)'),唯一的问题是它可以返回也包含匹配的子 div 的父元素。

于 2013-02-28T18:47:08.747 回答