簡體   English   中英

為什么文檔返回不同的文檔?

[英]Why is document returning a different document?

我正在制作一個網頁閱讀器,它需要在開始閱讀時清點文檔中的文本節點,因為它會讀取頁面上的每個句子。 所以我正在“抓取”您可以說的文本節點。

我有一個使用document.createTreeWalker來清點文本節點的過程。

我還沒有弄清楚模式(我認為有一個),但有一次當我使用document.body ,指向的文檔不是主頁,而是 iframe 的文檔。 在我當前的調試中,這恰好是一個 twitter 小部件,但我想它可以是任何東西。 這不是 twitter 問題,但如果您碰巧知道 twitter 正在做一些非常普通的事情,以使文檔始終轉到它而不是頂部文檔,那么您可以讓它通知您的答案。 無論如何,無論來源如何,我都需要得到正確的文件。

你問我,正確的文件是什么意思? 我會說托管所選文本的文檔,或者如果未選擇任何文本,則為頂級文檔。

但我真正的問題是這是怎么發生的,為什么會這樣? 我上一次搞亂 dom 是在 2009 年,當時我在 IE 中編寫了一個網頁閱讀器。 時代變了; 我正在編寫一個 Chrome 擴展程序,現在網頁似乎復雜了 1000 倍。 老實說,它就像普通網頁上的馬戲團,大部分你看不到; 它被埋在下面並潛伏着絆倒任何像我的讀者一樣的機器人。

我不想為 twitter 或任何其他小部件制定硬編碼規則。 一定有一千個這樣的東西最終會添加/注入到頁面中。 我真的無法進入自定義規則的業務。

  this.LoadAllTextNodes = function () {
    this.AllTextNodes = textNodesUnder(document.body); // at some point, this document starts referring to something other than the top document. How did the definition of "document" change?
  }

  function textNodesUnder(root) {
    var textNodes = [];
    if (root.nodeType == 3)
      textNodes.push(root);
    else {
      var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, getTextElements, false);
      var node;
      while (node = treeWalker.nextNode())
        textNodes.push(node);
    }
    return textNodes; // Array
  }

  function getTextElements(node) {
    if (['SCRIPT', 'STYLE'].indexOf(node.parentNode.tagName) !== 0 && node.nodeValue !== '') //filter out script elements and empty elements 
      return NodeFilter.FILTER_ACCEPT
    else
      return NodeFilter.FILTER_SKIP
  }

我正在測試的網頁恰好是https://code.visualstudio.com/blogs/2016/02/23/introducing-chrome-debugger-for-vs-code 該頁面的主題事項涉及 Chrome 調試這一事實只是一個巧合。 它與問題無關。 我只是在您想查看頁面來源的情況下添加它。

調試器顯示錯誤的文檔被引用

<iframe id="twitter-widget-0" scrolling="no" frameborder="0" allowtransparency="true" class="twitter-follow-button twitter-follow-button-rendered" title="Twitter Follow Button" src="https://platform.twitter.com/widgets/follow_button.d59f1863bc12f58215682d9908af95aa.en.html#dnt=false&amp;id=twitter-widget-0&amp;lang=en&amp;screen_name=code&amp;show_count=true&amp;show_screen_name=true&amp;size=m&amp;time=1474137195557" style="position: static; visibility: visible; width: 191px; height: 20px;" data-screen-name="code"></iframe>

在 chrome 擴展中,內容腳本為每個窗口運行,包括頂部窗口和所有 iframe。 通過這種方式,Chrome 擴展訪問勝過在腳本標簽中運行的腳本可能具有的跨站點限制。

這是為每個框架實例化一個上下文,它將我在該框架中運行的擴展代碼的重復指向它們各自的文檔,而不是頂部窗口的文檔。

它並行運行代碼。 在我的情況下,每一幀都在在我不知道的情況下排隊要閱讀的內容,以便單例window.speechSynthesis閱讀。

修復很簡單; 只是不要在非頂級窗口中運行:

if (window != window.top) return; // don't run in frames

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM