如何使用JavaScript创建文档对象

如何使用JavaScript创建文档对象,javascript,dom,xmlhttprequest,document,specifications,Javascript,Dom,Xmlhttprequest,Document,Specifications,基本上,这就是问题所在,如何在javascript中从HTML字符串动态构造对象?根据规范(),可以使用dominemplementation的createHTMLDocument方法,可通过文档访问。实现如下所示: var doc = document.implementation.createHTMLDocument('My title'); var body = document.createElementNS('http://www.w3.org/1999/xhtml', 'body

基本上,这就是问题所在,如何在javascript中从HTML字符串动态构造对象?

根据规范(),可以使用
dominemplementation
createHTMLDocument
方法,可通过
文档访问。实现如下所示:

var doc = document.implementation.createHTMLDocument('My title');  
var body = document.createElementNS('http://www.w3.org/1999/xhtml', 'body'); 
doc.documentElement.appendChild(body);
// and so on
  • jsFiddle:
  • dom实施的MDN文档
  • 用于
    域实现的MDN文档。createHTMLDocument

规范中定义了两种方法,来自DOM核心级别2和HTML5。前者创建XML文档(包括XHTML),后者创建HTML文档。两者都作为函数驻留在
dominemplementation
界面上

var impl    = document.implementation,
    xmlDoc  = impl.createDocument(namespaceURI, qualifiedNameStr, documentType),
    htmlDoc = impl.createHTMLDocument(title);
实际上,这些方法相当年轻,仅在最近的浏览器版本中实现。根据和,以下浏览器支持
createHTMLDocument

  • 铬4
  • 歌剧10
  • 火狐4
  • Internet Explorer 9
  • 狩猎4
有趣的是,您可以使用
ActiveXObject
,在旧版本的Internet Explorer中创建HTML文档:

var htmlDoc = new ActiveXObject("htmlfile");

生成的对象将是一个新文档,它可以像任何其他文档一样进行操作。

以下内容适用于大多数常用浏览器,但在某些浏览器中不适用。这就是它应该(但不是)的简单程度:

//如果UA不支持文本/html的parseFromString(例如IE),则失败
函数HTMLTOC(标记){
var parser=新的DOMParser();
返回parser.parseFromString(标记,“text/html”);
}
var htmlString=“foo bara div”;
警报(htmlToDoc(htmlString.title);
为了解释用户代理的异常情况,以下可能更好(请注意属性):

/*
*DOMParser HTML扩展
* 2012-02-02
*
*伊莱·格雷,http://eligrey.com
*公共领域。
*没有明示或暗示的保证。使用风险自负。
*
*由RobG修改为与IE 9一起使用
* 2012-08-29
*
*注:
*
*  1. 提供的标记应为带或不带HTML标记的avalid HTML文档,以及
*没有DOCTYPE(可以添加DOCTYPE支持,只是我没有这么做)
*
*  2. 主机支持文本/html时使用的主机方法
*/
/*! @来源https://gist.github.com/1129031 */
/*! @来源https://developer.mozilla.org/en-US/docs/DOM/DOMParser */
/*全局文档解析器*/
(函数(DOMParser){
“严格使用”;
var-domu-proto;
var real_parseFromString;
var textHTML;//文本/html支持的标志
var textXML;//支持text/xml的标志
var htmleinnerHTML;//用于支持设置html元素的innerHTML的标志
//如果未定义DOMParser,请停止此处
如果(!DOMParser)返回;
//Firefox、Opera和IE在不支持的类型上抛出错误
试一试{
//WebKit在不支持的类型上返回null
textHTML=!!(新的DOMParser).parseFromString(“”,'text/html');
}捕获(er){
textHTML=false;
}
//如果支持text/html,则无需执行任何操作。
如果(textHTML)返回;
//下一步尝试设置已创建文档的innerHTML
//IE 9及更低版本将抛出错误(无法设置其HTML元素的innerHTML)
试一试{
var doc=document.implementation.createHTMLDocument(“”);
doc.documentElement.innerHTML='';
htmleinnerHTML=true;
}捕获(er){
HtmlInnerHtml=false;
}
//如果失败,请尝试text/xml
如果(!HtmleInnerHtml){
试一试{
textXML=!!(新的DOMParser).parseFromString(“”,'text/xml');
}捕获(er){
textHTML=false;
}
}
//如果上述其中一项有效,请使用DOMParser.prototype(低于最佳…)
//假设可以写入原型,如果不能,则将其作为独立函数
if(DOMParser.prototype&(htmleinnerHTML | | textXML)){
DOMParser_proto=DOMParser.prototype;
real_parseFromString=DOMParser_proto.parseFromString;
DOMParser_proto.parseFromString=函数(标记,类型){
//仅当类型为text/html时才执行此操作
if(/^\s*text\/html\s*(?:;|$)/i.test(type)){
var doc,doc_el,first_el;
//如果支持,请使用innerHTML
如果(HTML){
doc=document.implementation.createHTMLDocument(“”);
doc_el=doc.documentElement;
doc_el.innerHTML=标记;
first_el=doc_el.firstElementChild;
//否则使用XML方法
}else if(textXML){
//确保标记包装在HTML标记中
//应该允许使用DOCTYPE
如果(!(/^$/i.test(标记))){
标记=“”+标记+“”;
}
doc=(新的DOMParser).parseFromString(标记为'text/xml');
doc_el=doc.documentElement;
first_el=doc_el.firstElementChild;
}
//RG:我不明白这是什么意思,不过我还是把它留在这里
//在IE中,doc_el是HTML元素,first_el是HEAD。
//
//这是一个完整的文档还是一个片段?
if(doc_el.childElementCount==1&&first_el.localName.toLowerCase()==html){
替换文件(第一个文件,文件);
}
退货单;
//如果不是text/html,则按原样发送到主机方法
}否则{
返回real_parseFromString.apply(这是参数);
}
};
}
}(多姆);
//现在是一些测试代码
var htmlString='foo bara div';
var dp=新的DOMParser();
var doc=dp.parseFromString(htmlString,'text/html');
//将其视为XML文档并仅使用DOM核心方法
警报(doc.documentElement.getElementsByTagName('title')[0].childNodes
// Fails if UA doesn't support parseFromString for text/html (e.g. IE)
function htmlToDoc(markup) {
  var parser = new DOMParser();
  return parser.parseFromString(markup, "text/html");
}

var htmlString = "<title>foo bar</title><div>a div</div>";
alert(htmlToDoc(htmlString).title);
/*
 * DOMParser HTML extension
 * 2012-02-02
 *
 * By Eli Grey, http://eligrey.com
 * Public domain.
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 *
 * Modified to work with IE 9 by RobG
 * 2012-08-29
 *
 * Notes:
 *
 *  1. Supplied markup should be avalid HTML document with or without HTML tags and
 *     no DOCTYPE (DOCTYPE support can be added, I just didn't do it)
 *
 *  2. Host method used where host supports text/html
 */

/*! @source https://gist.github.com/1129031 */
/*! @source https://developer.mozilla.org/en-US/docs/DOM/DOMParser */

/*global document, DOMParser*/

(function(DOMParser) {
    "use strict";

    var DOMParser_proto;
    var real_parseFromString;
    var textHTML;         // Flag for text/html support
    var textXML;          // Flag for text/xml support
    var htmlElInnerHTML;  // Flag for support for setting html element's innerHTML

    // Stop here if DOMParser not defined
    if (!DOMParser) return;

    // Firefox, Opera and IE throw errors on unsupported types
    try {
        // WebKit returns null on unsupported types
        textHTML = !!(new DOMParser).parseFromString('', 'text/html');

    } catch (er) {
      textHTML = false;
    }

    // If text/html supported, don't need to do anything.
    if (textHTML) return;

    // Next try setting innerHTML of a created document
    // IE 9 and lower will throw an error (can't set innerHTML of its HTML element)
    try {
      var doc = document.implementation.createHTMLDocument('');
      doc.documentElement.innerHTML = '<title></title><div></div>';
      htmlElInnerHTML = true;

    } catch (er) {
      htmlElInnerHTML = false;
    }

    // If if that failed, try text/xml
    if (!htmlElInnerHTML) {

        try {
            textXML = !!(new DOMParser).parseFromString('', 'text/xml');

        } catch (er) {
            textHTML = false;
        }
    }

    // Mess with DOMParser.prototype (less than optimal...) if one of the above worked
    // Assume can write to the prototype, if not, make this a stand alone function
    if (DOMParser.prototype && (htmlElInnerHTML || textXML)) { 
        DOMParser_proto = DOMParser.prototype;
        real_parseFromString = DOMParser_proto.parseFromString;

        DOMParser_proto.parseFromString = function (markup, type) {

            // Only do this if type is text/html
            if (/^\s*text\/html\s*(?:;|$)/i.test(type)) {
                var doc, doc_el, first_el;

                // Use innerHTML if supported
                if (htmlElInnerHTML) {
                    doc = document.implementation.createHTMLDocument("");
                    doc_el = doc.documentElement;
                    doc_el.innerHTML = markup;
                    first_el = doc_el.firstElementChild;

                // Otherwise use XML method
                } else if (textXML) {

                    // Make sure markup is wrapped in HTML tags
                    // Should probably allow for a DOCTYPE
                    if (!(/^<html.*html>$/i.test(markup))) {
                        markup = '<html>' + markup + '<\/html>'; 
                    }
                    doc = (new DOMParser).parseFromString(markup, 'text/xml');
                    doc_el = doc.documentElement;
                    first_el = doc_el.firstElementChild;
                }

                // RG: I don't understand the point of this, I'll leave it here though 
                //     In IE, doc_el is the HTML element and first_el is the HEAD.
                //
                // Is this an entire document or a fragment?
                if (doc_el.childElementCount == 1 && first_el.localName.toLowerCase() == 'html') {
                    doc.replaceChild(first_el, doc_el);
                }

                return doc;

            // If not text/html, send as-is to host method
            } else {
                return real_parseFromString.apply(this, arguments);
            }
        };
    }
}(DOMParser));

// Now some test code
var htmlString = '<html><head><title>foo bar</title></head><body><div>a div</div></body></html>';
var dp = new DOMParser();
var doc = dp.parseFromString(htmlString, 'text/html');

// Treat as an XML document and only use DOM Core methods
alert(doc.documentElement.getElementsByTagName('title')[0].childNodes[0].data);
var stringToXMLDoc = (function(global) {

  // W3C DOMParser support
  if (global.DOMParser) {
    return function (text) {
      var parser = new global.DOMParser();
      return parser.parseFromString(text,"application/xml");
    }

  // MS ActiveXObject support
  } else {
    return function (text) {
      var xmlDoc;

      // Can't assume support and can't test, so try..catch
      try {
        xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async="false";
        xmlDoc.loadXML(text);
      } catch (e){}
      return xmlDoc;
    }
  }
}(this));


var doc = stringToXMLDoc('<books><book title="foo"/><book title="bar"/><book title="baz"/></books>');
alert(
  doc.getElementsByTagName('book')[2].getAttribute('title')
);
var doc = (new DOMParser).parseFromString(markup, mime_type);
var doc = document.implementation.createHTMLDocument('');
doc.open();
doc.write(html);
doc.close();
function parseHTML(sText) {
try {

    console.log("Domparser: " + typeof window.DOMParser);

    if (typeof window.DOMParser !=null) {
        // modern IE, Firefox, Opera  parse text/html
        var parser = new DOMParser();
        var doc = parser.parseFromString(sText, "text/html");
        if (doc != null) {
            console.log("parsed as HTML");
            return doc

        }
        else {

            //replace ampersands with harmless character string to avoid XML parsing issues
            sText = sText.replace(/&/gi, "j!J!");
            //safari parses as text/xml
            var doc = parser.parseFromString(sText, "text/xml");
            console.log("parsed as XML");
            return doc;
        }

    } 
    else  {
        // older IE 
        doc= document.implementation.createHTMLDocument('');
        doc.write(sText);           
        doc.close;
        return doc; 
    }
} catch (err) {
    alert("Error parsing html:\n" + err.message);
}
}