Как мне использовать OuterHTML в firefox?

Часть моего кода я получаю свойство OuterHTML

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

так что я могу делать что-то с его анализом.

Однако в javascript на firefox нет свойства OuterHTML, и я не могу найти альтернативный способ получить эту строку. Идеи?


person NibblyPig    schedule 09.11.2009    source источник
comment
Из вашего примера неясно, чего вы хотите достичь и где вы используете это свойство.   -  person Darin Dimitrov    schedule 09.11.2009
comment
Все, что мне нужно, это текст в событии OnClick в виде строки, чтобы я мог что-то с ней делать.   -  person NibblyPig    schedule 09.11.2009
comment
Если вам нужен только onclick, используйте elm.getAttribute (onclick).   -  person Marius    schedule 09.11.2009
comment
Да, вы так и думаете, но интенсивный поиск в Google показал, что getattribute работает с ошибками и не работает в каждом браузере, и getattributenode был решением;)   -  person NibblyPig    schedule 09.11.2009
comment
Хорошо, тогда используйте вместо этого getAttributeNode. Это все еще не объясняет, почему вам нужен внешний HTML (хотя, конечно, есть и другие причины, по которым он может вам понадобиться)   -  person MatrixFrog    schedule 27.08.2010
comment
Причина, по которой я хотел этого, заключалась в том, что у меня был некоторый javascript, который сканировал события onclick и делал с ним некоторые забавные вещи, чтобы создать элемент управления вкладкой. Это было некоторое время назад, и я не знал jquery =)   -  person NibblyPig    schedule 06.12.2011


Ответы (11)


Вот функция, которую мы используем в pure.js:

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

Чтобы использовать это способом DOM:

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

И он работает в разных браузерах

РЕДАКТИРОВАТЬ: ВНИМАНИЕ! Проблема с XMLSerializer, он генерирует строку XML (XHTML).
Это означает, что вы можете получить такие теги, как <div class="team" /> вместо
<div class="team"></div> < br /> Некоторым браузерам это не нравится. Недавно у меня были проблемы с 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);
  }
person Mic    schedule 29.09.2010
comment
Спасибо, я воспользовался вашим последним способом! - person Web_Designer; 14.05.2011
comment
Firefox 11 изначально будет поддерживать externalHTML - см. bugzilla.mozilla.org/show_bug.cgi?id= 92264 - person Nickolay; 05.12.2011
comment
@Nickolay wow ... наконец-то дан ответ на 10-летний запрос! Спасибо за обновления - person Mic; 05.12.2011
comment
Забиты в гольф: document.createElement('_').appendChild(node.cloneNode(true)).innerHTML - person yckart; 08.08.2014
comment
@yckart, интересно. Но Chrome, похоже, не нравится '_', и вы забыли родительский узел для получения внешнего тега. Однако что-то вроде document.createElement('div').appendChild( n.cloneNode(true) ).parentNode.innerHTML работает неплохо. Спасибо! - person Mic; 08.08.2014
comment
@Mic Упс ... У меня был только айфон и голова. Нет возможности проверить это раньше;) - person yckart; 08.08.2014

Правильный подход (для браузеров, отличных от IE):

var sOuterHTML = new XMLSerializer().serializeToString(oElement);
person Sergey Ilinsky    schedule 09.11.2009
comment
Обратите внимание, что XMLSerializer генерирует XML (XHTML), а затем выполняет такие действия, как <div /> вместо <div></div>. Смотрите мой ответ здесь. - person Mic; 03.12.2010

Если вы хотите использовать jQuery, это относительно просто:

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

Будет получен внешний HTML-код нескольких элементов, если выбрано несколько элементов.

person Peter Ajtai    schedule 10.09.2010
comment
Отличный ответ, спасибо! Сработало отлично. Очень просто и чисто. - person Andre Bulatov; 17.09.2015

outerHTML теперь поддерживается Firefox:

Из Firefox 11 для разработчиков

Firefox 11 выпущен 13 марта 2012 г. В этой статье содержится информация о новых функциях и основных ошибках, исправленных в этом выпуске, а также ссылки на более подробную документацию как для веб-разработчиков, так и для разработчиков надстроек.

  • Свойство element.outerHTML теперь поддерживается в элементах HTML.
person Rich Bennema    schedule 10.04.2012

Поскольку 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());   
    });  
} 
person sesame    schedule 29.03.2010

Попробуйте это: 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;
           }
         );
      }
   }
}
person Mark Bell    schedule 09.11.2009
comment
Проблема с этой страницей заключается в том, что она становится предметом обсуждения, когда люди говорят, что исходный пример неверен, поэтому меня это очень смущает. - person NibblyPig; 09.11.2009
comment
На самом деле парень, который говорит, что это неправильно, позже говорит, что это работает - вы пробовали? - person Mark Bell; 09.11.2009

Как насчет чего-то простого (не полностью протестированного):

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 "";
}
person Tim Down    schedule 09.11.2009

Пытаться:

(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);

для diyism

person diyism    schedule 18.05.2010

Если вам нужен только атрибут onclick, попробуйте следующее: Предполагается, что вы не установили событие с помощью attachEvent или addEventListener.

elm.getAttribute("onclick");

Если вы хотите создать внешнюю строку HTML (просто пообещайте не разбирать ее после того, как сделаете это):

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;
}

Эта функция должна помочь в большинстве случаев, но она не принимает во внимание пространства имен.

person Marius    schedule 09.11.2009
comment
Я помню, как пытался получить атрибут, но я не мог понять, как вытащить из него текст ... если возможно, это намного аккуратнее, чем outerhtml - person NibblyPig; 09.11.2009
comment
Пробовал вашу функцию, но она просто вернулась с temp = ‹LI undefined = undefined undefined = undefined undefined = undefined undefined = undefined undefined = undefined undefined = undefined undefined = undefined undefined = undefined ... и т. Д. - person NibblyPig; 09.11.2009
comment
Измените это, добавив if (attr) {...}, и неопределенные атрибуты не будут перечислены в результате. - person Stan Rogers; 19.09.2010

Догадаться!

child.getAttributeNode("OnClick").nodeValue;

getAttribute не работал, но getAttributeNode работал отлично; D

person NibblyPig    schedule 09.11.2009
comment
справочная информация для тех, кто заинтересован в getAttribute, не сработала: stackoverflow.com/questions/1833973/ - person Nickolay; 05.12.2011
comment
Я не вижу конкретного объяснения того, почему getAttribute отличается от getAttributeNode в ссылке - person NibblyPig; 06.12.2011

Я знаю, что это старый поток, но если кто-то обнаружит это с помощью Google (например, я) - я попробовал все эти решения, и ни одно из них не сработало из коробки, поскольку ни одно из них не обрабатывало как получение, так и установку свойств externalHTML. Я нашел это: что сработало для меня:

// 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

person JSP64    schedule 28.04.2013