【问题标题】:jquery/javascript remove HTML tags but no contentjquery/javascript 删除 HTML 标签但没有内容
【发布时间】:2012-11-12 18:54:13
【问题描述】:

我有以下代码,

$(document.getElementById('messages_message-wysiwyg-iframe').contentWindow.document).keydown(function() {
        var iFrame =  document.getElementById('messages_message-wysiwyg-iframe');
        var iFrameBody;
        if ( iFrame.contentDocument ) 
        { // FF
            iFrameBody = iFrame.contentDocument.getElementsByTagName('body')[0];
        }
        else if ( iFrame.contentWindow ) 
        { // IE
            iFrameBody = iFrame.contentWindow.document.getElementsByTagName('body')[0];
        }
            console.info(iFrameBody.innerHTML);
    });

如果获取 iframe 的内容,我想做什么,但删除所有不是的 html 标签,

b, strong, i, a, u, img

但是我不想删除任何文本,例如如果 iframe 中有以下内容,

<div class="box segment panel">
    <a href="http://www.google.com>hello world</a> 
    click this link and go far. 
    <img src="http://placehold.it/100x100" alt="Placeholder"/>
 </div>

返回的内容如下,

<a href="http://www.google.com">hello world</a>  
click this link and go far.
</a>
<img src="http://placehold.it/100x100" alt="Placeholder" />

这可能吗?

【问题讨论】:

  • 如果你使用 jQuery,那么使用 jQuery 而不是这种简单的 JS 和 jq 的疯狂组合。 $('#messages_message-wysiwyg-iframe') 而不是 document.getElementById(...) 等。

标签: javascript jquery regex


【解决方案1】:

这是我的纯 JS 解决方案:

function sanitize(el) {

    if (el.nodeType !== 1) return;

    if (!/^(B|STRONG|I|A|U|IMG)$/.test(el.tagName)) {
        var p = el.parentNode;

        // move all children out of the element, recursing as we go
        var c = el.firstChild;
        while (c) {
            var d = c.nextSibling;  // remember the next element
            p.insertBefore(c, el);
            sanitize(c);
            c = d;                  // look at the next sibling
        }

        // remove the element
        p.removeChild(el);
    }
}

http://jsfiddle.net/alnitak/WvJAx/ 上的演示

它的工作原理是(递归地)将受限标签的子节点移出其父节点,然后在它们为空时删除这些标签。

【讨论】:

  • 与 Bergi 的评论相同:这对于某些元素类型(如 table 或 ul)会中断。
  • @Christophe 怎么样?这些元素将被此代码删除,但它们的内部文本节点保持不变。
  • 啊 - 我明白了 - 你的意思是因为 &lt;li&gt; 可能会暂时移到包含 &lt;ul&gt; 的外部,这将是一个非法的 DOM。嗯……
  • 如果 el=table 你如何将头部、身体甚至 tr 移出元素?
  • @Christophe 这是一个棘手的问题 - 可能需要先从叶节点进行移动。我认为对我的代码稍作修改就可以实现这一点。
【解决方案2】:

使用正则表达式:

iFrameBody.innerHTML=iFrameBody.innerHTML.replace(/<[^(b|strong|i|a|u|img)]\b[^>]*>/gi,"").replace(/<\/[^(b|strong|i|a|u|img)]>/gi,"");

第一次替换删除开始标签,第二次删除结束标签。

请注意,有几个陷阱when using regex to match html。但在这种特定情况下,这似乎是一个合理的选择(参见我的 cmets 的其他答案)。

为了记录,这是我用来访问 iframe 的内容文档的:

var doc=ifr.contentWindow||ifr.contentDocument;
if (doc.document) doc=doc.document;

【讨论】:

    【解决方案3】:
    var iFrame = document.getElementById('messages_message-wysiwyg-iframe');
    var iFrameDoc = iFrame.contentDocument || iFrame.contentWindow.document;
    $(iFrameDoc).keydown(function() {
        var iFrameBody = $("body", iFrameDoc);
        var cleared = iFrameBody.clone();
        cleared.find("*:not(b,strong,i,a,u,img)").each(function() {
            var $this = $(this);
            $this.replaceWith($this.contents());
        });
        console.log(cleared.html());
    });
    

    Demo at jsfiddle.net

    【讨论】:

    • 认为如果它们嵌套在其他可接受的元素中,这将无法保留可接受的元素...
    • @Alnitak:是的,我需要一些时间来让它工作。但是现在,克隆体 in 中的每个不需要的元素都应该被其自己的子元素替换,而将需要的 html 留在正文中。
    • @Bergi 我希望这会破坏某些具有特定嵌套规则的元素类型(例如 table,ul)
    • 我仍然认为这行不通...它也非常低效,因为它会为每个不匹配的节点评估$this.contents,而简单的 DOM 操作方法会更有效.
    【解决方案4】:

    我认为您对如何描述您正在尝试做的事情有点困惑。当您谈论“文本”时,您指的是标签内的 innerHTML/text 节点。我认为,您真正想做的是获取所有特定内容和内容的结构,也就是 iFrame 的子元素。

    您可以使用 jQuery 的 .text() 方法单独获取每个元素的文本内容并在从 DOM 中删除实际标签之前保存它,如果您想说,获取跨度的文本内容但您没有'不希望 span 再出现在 DOM 中,或者您想将其放置在文档中的其他位置。

    var elemText = $('span#mySpan').text();
    $('span#mySpan').remove();
    

    对于您尝试基于示例 HTML 执行的操作,您可能需要查看 jQuery 的分离方法:http://api.jquery.com/detach/

    这将允许您存储返回的子元素,以便稍后附加到其他地方。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-22
      • 1970-01-01
      • 2013-12-07
      • 2016-02-03
      • 1970-01-01
      • 1970-01-01
      • 2014-03-14
      相关资源
      最近更新 更多