繁体   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