How do I do OuterHTML in firefox?
Part of my code I get the OuterHTML propery
"<LI onclick="TabClicked(this, 'SearchName', 'TabGroup1');">Name "
so I can do stuff involing parsing it.
There is no OuterHTML property in javascript on firefox though and I can't find an alternative way to get this string. Id开发者_如何学JAVAeas?
Here's the function we use in pure.js:
function outerHTML(node){
return node.outerHTML || new XMLSerializer().serializeToString(node);
}
To use it the DOM way:
outerHTML(document.getElementById('theNode'));
And it works cross browsers
EDIT: WARNING!
There is a trouble with XMLSerializer, it generates an XML(XHTML) string.
Which means you can end up with a tags like <div class="team" />
instead of<div class="team"></div>
Some browsers do not like it. I had some pain with Firefox 3.5 recently.
So for our pure.js
lib we came back to the old and safe way:
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);
}
The proper approach (for non-IE browsers) is:
var sOuterHTML = new XMLSerializer().serializeToString(oElement);
If you are willing to use jQuery then it's relatively simple:
$('<div>').append( $(ElementSelector).clone() ).html();
This will get the outer HTML of multiple elements if multiple elements are selected.
outerHTML is now supported by Firefox:
From Firefox 11 for developers
Firefox 11 shipped on March 13, 2012. This article provides information about the new features and key bugs fixed in this release, as well as links to more detailed documentation for both web developers and add-on developers.
- The element.outerHTML property is now supported on HTML elements.
For the reason that W3C does not include outerHTML property, you just need add following:
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());
});
}
Try this: 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;
}
);
}
}
}
How about something simple like this (not fully tested):
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 "";
}
Try:
(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);
for diyism
If all you want is the onclick attribute, then try the following: This assumes that you did not set the event using attachEvent or addEventListener.
elm.getAttribute("onclick");
If you want to make an outerHTML string (just promise not to take it apart after you make it):
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;
}
This function should do the trick in most cases, but it does not take namespaces into account.
Figured it out!
child.getAttributeNode("OnClick").nodeValue;
getAttribute didn't work, but getAttributeNode worked great ;D
I know this is an old thread but if anyone finds this with Google (like I did) - I tried all these solutions and none of them worked out-of-the-box, since none handled both the getting and setting properties of outerHTML. I found this: which worked for me:
// 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);
}
}());
Kudos: https://www.inkling.com/read/javascript-definitive-guide-david-flanagan-6th/chapter-15/implementing-the-outerhtml
精彩评论