如何在 Firefox 中执行 OuterHTML?

Posted

技术标签:

【中文标题】如何在 Firefox 中执行 OuterHTML?【英文标题】:How do I do OuterHTML in firefox? 【发布时间】:2010-12-14 15:00:45 【问题描述】:

我的部分代码获得了 Outerhtml 属性

"<LI onclick="TabClicked(this, 'SearchName', 'TabGroup1');">Name "

所以我可以做一些涉及解析它的事情。

firefox 上的 javascript 中没有 OuterHTML 属性,但我找不到获取此字符串的替代方法。想法?

【问题讨论】:

从您的示例中不清楚您想要完成什么以及在哪里使用此属性。 我想要的只是 OnClick 事件中的文本作为字符串,所以我可以用它来做事。 如果你想要的只是onclick,那么使用elm.getAttribute("onclick")。 是的,你会这么认为,但大量的谷歌搜索显示 getattribute 在每个浏览器中都存在错误和损坏,而 getattributenode 是解决方案;) 好的,那就改用getAttributeNode吧。这仍然无法解释您为什么需要 outerHTML(当然,您可能还有其他原因需要它) 【参考方案1】:

这是我们在pure.js中使用的函数:

function outerHTML(node)
    return node.outerHTML || new XMLSerializer().serializeToString(node);

以 DOM 方式使用它:

outerHTML(document.getElementById('theNode'));

它可以跨浏览器工作

编辑:警告! XMLSerializer 有问题,它会生成一个 XML(XHTML) 字符串。 这意味着您最终可以使用&lt;div class="team" /&gt; 之类的标签,而不是&lt;div class="team"&gt;&lt;/div&gt;某些浏览器不喜欢它。我最近对 ​​Firefox 3.5 感到有些痛苦。

所以对于我们的pure.js lib,我们回到了旧的安全方式:

function outerHTML(node)
    // if IE, Chrome take the internal method otherwise build one
  return node.outerHTML || (
      function(n)
          var div = document.createElement('div'), h;
          div.appendChild( n.cloneNode(true) );
          h = div.innerHTML;
          div = null;
          return h;
      )(node);
  

【讨论】:

谢谢,我用了你最后的方法! Firefox 11 将原生支持 outerHTML - 请参阅 bugzilla.mozilla.org/show_bug.cgi?id=92264 @Nickolay wow... 10 年的请求终于得到了答复!感谢更新 打高尔夫球:document.createElement('_').appendChild(node.cloneNode(true)).innerHTML @yckart,很有趣。但是 Chrome 似乎不喜欢 '_',并且你忘记了一个 parentNode 来获取外部标签。但是像document.createElement('div').appendChild( n.cloneNode(true) ).parentNode.innerHTML 这样的东西效果很好。谢谢!【参考方案2】:

正确的方法(对于非 IE 浏览器)是:

var sOuterHTML = new XMLSerializer().serializeToString(oElement);

【讨论】:

注意 XMLSerializer 生成 XML(XHTML) 然后做类似&lt;div /&gt;而不是&lt;div&gt;&lt;/div&gt;的事情。在这里查看我的答案。【参考方案3】:

如果你愿意使用 jQuery 那就比较简单了:

$('<div>').append( $(ElementSelector).clone() ).html();

如果选择了多个元素,这将得到 the outer HTML of multiple elements

【讨论】:

很好的答案,谢谢!工作完美。非常简单干净。【参考方案4】:

outerHTML 现在被 Firefox 支持:

来自Firefox 11 for developers

Firefox 11 于 2012 年 3 月 13 日发布。本文提供有关此版本中新功能和修复的主要错误的信息,以及指向 Web 开发人员和插件开发人员的更详细文档的链接。

现在 HTML 元素支持 element.outerHTML 属性。

【讨论】:

【参考方案5】:

由于 W3C 不包含 outerHTML 属性,您只需添加以下内容:

if (typeof (HTMLElement) != "undefined" && !window.opera)  
  
    HTMLElement.prototype._____defineGetter_____("outerHTML", function()  
      
        var a = this.attributes, str = "<" + this.tagName, i = 0; for (; i < a.length; i++)  
            if (a[i].specified)  
            str += " " + a[i].name + '="' + a[i].value + '"';  
        if (!this.canHaveChildren)  
            return str + " />";  
        return str + ">" + this.innerHTML + "</" + this.tagName + ">";  
    );  
    HTMLElement.prototype._____defineSetter_____("outerHTML", function(s)  
      
        var r = this.ownerDocument.createRange();  
        r.setStartBefore(this);  
        var df = r.createContextualFragment(s);  
        this.parentNode.replaceChild(df, this);  
        return s;  
    );  
    HTMLElement.prototype._____defineGetter_____("canHaveChildren", function()  
      
        return !/^(area|base|basefont|col|frame|hr|img|br|input|isindex|link|meta|param)$/.test(this.tagName.toLowerCase());   
    );  
 

【讨论】:

【参考方案6】:

试试这个:http://snipplr.com/view/5460/outerhtml-in-firefox/:

if (document.body.__defineGetter__)  
   if (HTMLElement) 
      var element = HTMLElement.prototype;
      if (element.__defineGetter__) 
         element.__defineGetter__("outerHTML",
           function () 
              var parent = this.parentNode;
              var el = document.createElement(parent.tagName);
              el.appendChild(this);
              var shtml = el.innerHTML;
              parent.appendChild(this);
              return shtml;
           
         );
      
   

【讨论】:

该页面的问题在于它陷入了与人们说原始示例错误的讨论中,所以我对此感到很困惑。 其实那个说错的人后来说它确实有效——你试过了吗?【参考方案7】:

像这样简单的东西怎么样(未完全测试):

function outerHTML(node) 
    var el;
    if (node.outerHTML) 
        return node.outerHTML;
     else if (node.parentNode && node.parentNode.nodeType == 1) 
        var el = document.createElement(node.parentNode.nodeName);
        el.appendChild( node.cloneNode(true) );
        return el.innerHTML;
    
    return "";

【讨论】:

【参考方案8】:

试试:

(function(ele, html)
if (typeof(ele.outerHTML)=='undefined')
    var r=ele.ownerDocument.createRange();
     r.setStartBefore(ele);
     ele.parentNode.replaceChild(r.createContextualFragment(html), ele);
    
 else
     ele.outerHTML=html;
     
)(aEle, aHtml);

为了自制

【讨论】:

【参考方案9】:

如果您只需要 onclick 属性,请尝试以下操作:假设您没有使用 attachEvent 或 addEventListener 设置事件。

elm.getAttribute("onclick");

如果你想制作一个outerHTML字符串(只要保证制作后不拆开它):

function outerHTML(elm)
  var ret = "<"+elm.tagName;
  for(var i=0; i<elm.attributes.length; i++)
    var attr = elm.attributes[i];
    ret += " "+attr.name+"=\""+attr.nodeValue.replace(/"/, "\"")+"\"";
  
  ret += ">";
  ret += elm.innerHTML+"</"+elm.tagName+">";
  return ret;

这个函数在大多数情况下应该可以解决问题,但它不考虑命名空间。

【讨论】:

我记得尝试过getattribute,但我不知道如何从中获取文本...如果可能的话,它比outerhtml更整洁 试过你的函数,但它只是返回 temp = " 通过添加 if (attr) ... 来修改它,结果中不会枚举未定义的属性。【参考方案10】:

想通了!

child.getAttributeNode("OnClick").nodeValue;

getAttribute 没用,但 getAttributeNode 效果很好;D

【讨论】:

对“getAttribute 不起作用”感兴趣的人的背景信息:***.com/questions/1833973/… 我在链接中看不到任何关于 getAttribute 与 getAttributeNode 不同的具体解释【参考方案11】:

我知道这是一个旧线程,但如果有人在 Google 上找到了这个(就像我一样) - 我尝试了所有这些解决方案,但没有一个是开箱即用的,因为没有一个同时处理获取和设置属性外层HTML。我发现了这个:这对我有用:

// Implement the outerHTML property for browsers that don't support it.
// Assumes that the browser does support innerHTML, has an extensible 
// Element.prototype, and allows getters and setters to be defined.
(function() 
// If we already have outerHTML return without doing anything
if (document.createElement("div").outerHTML) return;

// Return the outer HTML of the element referred to by this
function outerHTMLGetter() 
    var container = document.createElement("div"); // Dummy element
    container.appendChild(this.cloneNode(true));   // Copy this to dummy
    return container.innerHTML;                    // Return dummy content


// Set the outer HTML of the this element to the specified value
function outerHTMLSetter(value) 
    // Create a dummy element and set its content to the specified value
    var container = document.createElement("div");
    container.innerHTML = value;
    // Move each of the nodes from the dummy into the document
    while(container.firstChild)  // Loop until container has no more kids
        this.parentNode.insertBefore(container.firstChild, this);
    // And remove the node that has been replaced
    this.parentNode.removeChild(this);


// Now use these two functions as getters and setters for the 
// outerHTML property of all Element objects. Use ES5 Object.defineProperty
// if it exists and otherwise fall back on __defineGetter__ and Setter__.
if (Object.defineProperty) 
    Object.defineProperty(Element.prototype, "outerHTML", 
                              get: outerHTMLGetter,
                              set: outerHTMLSetter,
                              enumerable: false, configurable: true
                          );

else 
    Element.prototype.__defineGetter__("outerHTML", outerHTMLGetter);
    Element.prototype.__defineSetter__("outerHTML", outerHTMLSetter);

());

荣誉:https://www.inkling.com/read/javascript-definitive-guide-david-flanagan-6th/chapter-15/implementing-the-outerhtml

【讨论】:

以上是关于如何在 Firefox 中执行 OuterHTML?的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript Firefox中的outerHTML

什么时候应该在 JavaScript 中使用 outerHTML? [关闭]

如何修复未捕获的 TypeError:无法读取 null 的属性“outerHTML”

jq-outerhtml不能执行新元素内部的js解决方案

如何在不使用outerHTML的情况下在javascript中将标签作为文本? [复制]

jQuery outerHTML 关闭标签