Tinymce 图像自动包装在 <p> 标签中。 CSS 方法或文本编辑器黑客

Posted

技术标签:

【中文标题】Tinymce 图像自动包装在 <p> 标签中。 CSS 方法或文本编辑器黑客【英文标题】:Tinymce images auto-wrapped in <p> tag. CSS ways around or text editor hacks 【发布时间】:2011-08-14 18:23:03 【问题描述】:

你好, 我现在使用drupal或wordpress多次遇到这个问题,我的tinymce配置文件有点过于巧妙地抽象了。

问题是 tinymce 将我的 &lt;img&gt; 标签自动包装在 &lt;p&gt; 标签中。如果在 Wordpress 或 Drupal 中有解决此问题的方法,那就太棒了。

当我想做这样的事情时,我的问题就存在了

<style>
    img 
        float: left;
    
    p 
        float: right;
        margin-right: 20px;
        width: 400px;
    
 </style>

我希望我的代码看起来像这样

<img src="some_png.png" />
<p> Imagine a lot of lipsum text.</p>

但是tinymce会这样做

<p><img src="crap_im_wrapped_in_a_paragraph.png" /></p>
<p> Imagine a lot of lipsum text.</p>

我正在尝试将图像浮动到具有设定宽度的段落的左侧,而对图像本身没有宽度限制。 在这种情况下,图像的父级会得到一个宽度和一个浮点数。这不是我想要的。

很可能有一个简单而聪明的解决方法,但我仍然没有找到。如果没有必要,我宁愿不要破解我的配置文件。

1 警告... 存在此问题的唯一原因是因为我希望客户能够轻松地进行自己的编辑,所以 我不会让他们将图像包装在 &lt;div&gt; 而不是 &lt;p&gt; 中。在我看来,这对我的客户来说是不直观的,他们是所见即所得的实际用户

以前的解决方案 我一直在使用正则表达式来删除段落标签,但它总是有问题。我最终在其他地方添加了更多图像,然后我必须不断调整我的正则表达式以忽略它们。 502 错误比比皆是!

我的问题是(是)我可以在我的 CSS 中做什么来使段落中包含的图像执行我想要它执行的操作? 如果我不能我可以做些什么来使该段落消失?

-- 编辑-- 该解决方案需要与 IE7+ 和现代浏览器兼容。 :P

谢谢! 亚伦

【问题讨论】:

我知道tinyMCE.init.forced_root_block,但我不知道如何实现它,也不知道它是否会起作用。 废话,这是链接tinymce.moxiecode.com/wiki.php/Configuration:forced_root_block 【参考方案1】:

你用 tinyMCE.init 函数调用 tinyMCE,不是吗?

所以添加这个字符串:

forced_root_block : false,

您也可以更改 tiny_mce_src.js。查找

forced_root_block : 'p',

并将其更改为

forced_root_block : false,

附:不要伪造清除缓存。

【讨论】:

The TinyMCE Docs say:“如果您将此选项设置为 false,它将永远不会在输入时生成 P 标签,或者会自动生成 BR 元素,而 Shift+Enter 将生成 P。请注意,不使用 P 元素作为根块会严重削弱编辑器的功能。”也许这对某些人来说是可以的,但使用风险自负!【参考方案2】:

如果您不希望它包装图像标签,请在 Tinymce 源代码中查找名为“isBlock”的函数。有一个正则表达式白名单测试来确定一个元素是否是块元素。如果您需要将图像标签视为块元素,则将“IMG”添加到它查找的节点名称列表中。我只需要自己做这件事,目前仍在寻找负面影响,但它确实解决了眼前的问题。

编辑: 这或多或少是一个临时解决方案,如果您只需要停止图像标签的根级块包装,则有一个名为“forceRoots”的函数,您实际上需要在其中执行图像标签检查。我是通过修改这行代码来做到的:

if (nx.nodeType == 3 || (!t.dom.isBlock(nx) && nx.nodeType != 8)) 

看起来像这样:

if (nx.nodeType == 3 || (!t.dom.isBlock(nx) && nx.nodeType != 8) && nx.nodeName.toLowerCase() != "img") 

这对我来说很好地解决了这个问题。

【讨论】:

我很幸运不必再使用 TinyMCE,所以很遗憾我可能永远无法测试这些解决方案。答案投票最多。 要在 tinyMCE4 中应用此更改,请查找 blockElementsMap = createLookupTable('...') 并将 img 添加到块元素列表中。我还没有测试过副作用!【参考方案3】:

如果我们谈论的是 WordPress 网站,有一个烦人的过滤器会自动将一些元素包裹在内容中,并带有一个名为 wpautop

标签。它实际上是由 wordpress 在运行时处理的,而不是由 TinyMCE 处理的。

将此添加到模板或functions.php文件的顶部:

<?php remove_filter('the_content', 'wpautop'); ?>

来源:http://wordpress.org/support/topic/stop-wordpress-from-adding-p-tags-and-removing-line-break

【讨论】:

【参考方案4】:

在 Drupal 中,一种“klugey”的做法是使用 hook_nodeapi() 或 d7 等价物来显示节点,并使用正则表达式替换出现在开头的 p-wrapped 图像场。您必须通知您的客户,它们在编辑时看起来不正确,但在显示时,它们会正确显示。

如果您正在寻找 CSS 选项:

在 css2 中有 :first-child 选择器,在 css3 中还有 :only-child 选择器。 p:first-child img 可以与负边距一起使用,以抵消您为 p 元素声明的边距。不利的一面是,这也会对客户可能放在第一段中的任何图像施加相同的负边距。您打算覆盖的所有浏览器都可能不支持 css3,但如果您可以使用它 - 您可以将 :only-child 选择器用于作为 p 元素的唯一子元素的图像,用负边距抵消父 p 的边距。

【讨论】:

就像我上面提到的,我以前使用过旧的正则表达式技巧。这正是我想要避免的。我认为 :first-child 选择器没有得到支持。这似乎甚至可以与 IE7 一起使用。问题仍然是我很可能不会使用第一个孩子并且我还不愿意使用 CSS3 选择器。 +1 不过,谢谢 我不怪你想要避免 regex hack。我的猜测是 :first-child 可能对您的大多数网站访问者来说已经足够好了……尽管当第一段中存在文本时,它确实对第一段中包含的图像有缺点。祝你好运!【参考方案5】:

如果 javascript 是一个选项,那么您可以使用 jQuery 将 img 重新设置为 p 的兄弟。像这样的东西(未经测试)

$("p > img").each(function () 
  var $this = $(this);
  var $p= $this.parent();
  $p.before($this);
);

仅向您真正需要的段落/图像添加逻辑。

丑陋,是的,但作为最后手段的可行解决方案。

【讨论】:

我会写最后一行 $p.before($this).remove(); :O 是的,在您的情况下,这可能是可取的。不过,我不会在那个函数中这样做。更通用的解决方案是单独调用以删除所有空段落和仅由   组成的所有段落。 TinyMCE 经常发生这两种情况。【参考方案6】:

添加这一行:

theme_advanced_blockformats : "p,div,h1,h2,h3,h4,h5,h6,blockquote,dt,dd,code,samp"

当你想插入一个img选择div时:

<div>
    <img src="my_img.jpg>
</div>

无需使用 css 进行任何修改。

【讨论】:

【参考方案7】:

TinyMCE 4 将所有内容包装在块元素中。默认包装是 P。单击图像并选择另一个包装元素,如 DIV。要将 DIV 添加到菜单中,请将其添加到 functions.php

function make_mce_awesome( $init ) 
  $init['block_formats'] = "Paragraph=p; Heading 1=h1; Heading 3=h3; Heading 2=h2; Preformatted=pre; Media=div";
return $init;


add_filter('tiny_mce_before_init', __NAMESPACE__ . "\\make_mce_awesome");

【讨论】:

【参考方案8】:

有选项“valid_children”https://www.tiny.cloud/docs/configure/content-filtering/#valid_children。它控制您禁止 (-) 或允许 (+) img 标签包含哪些元素。

此示例适用于 - 不让 img 标签成为 p 和 h1-4 的孩子 - 让 img 标签成为 div 和 span 的子标签

tinymce.init(
valid_children : '-p[img],h1[img],h2[img],h3[img],h4[img],+div[img],span[img]'
);

【讨论】:

【参考方案9】:

我担心这是不可能的,因为img 是一个内联元素。 Tinymce 将用户输入的所有内容包装到块元素中(divs 或 p-tags),但 img 不是块元素。

【讨论】:

我以前读过它,这个另一个问题 (***.com/questions/2402761/…) 似乎暗示 img 标签是内联 块元素。但表现得更像内联元素。因此,tinymce 在所有情况下都不能正确包装图像。只是大多数情况。 我认为应该可以定义 tinymce 处理 img-tags 的方式。禁用forced_root_block可能会起作用 从我上面的评论中可以看出,我知道forced_root_block,但不知道如何在Wordpress 或Drupal 中实现它。你知道怎么做吗? 是的,看看这篇关于如何在 wordpress 中设置 tinymce 初始化参数的教程:lucidgreen.net/webbybooth/?p=11

以上是关于Tinymce 图像自动包装在 <p> 标签中。 CSS 方法或文本编辑器黑客的主要内容,如果未能解决你的问题,请参考以下文章

tinymce富文本编辑器

TinyMce:定制新行

TinyMce 不显示图标

在包装器中按图像自动隐藏自动高度和宽度

为啥 TinyMCE 显示 HTML 标签?

tinymce 将跨度插入列表标签