Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/441.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
解析html会中断与javascript相关的项目,尽管保留了脚本_Javascript_Html_Google Chrome Extension - Fatal编程技术网

解析html会中断与javascript相关的项目,尽管保留了脚本

解析html会中断与javascript相关的项目,尽管保留了脚本,javascript,html,google-chrome-extension,Javascript,Html,Google Chrome Extension,因此,我有一个脚本,它接受body的innerHTML(是的,body标记中的所有内容),将所有阿拉伯数字(123)转换为阿拉伯印度数字(£٣٣),并用修改后的替换innerHTML。现在,解析器工作得很好,只更改用户在页面上可见的数字,避免标记属性中的数字,并保持“敏感”标记(如脚本、样式、noscript…)中的内容不变(我正在解决一些问题),就像我希望的那样!(顺便说一下,这是在chrome扩展中运行的,脚本在触发onLoad事件时运行) 但由于某种原因,有些东西停止了应有的功能。例如,以

因此,我有一个脚本,它接受body的innerHTML(是的,body标记中的所有内容),将所有阿拉伯数字(123)转换为阿拉伯印度数字(£٣٣),并用修改后的替换innerHTML。现在,解析器工作得很好,只更改用户在页面上可见的数字,避免标记属性中的数字,并保持“敏感”标记(如脚本、样式、noscript…)中的内容不变(我正在解决一些问题),就像我希望的那样!(顺便说一下,这是在chrome扩展中运行的,脚本在触发onLoad事件时运行)

但由于某种原因,有些东西停止了应有的功能。例如,以一个关于堆栈溢出的随机问题为例;“向上/向下投票”按钮停止工作。我甚至还比较了原始和未解析的HTML:

那里一切看起来都很好;唯一的区别是数字,虽然用户可以看到的一些链接(例如,格式化帮助部分中的链接)被更改,但我计划解决这个问题,而且它对脚本没有任何影响,所以我现在忽略它们


感谢您花时间阅读,更感谢您的回答:)

如上所述,替换页面正文中的html会生成所有新元素(尽管与原始元素相同),这会导致丢弃所有附加到它们的事件。您要做的是循环遍历正文中的所有文本节点。这是使用XPath最容易做到的:

xpath = new XPathEvaluator()
xpath.evaluate("//text()", document.body)
这将返回当前文档正文中所有文本节点的数组。然后可以循环浏览它们并修改它们的每个内容

另一个问题是,这可能仍然会中断正在修改的文本节点中解析数字的脚本。对此,我能想到的唯一解决方案(是的,它非常粗糙)是扩展
Number
函数的行为:

(function (){
  var oldNumber = Number
  window.Number = function(obj){
    if(typeof obj == "string"){
      // replace numerals
      var numerals = ["٠","١","٢","٣","٤","٥","٦","٧","٨","٩"]
      for(idx in numerals){
        obj = obj.replace(new RegExp(numerals[idx],"g"), idx)
      }
      // replace decimal point
      obj.replace(/٫/g,".")
    }
    return oldNumber(obj)
  }
})()

您还必须扩展parseInt和parseFloat函数,以使一切正常工作,尽管代码几乎相同。这将防止从html中解析数字的脚本被破坏;但请注意,当它们将数字显示回网页时,它们将是普通的阿拉伯数字。要解决这个问题,您可以扩展Number的
到string
方法,但这可能比扩展相对安全的Number解析函数更危险。

我建议获取文本节点并直接修改它们:

//这将获取元素的后代的所有文本节点。
函数getTextNodes(元素){
变量节点=[],
children=element.childNodes,
i=0,child=children[0];
for(;i

您可以在演示中看到,单击事件不受节点数据更改的影响。

您说javascript中断。有错误信息吗?我唯一的猜测是javascript在某种程度上依赖于在HTML中看到其他格式的数字。如果有任何事件通过javascript(而不是内联)绑定到元素,它们将被删除,因为当您设置innerHTML时,它会破坏当前DOM节点并用新节点替换它们。而不是使用innerHTML,您应该能够更改文本节点。此外,快速测试替换此问题的upvotes文本节点(使用阿拉伯-印度数字)表明它会破坏投票脚本。脚本显然会解析并增加数字。不要放弃!这两个问题都不太难解决:)谢谢!只是一个简单的问题:我应该什么时候运行覆盖数字的函数?该函数是匿名的,一旦定义它就会被调用(这就是结尾的
()
)。该外部包装器仅用于防止
oldNumber
变量泄漏。
// this will get all text nodes that are descendant of element. 
function getTextNodes(element) {
    var nodes = [],
        children = element.childNodes,
        i=0, child = children[0];

    for (; i < children.length; i++, child=children[i]) {
        if (child.nodeType === 3) nodes.push(child);
        else nodes = nodes.concat(getTextNodes(child));
    }

    return nodes;
}

var nodes = getTextNodes(document.body); // get all text nodes in the body.

for (var i = 0; i < nodes.length; i++) {
    var node = nodes[i];

    node.data = node.data.replace(/text/g, "banana"); // replace "text" with "banana"
}​