![](/img/trans.png)
[英]Why is document.body.scrollHeight returning different number?
[英]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&id=twitter-widget-0&lang=en&screen_name=code&show_count=true&show_screen_name=true&size=m&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.