【问题标题】:Remove all HTML tags inside of selection in contenteditable删除 contenteditable 中选择内的所有 HTML 标记
【发布时间】:2012-12-02 12:30:54
【问题描述】:

我有一个<div />,即contenteditable,可以包含多种类型的HTML元素,例如<span /><a /><b /><u />等等。

现在,当我在contenteditable 中选择文本时,我希望有一个按钮来删除选择中的所有样式。

示例 1:

选择:

Hello <b>there</b>. I am <u>a selection</u>

会变成:

Hello there. I am a selection

示例 2:

选择:

<a href="#">I am a link</a>

会变成:

I am a link

你懂的……

我发现这个有用的功能https://stackoverflow.com/a/3997896/1503476 用自定义文本替换当前选择。但我只是无法先获取选择的内容,然后在替换之前去掉标签。我该怎么做?

【问题讨论】:

标签: javascript jquery wysiwyg contenteditable rangy


【解决方案1】:

我这样做的方法是遍历选择中的节点并删除内联节点(可能只留下 &lt;br&gt; 元素)。这是一个示例,为方便起见,使用我的 Rangy 库。它适用于所有主流浏览器(包括 IE 6),但并不完美:例如,它不会拆分部分选择的格式元素,这意味着完全删除了部分选择的格式元素,而不仅仅是选择的部分。解决这个问题会比较棘手。

演示:http://jsfiddle.net/fQCZT/4/

代码:

var getComputedDisplay = (typeof window.getComputedStyle != "undefined") ?
    function(el) {
        return window.getComputedStyle(el, null).display;
    } :
    function(el) {
        return el.currentStyle.display;
    };

function replaceWithOwnChildren(el) {
    var parent = el.parentNode;
    while (el.hasChildNodes()) {
        parent.insertBefore(el.firstChild, el);
    }
    parent.removeChild(el);
}


function removeSelectionFormatting() {
    var sel = rangy.getSelection();

    if (!sel.isCollapsed) {
        for (var i = 0, range; i < sel.rangeCount; ++i) {
            range = sel.getRangeAt(i);

            // Split partially selected nodes 
            range.splitBoundaries();

            // Get formatting elements. For this example, we'll count any
            // element with display: inline, except <br>s.
            var formattingEls = range.getNodes([1], function(el) {
                return el.tagName != "BR" && getComputedDisplay(el) == "inline";
            });

            // Remove the formatting elements
            for (var i = 0, el; el = formattingEls[i++]; ) {
                replaceWithOwnChildren(el);
            }
        }
    }
}
​

【讨论】:

  • 伙计,我也得到了 RANGY 插件的链接,但我不知道解决方案,但你竖起大拇指 :)
  • 在 Firefox 中,您可以通过在选择时按住 Ctrl 键来选择多段文本。您的脚本仅从 1st 选择中删除格式。
  • @user2428118:确实如此,但没有其他浏览器支持或可能支持,current spec 只讨论单个选择范围。因此,不久前,我不再费心处理 Stack Overflow 答案中的多范围情况;你是第一个抱怨的。我会更新我的答案。
【解决方案2】:

根据您建议的功能,在控制台中进行了一些实验后,我想出了这个简洁的小脚本。 虽然没有测试跨浏览器的兼容性

var selection = window.getSelection().getRangeAt(0);
var selectedText = selection.cloneContents().childNodes[0]; // This is your selected text.

现在,您可以从 selectedText 中去除 HTML 标记,并使用您在问题中提供的功能替换它。

例如,您可以使用来自the php.js projectstrip_tags()

我希望这能回答你的问题。

【讨论】:

  • 那行不通。我无法将strip_tags 函数应用于selectedText。它将返回TypeError: input.replace is not a function
  • 也许 strip_tags 函数不是您想要的,您可以将我的答案与@gulty 的答案结合起来。我假设您已经有了替换字符串的解决方案,使用您提供的链接中的答案:stackoverflow.com/a/3997896/1503476
【解决方案3】:

http://jsfiddle.net/tnyWD/

HTML:

<div class="test">
    Hello <b>there </b><a href="#">I am a link</a>
</div>
<button class="remove">Remove HTML</button>​

JS:

$(document).ready(function(){
    jQuery.fn.stripTags = function() { return this.replaceWith(this.html().replace(/<\/?[^>]+>/gi, '') ); };
$('.remove').click(function(){
    $('.test').stripTags();
});
});​

这就是你要找的吗?

【讨论】:

  • 我正在contenteditable div 中进行选择。所以我只需要将stripTags应用于选择!
【解决方案4】:

http://jsfiddle.net/fQCZT/2/

<div contenteditable="true">
    <p>
        Here is some <b>formatted text</b>. Please select some and watch the formatting
        <i>magically disappear</i>.
        <br>
        Look, some more <u>formatted</u> content.
    </p>
    <p>And <i>another</i> paragraph of it</p>
</div>
<button onmousedown="removeSelectionFormatting()">Change</button>​

它与上述答案之一重复,但带有一个更改文本的按钮!

【讨论】:

  • 我不想替换整个周围的div。我正在contenteditable div 内部进行选择...
  • 您想删除所选文本的标签吗?如果是,我编辑我的答案!
  • 是的,我想删除选择中的标签。
  • 给我一些我正在努力的时间!
猜你喜欢
  • 2011-01-15
  • 1970-01-01
  • 1970-01-01
  • 2011-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-16
  • 1970-01-01
相关资源
最近更新 更多