我想从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()
不起作用,我无法转换它。
承认上面的例子不是很有意义,因为它们还复制了元素的不再唯一ID。但有什么简单的方法吗?非常感谢。
答案 0 :(得分:15)
对于未来的Google员工,有一种方法可以在没有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
。
答案 1 :(得分:4)
var wrapper = $('.class').clone().attr('id','').empty();
答案 2 :(得分:1)
这是我的解决方法:
opentag=elem.outerHTML.slice(0, elem.outerHTML.length-elem.innerHTML.length-elem.tagName.length-3);
我想,关闭标签的格式为:"</"+elem.tagName+">"
。
答案 3 :(得分:1)
这是我使用过的解决方案:
const wrap = document.createElement('div')
wrap.appendChild(target.cloneNode(true))
const openingTag = wrap.innerHTML.split('>')[0] + '>'
答案 4 :(得分:0)
不幸的是,@AaronGillion's answer并不可靠,就像我在a comment中所说的那样。感谢@sus。我建议对his/her way进行一些改动以支持<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);
}
代码在Typescript中。如果需要纯Javascript,则删除类型(HTMLElement
和number
)。
答案 5 :(得分:0)
这可以在没有任何String操作的情况下完成。
相反,您可以使用元素的内部构造,并从那里自己构建字符串:
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>
请注意,对于<img />
之类的自闭合元素,这会给您带来不必要且错误的结束标记。随意调整代码。
答案 6 :(得分:0)
如果某人没有使用jQuery。 。
elem.outerHTML
"<a href="#" class="class">
link text
</a>"
elem.cloneNode().outerHTML
"<a href="#" class="class"></a>"
如果您想保护2014年中之前发布的Firefox等安全,请使用cloneNode(false)避免获取内部内容。
参考:https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode
答案 7 :(得分:0)
+1 为上面的 cloneNode 答案
function getTagHTML(el, includeClosingTag=true , selfClosing = false) {
//return el.cloneNode(false).outerHTML;
if (el.attributes)
return `<${el.localName}` +
[...el.attributes].map(
attr => ` ${attr.name}="${attr.nodeValue.replace(/"/g, """)}"`
).join`` +
`${selfClosing ? "/" : ""}>` +
(!selfClosing && includeClosingTag ? `</${el.localName}>` : "");
else
return null;
}
document.body.querySelectorAll("*:not(script)").forEach(el=>{
console.log(getTagHTML(el));
console.log(getTagHTML(el,false));
console.log(getTagHTML(el,false,true))
});
<div id="ONE" class='CLASSNAMES' attr1='"string"'>
INNERHTML
</div>
<img id="TWO" src="https://svgshare.com/i/Uhq.svg"/>
答案 8 :(得分:0)
我的解决方案使用 Reg Exp 替换元素属性中所有可能的结束标记:
const outerHTML = div.outerHTML;
const content = outerHTML.slice(0, outerHTML.length - div.innerHTML.length);
const dummy = content.replace(/'.*?'|".*?"/g, x => 'x'.repeat(x.length));
return content.slice(0, 1 + dummy.indexOf('>'));