我使用的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>
图像具有内联CSS样式,使图像具有固定的宽度,这对于响应式网站来说是无用的:
<img src="..." style="width:832px;">
YouTube iFrame的固定尺寸可以从手机屏幕上移开:
<iframe src="..." width="560" height="380">
所以,正如你所看到的,它不是很好,但我没有选择更改编辑器(不允许),我需要想出一种纠正这些问题的方法在HTML保存在数据库之前。就我而言,使用jQuery。
因此,经过一些试验和错误后,我已设法通过这个小片段修复了响应式问题:
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()
.html();
正如您所看到的,这将所有iFrame包装在响应包装器中,将所有图像包装在另一个包装器中(用于非响应目的)并从图像中删除所有内联样式,使其更加流畅。这很有效,但我在最后一部分真的很挣扎;用适当的元素替换所有这些span标签,不幸的是我需要寻求帮助。
我知道使用这样的内容可以为BOLD选择SPAN元素并使用wrapInner()
和unwrap()
我可以用适当的文本元素替换spans:
$('span').filter(function() {
return $(this).css('font-weight') == 'bold';
}).wrapInner('<b></b>').unwrap()
BUT
1)我甚至无法让wrapInner()
使用它自己(check this fiddle)。
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();
查看此失败的JSFIDDLE演示。没有任何错误,但它肯定没有按照它所说的那样做。我曾试着大喊大叫,但那不起作用。
令人惊叹的答案
对于所有受挫的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();
它做了什么?
text-decoration:underline
替换内联underline
。<span style="font-style:italic">
标记替换<i>
个标记。<span style="font-weight:bold">
标记替换<b>
个标记。答案 0 :(得分:2)
您的选择器都混乱,并且您没有正确引用链中所需的元素。
在这个例子中(出于诊断目的)我从末尾删除了.html()并将newCode输出到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);
有关详细信息,请参阅此更新的小提琴:http://jsfiddle.net/P2Ry8/6/
答案 1 :(得分:0)
您的案例中的.unwrap()
会解包span
元素,而您需要解包新创建的<strong>
。基本想法可以在这里看到:http://jsfiddle.net/skip405/DLuD4/
更改的html包含两个spans
而不是三个。
我决定从头开始写:)
要钻进覆盖范围,我们需要检查所谓的&#34;第一级&#34;跨越并将它们更改为相应的html元素(我个人不喜欢,因为html标签具有它们的语义,对于使用wysiwyg的人来说可能不太清楚),但那是另一个讨论的话题。我还会搜索孩子spans
并删除他们的style
属性。
无论如何,我设法改变你的代码以获得理想的效果。你可以在这里找到:http://jsfiddle.net/skip405/DLuD4/2/
最终结果不是100%更好,但这是一个开始,希望你会发现它有用。
修改强> 为了让事情有点干,我修改了我的原始版本并更新了小提琴。 http://jsfiddle.net/skip405/DLuD4/4/
$('.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);
});
});
});