使用Javascript或jQuery清理所见即所得编辑器';s HTML输出

使用Javascript或jQuery清理所见即所得编辑器';s HTML输出,javascript,jquery,html,Javascript,Jquery,Html,我使用的CMS有一个非常恼人的WYSIWYG编辑器,名为Summernote。这个编辑器看起来很漂亮,实际上工作得很好,但是它输出的HTML非常糟糕,没有任何用于设置输出样式的配置选项。例如,这是带有下划线的粗体斜体文本: <span style="text-decoration: underline;"> <span style="font-style: italic;"> <span style="font-weight: bold;"&

我使用的CMS有一个非常恼人的WYSIWYG编辑器,名为Summernote。这个编辑器看起来很漂亮,实际上工作得很好,但是它输出的HTML非常糟糕,没有任何用于设置输出样式的配置选项。例如,这是带有下划线的粗体斜体文本:

<span style="text-decoration: underline;">
    <span style="font-style: italic;">
        <span style="font-weight: bold;">
            Help!! I'm being squashed by 3 heavy tags.
        </span>
    </span>
</span>
但是

1) 我甚至无法让
wrapInner()
自己工作()

2) 如果这实际上是可能的,无论是在物理上还是在效率上,请建议如何以及如何将它们链接在一起

3) 有时跨度顺序不同,具体取决于单击按钮的顺序

这是我拙劣的尝试失败:

var code = $('#summernote').code();
var newCode = $('<div></div>').append(code)
    .find('iframe').wrap('<div class="flexVideo"/>')
    .end()
    .find('img').removeAttr('style').wrap('<div class="flexPhoto"/>')
    .end()
    .find('span').filter(function() {
        return $(this).css('font-weight') == 'bold';
    })
    .wrapInner('<b></b>')
    .unwrap()
    .end()
    .html();
var code=$('#summernote').code();
var newCode=$('').append(代码)
.find('iframe').wrap('')
(完)
.find('img').removeAttr('style').wrap('')
(完)
.find('span').filter(函数(){
返回$(this.css('font-weight')=='bold';
})
.wrapInner(“”)
.unwrap()
(完)
.html();
看看这个失败的演示。没有错误,但它肯定没有按要求去做。我试过冲它大喊大叫,但没用

惊人的答案

对于那些沮丧的Summernote用户,您可能会发现这很有用。为什么它令人惊奇?好吧,虽然在这个例子中它被分成多行,但实际上这是一行

var newCode = $('<div></div>').append(code)
   .find('iframe')
       .wrap('<div class="flexVideo"/>')
   .end()
   .find('img')
       .removeAttr('style')
       .wrap('<div class="flexPhoto"/>')
   .end()
   .find('span')
       .filter("[style*='underline']")
           .removeAttr('style')
           .addClass('underline')
       .end()
       .filter("[style*='bold']")
           .wrapInner('<b></b>')
           .children()
               .unwrap()
           .end()
       .end()
       .filter("[style*='italic']")
           .wrapInner('<i></i>')
           .children()
               .unwrap()
           .end()
       .end()
   .end()
   .html();
var newCode=$('').append(代码)
.find('iframe'))
.wrap(“”)
(完)
.find('img'))
.removeAttr('style'))
.wrap(“”)
(完)
.find('span'))
.filter(“[style*='underline']”)
.removeAttr('style'))
.addClass(“下划线”)
(完)
.filter(“[style*='bold']”)
.wrapInner(“”)
.儿童()
.unwrap()
(完)
(完)
.filter(“[style*='italic']”)
.wrapInner(“”)
.儿童()
.unwrap()
(完)
(完)
(完)
.html();
它有什么作用?

  • 从限制响应的图像中删除内联样式
  • 将图像包装到DIV中(个人偏好使用按钮和文本覆盖图像)
  • 将iframe视频包装在DIV中,以实现响应能力
  • 将内联
    文本装饰:下划线
    替换为类
    下划线
  • 标记替换为正确的
    标记
  • 标记替换为正确的
    标记

您的选择器都乱七八糟,并且没有正确引用链中所需的元素

在本例中(出于诊断目的),我从末尾删除了.html(),并将新代码输出到console.log()命令中,我可以在fireBug中查询该命令

这表明筛选器选择器找不到匹配的元素。我更改了过滤器以使用不同的选择器。然后我意识到,你试图打开的元素是错误的,这是消除你的大部分标记。于是我走到匹配的大胆跨度的孩子面前,然后打开包装。然后我结束了链条

var code = '<span style="text-decoration: underline;"><span style="font-style: italic;"><span style="font-weight: bold;">asdasdad</span></span></span><br><br><img src="" style="width:748px;"><br><br><iframe src="" width="560" height="380"><iframe>';

var newCode = $('<div></div>').append(code)
    .find('iframe')
        .wrap('<div class="flexVideo"/>')
    .end()
    .find('img')
        .removeAttr('style')
        .wrap('<div class="flexPhoto"/>')
    .end()
    .find('span')
        .filter("[style*='bold']")
            .wrapInner('<strong></strong>')
            .children()
                .unwrap()
            .end()    
        .end()   
    .end()
    .html();

$('.output').text(newCode);
var code='asdasdad




'; var newCode=$('').append(代码) .find('iframe')) .wrap(“”) (完) .find('img')) .removeAttr('style')) .wrap(“”) (完) .find('span')) .filter(“[style*='bold']”) .wrapInner(“”) .儿童() .unwrap() (完) (完) (完) .html(); $('.output').text(新代码);
查看此更新的小提琴以了解详细信息:

在您的示例中,
.unwrap()
将打开
span
元素,而您需要打开新创建的
。基本思路如下:

更改后的html包含两个
范围,而不是三个

我决定从头开始写:)

为了深入研究覆盖范围,我们需要检查所谓的“第一级”范围,并将其更改为相应的html元素(我个人不喜欢,因为html标记有其语义,使用wysiwyg的标记可能不清楚),但这是另一个要讨论的主题。我还搜索子
跨度
,并删除它们的
样式
属性

无论如何,我设法实际更改了您的代码以获得所需的效果。你可以在这里找到:

最终的结果不是100%好,但这只是一个开始,希望你会发现它有用

编辑: 为了让东西更干爽一点,我修改了我原来的版本并更新了小提琴。

$('.wysiwyg')。每个(函数(){
var$wysiwyg=$(此),
$directspan=$wysiwyg.children('span');
//首先让我们创建顶级元素
$directSpans.each(函数(){
变量$span=$(此),
$innerSpans=$span.find('span'),
元素=“”;
开关($span.attr('style')){
大小写“字体大小:粗体;”:
元素='强';
打破
大小写“字体样式:斜体;”:
元素='em';
打破
案例“文本装饰:下划线;”:
元素='u';
打破
}
$span.wrapInner(“”).find(元素).unwrap();
$innerSpans.each(函数(){
var innerSpan=$(此),
innerStyle=innerSpan.attr('style'),
类名=“”;
开关(内部样式){
大小写“字体大小:粗体;”:
className='bold';
打破
大小写“字体样式:斜体;”:
className='italic';
打破
案例“文本装饰:下划线;”:
className='underline';
打破
}
$('span').filter(function() {
     return $(this).css('font-weight') == 'bold';
}).wrapInner('<b></b>').unwrap()
var code = $('#summernote').code();
var newCode = $('<div></div>').append(code)
    .find('iframe').wrap('<div class="flexVideo"/>')
    .end()
    .find('img').removeAttr('style').wrap('<div class="flexPhoto"/>')
    .end()
    .find('span').filter(function() {
        return $(this).css('font-weight') == 'bold';
    })
    .wrapInner('<b></b>')
    .unwrap()
    .end()
    .html();
var newCode = $('<div></div>').append(code)
   .find('iframe')
       .wrap('<div class="flexVideo"/>')
   .end()
   .find('img')
       .removeAttr('style')
       .wrap('<div class="flexPhoto"/>')
   .end()
   .find('span')
       .filter("[style*='underline']")
           .removeAttr('style')
           .addClass('underline')
       .end()
       .filter("[style*='bold']")
           .wrapInner('<b></b>')
           .children()
               .unwrap()
           .end()
       .end()
       .filter("[style*='italic']")
           .wrapInner('<i></i>')
           .children()
               .unwrap()
           .end()
       .end()
   .end()
   .html();
var code = '<span style="text-decoration: underline;"><span style="font-style: italic;"><span style="font-weight: bold;">asdasdad</span></span></span><br><br><img src="" style="width:748px;"><br><br><iframe src="" width="560" height="380"><iframe>';

var newCode = $('<div></div>').append(code)
    .find('iframe')
        .wrap('<div class="flexVideo"/>')
    .end()
    .find('img')
        .removeAttr('style')
        .wrap('<div class="flexPhoto"/>')
    .end()
    .find('span')
        .filter("[style*='bold']")
            .wrapInner('<strong></strong>')
            .children()
                .unwrap()
            .end()    
        .end()   
    .end()
    .html();

$('.output').text(newCode);
$('.wysiwyg').each(function(){
    var $wysiwyg = $(this),
        $directSpans = $wysiwyg.children('span');

    //first lets create top-level elements
    $directSpans.each(function(){
        var $span = $(this),
            $innerSpans = $span.find('span'),
            element = '';

        switch( $span.attr('style') ) {
            case 'font-weight: bold;':
                element = 'strong';
                break;
            case 'font-style: italic;':
                element = 'em';
                break;
            case 'text-decoration: underline;':
                element = 'u';
                break;
        }

        $span.wrapInner('<' + element + ' />').find(element).unwrap();

        $innerSpans.each(function(){
            var innerSpan = $(this),
                innerStyle = innerSpan.attr('style'),
                className = '';

            switch( innerStyle ) {
                case 'font-weight: bold;':
                    className = 'bold';
                    break;
                case 'font-style: italic;':
                    className = 'italic';
                    break;
                case 'text-decoration: underline;':
                    className = 'underline';
                    break;
            }
            innerSpan.removeAttr('style').parent().addClass(className);
        });

    });

});