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+">"
.