JavaScript DOM解析器访问innerHTML和其他属性

33

我正在使用以下代码将字符串解析为 DOM:

var doc = new DOMParser().parseFromString(string, 'text/xml');

string 类似于 <!DOCTYPE html><html><head></head><body>content</body></html> 时。

typeof doc 返回 object。如果我执行像 doc.querySelector('body') 这样的操作,会返回一个 DOM 对象。但是,如果我尝试访问任何属性,就像通常可以的那样,它会返回 undefined

doc.querySelector('body').innerHTML; // undefined

对于其他属性,例如id,情况也是如此。另一方面,属性检索正常运行doc.querySelector('body').getAttribute('id');

是否有一种神奇的函数可以访问这些属性?

3个回答

57

你当前的方法失败了,因为给定的XML文档未定义HTML属性。如果你提供text/html MIME类型,这个方法应该可以工作。

var string = '<!DOCTYPE html><html><head></head><body>content</body></html>';
var doc = new DOMParser().parseFromString(string, 'text/html');
doc.body.innerHTML; // or doc.querySelector('body').innerHTML
// ^ Returns "content"

以下代码可为尚未原生支持text/html MIME类型的浏览器启用它。该代码摘自Mozilla开发者网络

/* 
 * DOMParser HTML extension 
 * 2012-02-02 
 * 
 * By Eli Grey, http://eligrey.com 
 * Public domain. 
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. 
 */  

/*! @source https://gist.github.com/1129031 */  
/*global document, DOMParser*/  

(function(DOMParser) {  
    "use strict";  
    var DOMParser_proto = DOMParser.prototype  
      , real_parseFromString = DOMParser_proto.parseFromString;

    // Firefox/Opera/IE throw errors on unsupported types  
    try {  
        // WebKit returns null on unsupported types  
        if ((new DOMParser).parseFromString("", "text/html")) {  
            // text/html parsing is natively supported  
            return;  
        }  
    } catch (ex) {}  

    DOMParser_proto.parseFromString = function(markup, type) {  
        if (/^\s*text\/html\s*(?:;|$)/i.test(type)) {  
            var doc = document.implementation.createHTMLDocument("")
              , doc_elt = doc.documentElement
              , first_elt;

            doc_elt.innerHTML = markup;
            first_elt = doc_elt.firstElementChild;

            if (doc_elt.childElementCount === 1
                && first_elt.localName.toLowerCase() === "html") {  
                doc.replaceChild(first_elt, doc_elt);  
            }  

            return doc;  
        } else {  
            return real_parseFromString.apply(this, arguments);  
        }  
    };  
}(DOMParser));

3
为了澄清,当使用 text/xml 时,docXMDocument 的一个实例。而当使用 text/html 时,docHTMLDocument 的一个实例。 - Rob W
哇,非常有用的答案!我自己找不到这个。只需要 MIME 类型并启用该 MIME 类型 :) - DADU
1
@RobW 我猜你是指 XMLDocument - devios1
感谢@RobW。这对于反向过程非常有用,其中可以使用正则表达式编辑文本字符串以添加HTML,然后构建替换节点[避免使用innerHTML](https://dev59.com/4G_Xa4cB1Zd3GeqP3q20#15535762)。您的解决方案完美地解决了问题! - Mike Wolfe
解决方案还不错,但是:
  • 为什么要使用逗号运算符而不是只用三个指令?这种选项更加“晦涩”,并且没有任何优势。此外,first_elt使用会在窗口作用域中创建一个全局变量(这很糟糕)。
- Adrian Maire
显示剩余9条评论

3

尝试像这样:

const fragment = document.createRange().createContextualFragment(html);

HTML是您要转换的字符串。


是的,如果您还想执行脚本,那么这是最好的解决方案,例如: https://dev59.com/7H7aa4cB1Zd3GeqPrIJf#58862506 - marciowb

0

对于 XML/HTML 元素,请使用 element.getAttribute(attributeName)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接