如何从字符串中删除具有属性的HTML标记?

时间:2016-09-04 23:04:38

标签: javascript php jquery html regex

我有一个像SO这样的问答网站。我还有一个textarea和一个预览(与SO完全相同)。我使用markdown库将一些符号转换为HTML标记。例如,JS库用**替换<b>。好的都好。

现在我需要转义具有属性的HTML标记。我可以通过像this这样的PHP来做到这一点:

<?php

$data = <<<DATA
<div>
    <p>These line shall stay</p>
    <p class="myclass">Remove this one</p>
    <p>But keep this</p>
    <div style="color: red">and this</div>
</div>
DATA;

$dom = new DOMDOcument();
$dom->loadHTML($data, LIBXML_HTML_NOIMPLIED);

$xpath = new DOMXPath($dom);

$lines_to_be_removed = $xpath->query("//*[count(@*)>0]");

foreach ($lines_to_be_removed as $line) {
    $line->parentNode->removeChild($line);
}

// just to check
echo $dom->saveHtml($dom->documentElement);
?>

我不确定上面的代码是最好的,但正如您所见(在小提琴中我已经链接)它按预期工作。我的意思是它删除至少有一个属性的节点。现在我需要通过JS (或jQuery) (我需要这个用于textarea预览模拟器)来做到这一点。无论如何我该怎么做?我需要正则表达式吗?

2 个答案:

答案 0 :(得分:2)

你可以这样做:

$('.myTextArea *').each(function(){
    if (this.attributes.length)
        $(this).remove();
});

JSFIDDLE

它不是最有效的,但如果它只是一个textarea预览它应该没问题。我建议尽可能少地运行它。据我所知,没有选择器(jQuery或其他)可以做到这一点......所以你必须让JS做的工作。

根据评论进行编辑:

要删除元素,只删除周围的标记,请执行以下操作:

$('.myTextArea *').each(function(){
    if (this.attributes.length)
        this.outerHTML = this.textContent;
});

JSFIDDLE

答案 1 :(得分:2)

JavaScript element.attributes属性返回标记属性及其值的实时NamedNodeMap。例如......

<强> HTML

<div class=".cls" id="id" title="divtitle">
    <!-- content ... -->
</div>

<强>的JavaScript

var div = document.getElementById('id');
var attr = div.attributes;

console.log(attr);
/* => 
NamedNodeMap [class="cls", id="id", title="divtitle"]
*/

这可用于过滤所选项目 - 例如,您的示例......

/* return an array from querySelectorAll */
var paras = Array.prototype.slice.call(
       document.querySelectorAll('div p')
);

/* loop through paras */
paras.forEach(function(p) {
    /* 'p' = each element in 'paras' */

    /* get attributes of 'p' */
    var attr = p.attributes;

    /* only check elements with attributes */
    if (attr.length != 0) {

        /* loop through attributes */
        Object.keys(attr).forEach(function(a) {
            /* apply conditional */
            if (attr[a].name === 'class' && attr[a].value === 'myclass' ||
                attr[a].name === 'style' && attr[a].value === 'color: red;') {

                /* remove element ('p') */
                p.parentElement.removeChild(p);
            }
        });
    }
});

因为NamedNodeMap是一种对象我使用Object.keys(obj)来返回一个键数组,然后循环它们以确定属性的.name.value属性

编辑:根据上述评论

如果您只想删除属性,那么您可以删除上面的条件,就像这样......

paras.forEach(function(p) {
    var attr = p.attributes;
    if (attr.length != 0) {
        Object.keys(attr).forEach(function(a) {
            p.removeAttribute(a);
        });
    }
});

请参阅: