【问题标题】:Does Javascript have internal knowledge of the raw source code of a given document?Javascript 是否对给定文档的原始源代码有内部知识?
【发布时间】:2011-01-05 10:54:26
【问题描述】:
<html>
 <head>
   <script>
     remove_line(11);
     // This should remove the line 11 from source code, 
     // eliminating the unordered list element.
   </script>
 </head>
 <body>
   <p>Some text</p>
   <ul><li>Some list item</li></ul>
   <a>Some link</a>
 </body>
</html>

完全知道这段代码会伤害你的眼睛。但是,由于非常非典型的技术原因(主要是性能),这将是解决我的问题的最有效方法。这很可能是不可行的,但它确实可以为我节省很多编码和性能问题。

如果不可行(如预期的那样),唯一识别/访问 DOM 的 每个 元素(包括文本)最一致/有效的符号/技术是什么?与元素混合/内联)。

我正在考虑以下符号:tag_name[index] 其中 index 将按照源代码中出现的顺序表示第 X 个元素。但是,我不确定它是否完全有效,也不确定如何在 Javascript 中实现它。我也想过 XPath,但我不确定 Javascript 是否很好地支持它(除了一些“模拟”它的框架)。

更新:我原来的帖子不是很清楚,所以我会澄清一些观点:

  • 我正在开发的库的最终目标是“最小化页面呈现”,因此在服务器端执行并将其发送回用户不是一种选择。一旦我有我正在尝试做的功能实现,我将发布更新。否则在这里解释太长了。

  • 为了澄清我真正需要做的事情,让我举一个(虚构的)例子:

    • Script X 是一个服务器端脚本,它从 document.html 中随机选择一个 DOM 节点。
    • 脚本 X 需要告诉脚本 Y(位于 document.html 中的 Javascript 脚本)删除它选择的 DOM 节点。
    • 脚本 X 如何唯一标识它选择的 DOM 节点,以便与脚本 Y 进行通信?

我对如何唯一标识 DOM 节点非常感兴趣,以便脚本 Y 可以识别并操作它。最好它也适用于文本节点。

【问题讨论】:

  • 为什么不能通过 CSS 选择器(例如通过 jQuery)或 id(通过 document.getElementById)访问它们?
  • 真正的原因需要很长时间才能解释,但基本上是因为我正在编写一个可以处理任何给定 HTML 文档的通用库。

标签: javascript html xpath


【解决方案1】:

没有 javascript 无法访问源代码。你为什么不在服务器上做呢?

【讨论】:

  • 我正在研究的库的目标是“最小化页面呈现”,因此在服务器端执行并将其发送回用户不是一种选择。一旦我对我正在尝试做的事情进行了功能实现,我会不断更新这个问题。否则在这里解释太长了。
【解决方案2】:

element_name 是指标签的名称,还是名称属性的值?对于前者,您可以这样做:

var nodeToRemove = document.getElementsByTagName('span')[7];

如果你的意思是 name 属性的值,你可以使用 jQuery 之类的库:

$('*[name=myName]:eq(7)');

或者如果使用纯 javascript,您必须手动(递归)迭代 DOM

【讨论】:

  • 我的意思是“标签的名称”。感谢您指出实现我提议的符号的实际 JS 函数。
【解决方案3】:

在某些有限的情况下是可能的。一个聪明的解决方法是,如果页面是静态的,您可以为同一页面创建 XmlHttpRequest,然后创建 responseText(),这将为您提供确切的源表示。 (注意:这可能会产生特定于浏览器的结果。)

然而,DOM 本身是一个对象图,不保留源代码结构的知识。给定一个 DOM,有无限多的原始资源可以生成它。

【讨论】:

  • getResponseText() 不会根据需要为您提供确切的源表示,例如试图计算行数。至少在 IE 中,getResponseText() 在 浏览器尝试修复不正确的 HTML 标记并因此对源代码进行潜在的更大更改之后返回文档。
  • jarnbjo:参考?你不是在想innerHTML,它的行为方式是这样的吗? XMLHttpRequest.responseText(不是getResponseText()!那是Java)通常根本不处理返回的内容(因为它甚至可能不是HTML)。
  • 感谢您的建议,但这并不是我真正想要做的 - 请参阅更新。
  • @John Feminella 不太固定 :) responseText 不是一个函数,它是一个属性,像 var myVar = xhr.responseText; 一样使用。
【解决方案4】:

浏览器将代码解析成DOM树,你可以遍历一个集合,比如document.body.childNodes并查询.nodeType(1代表元素,3代表文本节点),你可以查询nodeNames和collection all X 类型的元素。

ul 将是body 的第二个元素/子元素。 document.body.getElementsByTagName('*')[1] 会引用它,我不太确定你可以按行号来做,除非你解析 document.documentElement.innerHTML 并用换行符分解它,然后抓住第 11 行,但浏览器有可能重新格式化它。

再一次,它会帮助我们准确地、更具体地告诉我们你想要做什么。

编辑:如果您在服务器端执行此操作,请使用 DOM 库和removeElement

【讨论】:

    【解决方案5】:

    如果您访问document.body.innerHTML,您可能会获得源代码,但在某些浏览器中它可能会再次“标准化”(例如,删除了额外的换行符和空格)。

    我相信您想要的是保持语义并将 ID 分配给您知道以后可能会删除的元素。例如

    <html>
     <head>
       <script>
         var myItem = document.getElementById('list-1-item-1');
         myItem.parentNode.removeChild(myItem);
         // This should remove the line 12 from source code, 
         // eliminating the unordered list element.
       </script>
     </head>
     <body>
       <p>Some text</p>
       <ul><li id="list-1-item-1">Some list item</li></ul>
       <a>Some link</a>
     </body>
    </html>
    

    或者,如果您在父项上设置一个 ID 并同时查找它,您可以完全避免使用 parentNode

    我坚持这样做的语义,因为您的代码可能总是在浏览器、代理等中重新格式化。

    【讨论】:

      猜你喜欢
      • 2010-12-18
      • 2012-12-31
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 2020-09-26
      • 2021-10-17
      • 1970-01-01
      • 2016-08-08
      相关资源
      最近更新 更多