【问题标题】:Search within the text of an HTML Element在 HTML 元素的文本中搜索
【发布时间】:2016-02-20 14:09:33
【问题描述】:

我想使用 C# (winforms) 中的 webBrowser 控件 API 或使用注入的 java 脚本来搜索特定网页元素中的单词。

我使用了以下java脚本并将其注入到加载的网页中:

var TRange=null;

function findString (str) {

 var strFound;

  // EXPLORER-SPECIFIC CODE

  if (TRange!=null) {
   TRange.collapse(false);
   strFound=TRange.findText(str);
   if (strFound) TRange.select();
  }
  else if (TRange==null || strFound==0) {
   TRange=self.document.body.createTextRange();
   strFound=TRange.findText(str);
   if (strFound) TRange.select();
  }

 if (!strFound) alert ("String '"+str+"' not found!")
 return;
}

此代码适用于整个页面,但我想在特定元素的内部文本中进行搜索。如何将我的搜索限制在这样的元素上?

【问题讨论】:

  • 元素是什么,你有元素的id、名称或其他属性吗?
  • 您如何指定“特定元素”?我的意思是,如果你可以引用一个特定的元素,你可以简单地得到它的 innerText 而没有 TextRange 对象。请注意,在您使用的旧模型中,只能在 bodybuttontextareainput type="text" 上创建文本范围。然后您可以使用TextRange 对象的一些方法来移动范围,也可以移动到特定元素。
  • @Teemu 它是一个部门,我想我必须使用 moveToElementText
  • @Ahmad 是的,你应该 :)

标签: javascript c# .net winforms webbrowser-control


【解决方案1】:

以下在第一次调用中使用moveToElementText 的java 脚本(当TRange 为空时)有效

var TRange=null;

function findString (str) {

 var strFound;

  // EXPLORER-SPECIFIC CODE

  if (TRange!=null) {
   TRange.collapse(false);
   strFound=TRange.findText(str);
   if (strFound) TRange.select();
  }
  else if (TRange==null || strFound==0) {
   TRange=self.document.body.createTextRange();
   var elem = document.getElementById('my_elem');
   // go to the element text
   TRange.moveToElementText(elem);
   strFound=TRange.findText(str);
   if (strFound) TRange.select();
  }

 if (!strFound) alert ("String '"+str+"' not found!")
 return;
}

【讨论】:

    【解决方案2】:

    您需要:

    1. 添加对Microsoft.mshtml.dll的引用
    2. 然后使用webBrowser1.Document.Body.DomElement从正文中获取IHTMLBodyElement
    3. 然后找到您的标签并从您的标签中获取IHTMLElement
    4. 然后使用createTextRange从正文中获取IHtmlTextRange
    5. 然后使用moveToElementText 将搜索限制为您的标签
    6. 然后使用findText从范围内查找字符串
    7. 那么如果找到字符串,你可以select它。

    示例

    这是一个工作示例,我们在 "div2" 中找到 "some" 文本,而我们有 2 个 div 元素,div1div2,它们都包含 "some" 文本。

    表格

    创建一个Form 并在Form1 上放置一个WebBrowser 控件并编写以下代码:

    public Form1()
    {
        InitializeComponent();
        this.Load += Form1_Load;
        this.webBrowser1.DocumentCompleted += webBrowser1_DocumentCompleted;
    }
    
    private void Form1_Load(object sender, EventArgs e)
    {
        this.webBrowser1.Navigate(@"D:\file.html");
    }
    
    private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        var searchText="some";
        var body = webBrowser1.Document.Body.DomElement as IHTMLBodyElement;
        var tag= webBrowser1.Document.GetElementById("div2").DomElement as IHTMLElement;
    
        var range = body.createTextRange();
        range.moveToElementText(tag);
        if (range.findText(searchText, searchText.Length, 0))
            range.select();
        else
            MessageBox.Show(string.Format("String '{0}' not found.", searchText));
    }
    

    HTML 内容示例

    这里是file.html的内容供测试:

    <html>
    <head><title>Select content</title></head>
    <body>
        <div id="div1">Here is some content</div>
        <div id="div2">Here is some other content</div>
    </body>
    </html>
    

    截图

    这是截图:

    注意

    • 您可能需要在代码中添加一些空值检查。
    • 您可以使用其他属性查找元素,例如使用 name 属性:
    • 关于javascript解决方案,你可以看看Ahmad answer here
    var tag = this.webBrowser1.Document.Body.All.GetElementsByName("somename")
                  .Cast<HtmlElement>()
                  .FirstOrDefault().DomElement as IHTMLElement;
    

    【讨论】:

    • 非常感谢,我在回答这个问题时也使用了moveToElementText。现在,我已经修改了我的 java 脚本函数。我记得我在使用mshtml API 时在某些情况下突出显示所选文本时遇到了一些问题,然后我切换到这个脚本,它仍处于测试阶段
    • @Ahmad 感谢您的反馈。您的回答完全没问题,对于谁知道如何在文档 +1 中将此脚本注入您的问题和回答的人来说,这是一个很好的脚本答案:)
    【解决方案3】:

    我假设您知道如何获取元素的 DOM 引用。之后,您可以使用 JQuery 过滤 Element 中的文本节点,例如:

      $($element.contents()).filter(function(){
        return this.nodeType === 3; // filter textnodes only
    
      }).each(function(){
    
        findString(this.textContent);
      });
    

    【讨论】:

    • 或普通:document.getElementById('header').childNodes.filter(function(node){return node.nodeType===3 }).forEach(function(node){findString(node .textContent);}) - 您需要将 childNodes 转换为数组
    猜你喜欢
    • 2015-03-17
    • 2014-04-25
    • 2022-08-02
    • 1970-01-01
    • 1970-01-01
    • 2015-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多