get opening tag including attributes - outerHTML without innerHTML
-
09-12-2019 - |
Frage
I would like to retrieve a certain tag element with its attributes from the DOM. For example, from
<a href="#" class="class">
link text
</a>
I want to get <a href="#" class="class">
, optionally with a closing </a>
, either as a string or some other object.
In my opinion, this would be similar to retrieving the .outerHTML
without the .innerHTML
.
Finally, I need this to wrap some other elements via jQuery. I tried
var elem = $('#some-element').get(0);
$('#some-other-element').wrap(elem);
but .get()
returns the DOM element including its content. Also
var elem = $('#some-element').get(0);
$('#some-other-element').wrap(elem.tagName).parent().attr(elem.attributes);
fails as elem.attributes
returns a NamedNodeMap
which does not work with jQuery's attr()
and I was not able to convert it.
Admitted that the above examples are not very senseful as they copy also the element's no-longer-unique ID. But is there any easy way? Thanks alot.
Lösung
var wrapper = $('.class').clone().attr('id','').empty();
- You might want to change the selector to more exactly match the
<a>
element you're looking for. clone()
creates a new copy of the matched element(s), optionally copying event handlers too.- I used
attr
to clear the element's ID so that we don't duplicate IDs. empty()
removes all child nodes (the 'innerHTML
').
Andere Tipps
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.
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+">"
.
Unfortunately, @AaronGillion's answer isn't reliable as I said in a 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 pure Javascript.
Here's a solution I've used:
const wrap = document.createElement('div')
wrap.appendChild(target.cloneNode(true))
const openingTag = wrap.innerHTML.split('>')[0] + '>'