首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在普通字符串中用另一个HTML标记包装HTML标记

在普通字符串中用另一个HTML标记包装HTML标记
EN

Stack Overflow用户
提问于 2018-06-01 00:57:21
回答 2查看 474关注 0票数 0

我希望将一个HTML标记与另一个HTML标记包装在一个字符串中(所以不是DOM元素,而是一个普通字符串)。我创建了这个函数,但我想知道我是否可以在没有forEach循环的情况下一次性完成它。

这是工作函数:

代码语言:javascript
复制
function style(content) {
    var tempStyledContent = content;

    var imgMatches = tempStyledContent.match(/(<img.*?src=[\"'](.+?)[\"'].*?>)/g);

    imgMatches.forEach(function (imgMatch) {
        var imgTag = imgMatch;
        var imgSrc = imgMatch.match(/src\s*=\s*"(.+?)"/)[1];

        tempStyledContent = tempStyledContent.replace(imgTag,
            "<a href=\"" + imgSrc + "\" data-fancybox>" + imgTag + "</a>");
    });

    return tempStyledContent;
}

参数content是一个包含HTML代码的字符串。上面的函数输出与输入相同的html,但使用(fancybox) a标记将所有子img标记括起来。

所以像这样的输入字符串

代码语言:javascript
复制
"<div><img src='example.jpg'/></div>"

将输出

代码语言:javascript
复制
"<div><a href='example.jpg' data-fancybox><img src='example.jpg'/></a></div>"

有人能改进这一点吗?我对regex的了解太少,无法让它变得更好。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-06-01 03:20:33

使用正则表达式操作超文本标记语言是notoriously problematic。在DOM解析器中微不足道的更改可能很难为其创建健壮的正则表达式;当正则表达式失败时,它会静默地失败,这使得错误很容易遗漏。在正则表达式中工作时,您还必须小心处理标记中所有可能的变化,例如空格、属性顺序、引号样式、标记结束样式、与html相似但不希望修改的属性内容等。

正如在下面的注释线程中详细讨论的那样,如果有足够的时间和精力,当然可以在regex中处理所有这些事情;但这会导致复杂的、难以维护的regex --最重要的是,很难确保您的regex能够容纳所有可能的有效标记变体。DOM解析自动处理所有这些内容,并允许您直接处理结构化数据,而不必处理字符串表示中所有可能的变化。

因此,如果需要对HTML字符串进行重要更改,最好总是将HTML转换为真正的DOM树,使用标准DOM方法对其进行操作,然后(如果需要)将其转换回字符串。幸运的是,这样做不需要很多代码。下面是一个简单的普通JS演示:

代码语言:javascript
复制
var htmlToElement = function(html) {
  var template = document.createElement('template');
  template.innerHTML = html.trim();
  return template.content.firstChild;
};

var elementToHtml = function(el) {
  return el.outerHTML;
}

// Usage demo:
var string = "<div>This <b>is some</b> <i>html</i><img src='http://example.com'></div>";

var foo = htmlToElement(string);

// perform your DOM manipulation as needed on foo here. This would look much simpler if I wasn't so stubborn about avoiding jQuery these days, but here we are anyway:
foo.querySelectorAll('img').forEach(function(img) {
    var link = document.createElement('a');
    link.setAttribute('data-fancybox',true);
    link.setAttribute('href', img.getAttribute('src'));
    img.parentNode.insertBefore(link,img);
    link.appendChild(img);
});

// back to a string:
var bar = elementToHtml(foo);
console.log(bar);

票数 1
EN

Stack Overflow用户

发布于 2018-06-01 02:48:08

好吧,我可能会按照@DanielBeck的建议来做DOM操作。一旦knouckout完成绑定,我将使用$.wrap http://api.jquery.com/wrap/进行操作。我只是希望有一种不使用jquery的简单方法,所以如果有其他建议,请评论他们。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50629309

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档