将 html 内容分解为单独的更高级别 html 标签并将它们存储在数组中
Break html content into separate higher level html tags and store them in array
我正在尝试弄清楚如何实现以下目标。
假设我有一个像这样的字符串
"<h1>My heading</h1> <p><ul><li>Some item</li></ul> Some paragraph text</p> <p>Another paragraph text in <b>bold</b></p>"
我需要用更高级别的标签拆分这个字符串并将它们放入数组中,例如:
[
"<h1>My heading</h1>",
"<p><ul><li>Some item</li></ul> Some paragraph text</p>",
"<p>Another paragraph text in <b>bold</b></p>"
]
注意嵌套标签是如何分开的。此外,我不知道哪些标签可以处于更高级别,因此在这种情况下,不是 h1
和 p
,而是其他任何东西。
您可以将字符串转换为 DOM 元素,循环和拆分,然后重新转换为字符串(但不确定这是否是最佳方式):
var str = "<h1>My heading</h1> <div><ul><li>Some item</li></ul> Some paragraph text</div> <p>Another paragraph text in <b>bold</b></p>";
var arr = [];
var dom = document.createElement('div');
// Convert your string
dom.innerHTML = str;
// Loop through the dom structure and push only direct children into the array
for (var key in dom.childNodes) {
if (dom.childNodes[key].nodeType !== 3 && dom.childNodes[key].parentElement === dom) {
arr.push(dom.childNodes[key]);
}
}
// Traverse the array and re-convert the dom elements into strings
arr = arr.map(function(el){
var wrap = document.createElement('div');
wrap.appendChild(el);
return wrap.innerHTML;
});
console.log(arr);
注意:你是确切的例子是行不通的,因为你不能在 html.
中的 p 元素中包含 ul 元素
您可以这样做以避免使用 jQuery 或 DOM 元素。
htmlToPhrases('hello <p>my name is <span>Roman</span></p><span>!</span>');
它会 return
[
"hello ",
"<p>my name is <span>Roman</span></p>",
"<span>!</span>"
]
代码
function htmlToPhrases(text) {
let acc = [];
while (text) {
if (text[0] !== '<') {
const nextOpenTag = text.indexOf('<');
if (nextOpenTag === -1) {
acc.push(text);
} else {
acc.push(text.substr(0, nextOpenTag));
}
} else {
acc.push(_getFirstTag(text));
}
text = text.substr(acc[acc.length - 1].length);
}
return acc;
}
function _getFirstTag(text, acc = '', level = 0) {
const afterOpenChar = text.indexOf('<') + 1;
const nextTag = text[afterOpenChar];
level += nextTag === '/' ? -1 : 1;
acc += text.substr(0, afterOpenChar);
text = text.substr(afterOpenChar);
if (level === 0) return acc + text.substr(0, text.indexOf('>') + 1);
return _getFirstTag(text, acc, level);
}
我正在尝试弄清楚如何实现以下目标。
假设我有一个像这样的字符串
"<h1>My heading</h1> <p><ul><li>Some item</li></ul> Some paragraph text</p> <p>Another paragraph text in <b>bold</b></p>"
我需要用更高级别的标签拆分这个字符串并将它们放入数组中,例如:
[
"<h1>My heading</h1>",
"<p><ul><li>Some item</li></ul> Some paragraph text</p>",
"<p>Another paragraph text in <b>bold</b></p>"
]
注意嵌套标签是如何分开的。此外,我不知道哪些标签可以处于更高级别,因此在这种情况下,不是 h1
和 p
,而是其他任何东西。
您可以将字符串转换为 DOM 元素,循环和拆分,然后重新转换为字符串(但不确定这是否是最佳方式):
var str = "<h1>My heading</h1> <div><ul><li>Some item</li></ul> Some paragraph text</div> <p>Another paragraph text in <b>bold</b></p>";
var arr = [];
var dom = document.createElement('div');
// Convert your string
dom.innerHTML = str;
// Loop through the dom structure and push only direct children into the array
for (var key in dom.childNodes) {
if (dom.childNodes[key].nodeType !== 3 && dom.childNodes[key].parentElement === dom) {
arr.push(dom.childNodes[key]);
}
}
// Traverse the array and re-convert the dom elements into strings
arr = arr.map(function(el){
var wrap = document.createElement('div');
wrap.appendChild(el);
return wrap.innerHTML;
});
console.log(arr);
注意:你是确切的例子是行不通的,因为你不能在 html.
中的 p 元素中包含 ul 元素您可以这样做以避免使用 jQuery 或 DOM 元素。
htmlToPhrases('hello <p>my name is <span>Roman</span></p><span>!</span>');
它会 return
[
"hello ",
"<p>my name is <span>Roman</span></p>",
"<span>!</span>"
]
代码
function htmlToPhrases(text) {
let acc = [];
while (text) {
if (text[0] !== '<') {
const nextOpenTag = text.indexOf('<');
if (nextOpenTag === -1) {
acc.push(text);
} else {
acc.push(text.substr(0, nextOpenTag));
}
} else {
acc.push(_getFirstTag(text));
}
text = text.substr(acc[acc.length - 1].length);
}
return acc;
}
function _getFirstTag(text, acc = '', level = 0) {
const afterOpenChar = text.indexOf('<') + 1;
const nextTag = text[afterOpenChar];
level += nextTag === '/' ? -1 : 1;
acc += text.substr(0, afterOpenChar);
text = text.substr(afterOpenChar);
if (level === 0) return acc + text.substr(0, text.indexOf('>') + 1);
return _getFirstTag(text, acc, level);
}