Получить открывающий тег, включая атрибуты - outerHTML без innerHTML

Я хотел бы получить определенный элемент тега с его атрибутами из DOM. Например, из

<a href="#" class="class">
  link text
</a>

Я хочу получить <a href="#" class="class">, необязательно с закрытием </a>, либо как строку, либо какой-либо другой объект. По-моему, это было бы похоже на извлечение .outerHTML без .innerHTML.

Наконец, мне нужно это, чтобы обернуть некоторые другие элементы через jQuery. Я попробовал

var elem = $('#some-element').get(0);
$('#some-other-element').wrap(elem);

но .get() возвращает элемент DOM, включая его содержимое. Также

var elem = $('#some-element').get(0);
$('#some-other-element').wrap(elem.tagName).parent().attr(elem.attributes);

не работает, поскольку elem.attributes возвращает NamedNodeMap, который не работает с jQuery attr(), и я не смог его преобразовать. Приняли, что приведенные выше примеры не очень понятны, поскольку они копируют также элемент no-long-unique ID. Но есть ли простой способ? Большое спасибо.

Ответ 1

var wrapper = $('.class').clone().attr('id','').empty();
  • Возможно, вы захотите изменить селектор, чтобы он более точно соответствовал элементу <a>, который вы ищете.
  • clone() создает новую копию соответствующих элементов, а также дополнительно копирует обработчики событий.
  • Я использовал attr для очистки идентификатора элемента, чтобы мы не дублировали идентификаторы.
  • empty() удаляет все дочерние узлы ('innerHTML').

Ответ 2

Для будущих Googlers существует способ сделать это без jQuery:

tag = elem.outerHTML.slice(0, elem.outerHTML.indexOf(elem.innerHTML));

Так как outerHTML содержит тег открытия, за которым следует зеркало того, что содержит innerHTML, мы можем подстроить outerHTML от 0 (начало открытого тега) туда, где innerHTML начинается (конец открытого тега), а поскольку innerHTML является зеркалом outerHTML, за исключением открытого тега, останется только тег открытия!

Этот файл работает с тегами <br>, тегами <meta> и другими пустыми тегами:

tag = elem.innerHTML ? elem.outerHTML.slice(0,elem.outerHTML.indexOf(elem.innerHTML)) : elem.outerHTML;

Поскольку innerHTML будет пустым в самозакрывающихся тегах, а indexOf('') всегда возвращает 0, вышеуказанная модификация сначала проверяет наличие innerHTML.

Ответ 3

Вот мое решение:

opentag=elem.outerHTML.slice(0, elem.outerHTML.length-elem.innerHTML.length-elem.tagName.length-3);

Я предполагаю, что закрывающий тег имеет форму: "</"+elem.tagName+">".

Ответ 4

К сожалению, ответ @AaronGillion не является надежным, как я сказал в комментарии. Спасибо @sus. Я рекомендую его/ее путь с небольшим изменением для поддержки <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 always '</${tagName}>'. Correct?

    return outerHtml.slice(0, openTagLength);
}

Код в Typescript.Удалите типы (HTMLElement и number), если вы хотите чистый Javascript.

Ответ 5

Вот решение, которое я использовал:

const wrap = document.createElement('div')
wrap.appendChild(target.cloneNode(true))
const openingTag = wrap.innerHTML.split('>')[0] + '>'