I would like to retrieve a certain tag element with its attributes from the DOM. For example, from
link text
Unfortunately, @AaronGillion's answer isn't reliable as I said in my comment. Thank @sus. I recommend his/her way with a little change to support <self-closing tags />:
function getOpenTag(element: HTMLElement): string {
const outerHtml = element.outerHTML;
const len = outerHtml.length;
const openTagLength = outerHtml[len - 2] === '/' ? // Is self-closing tag?
len :
len - element.innerHTML.length - (element.tagName.length + 3);
// As @sus said, (element.tagName.length + 3) is the length of closing tag. It's always `</${tagName}>`. Correct?
return outerHtml.slice(0, openTagLength);
}
The code is in typescript. Remve types (HTMLElement and number) if you want javascript.
This can be done without any String manipulation.
Instead, you can use the element's internals and build the string yourself from there:
function getTagHTML(el) {
if (!el instanceof HTMLElement) return null;
let result = `<${el.tagName.toLowerCase()}`;
for (const attribute in el.attributes) {
if (el.attributes[attribute].nodeValue)
result += ` ${el.attributes[attribute].name}="${el.attributes[attribute].nodeValue.replace(/"/g, """)}"`
}
result += `></${el.tagName.toLowerCase()}>`;
return result;
}
console.log(getTagHTML(document.getElementById('outer')));
<div id="outer" class='i-want-"this"'>
<span>I do not want this</span>
</div>
Please note that for self-closing elements like <img /> this would give you an unwanted and incorrect closing tag. Feel free to adjust the code accordingly.
var wrapper = $('.class').clone().attr('id','').empty();
<a> element you're looking for.attr to clear the element's ID so that we don't duplicate IDs.innerHTML').For future Googlers, there is a way to do this without jQuery:
tag = elem.outerHTML.slice(0, elem.outerHTML.indexOf(elem.innerHTML));
Since outerHTML contains the opening tag followed by a mirror of what innerHTML contains, we can substring the outerHTML from 0 (the beginning of the opening tag) to where the innerHTML begins (end of opening tag), and since innerHTML is a mirror of outerHTML, except for the opening tag, only the opening tag will be left!
This one works with <br> tags, <meta> tags, and other empty tags:
tag = elem.innerHTML ? elem.outerHTML.slice(0,elem.outerHTML.indexOf(elem.innerHTML)) : elem.outerHTML;
Because innerHTML would be empty in self-closing tags, and indexOf('') always returns 0, the above modification checks for the presence of innerHTML first.
If someone is not using jQuery . . .
elem.outerHTML
"<a href="#" class="class">
link text
</a>"
elem.cloneNode().outerHTML
"<a href="#" class="class"></a>"
If you want to be safe for Firefox etc. released before mid-2014, use cloneNode(false) to avoid getting inner stuff.
Reference: https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode
Here is my solution:
opentag=elem.outerHTML.slice(0, elem.outerHTML.length-elem.innerHTML.length-elem.tagName.length-3);
I suppose, that close tag is of the form: "</"+elem.tagName+">".