如何自动调整tinyMCE的大小?

35

我有一个TinyMCE编辑器,它设置在TextArea上,我希望这个编辑区始终占据其父div的所有空间。

我有一个JS函数,可以获取当前空间并将textarea.style.height设置为它,但是当我启用TinyMCE时,它似乎停止工作。

此外,TextArea的宽度为100%; 当使用TinyMCE时,它不会通过HTML渲染进行调整大小。

有什么想法吗?

12个回答

55

现在,你应该使用tinyMCE自带的autoresize插件。你需要像这样调用tinyMCE(jQuery版本):

$('.tinymce').tinymce({
  theme : 'advanced',
  plugins : 'autoresize',
  width: '100%',
  height: 400,
  autoresize_min_height: 400,
  autoresize_max_height: 800,
});

我有这样的经验,手动在 init_instance_callback 函数中调用 resize 可以帮助提供正确的初始高度。如果你需要这个功能,请将该参数添加到传递的选项中:

init_instance_callback: function (inst) { inst.execCommand('mceAutoResize'); }

2
autoresize_min_heightautoresize_max_height现已弃用,请改用min_heightmax_height - jla

14

重点在于TinyMCE会在textarea的位置生成一个iframe,该iframe的ID为:originalID+"_ifr",同时生成一个table用于容纳控件和编辑区域,其ID为:originalID+"_tbl"。

使宽度自适应的方法:

document.getElementById(id+'_tbl').style.width='100%'

让高度自适应:

通过JS动态更改document.getElementById(id+'_ifr').style.height为所需高度。
这是我用的脚本:

function toScreenHeight(id, minus) {
    var height;

    if (typeof(window.innerHeight) == "number") //non-IE
        height = window.innerHeight;
    else if (document.documentElement && document.documentElement.clientHeight) //IE 6+ strict mode
        height = document.documentElement.clientHeight;
    else if (document.body && document.body.clientHeight) //IE 4 compatible / IE quirks mode
        height = document.body.clientHeight;

    document.getElementById(id).style.height = (height - minus) + "px";
}

你可以在 onloadonresizebody 事件中使用代码和函数调用。


1
谢谢。这很有帮助。您应该更改“使高度流动”的第一行下的样式声明为“document.getElementById(id+'_tbl').style.height”,我相信这就是您想要的。 - Joel Anair
我遇到了同样的问题,我有一个窗口调整大小的监听器,动态设置TinyMCE编辑器的宽度,但是这个方法连同100%一起停止工作了。这个组件的自动宽度似乎有点脆弱..? - danjah

10

在 TinyMCE 3.4.6 中,设置

width:'100%'

在init选项中解决问题。


这有点显而易见,正如你可以从我自己的回答中看到的那样。最大的问题是高度。 - igorsantos07

4

如果您正在通过JS动态使用Tiny MCE,可能会遇到MCE编辑器尚未可用于样式调整的时间问题。为了解决这个问题,您可以使用旧式超时。

在此示例中,我正在使用“j”命名空间来代表JQuery。如果您的编辑器位于大小会发生变化的流体div中,则可能需要将其包含在$(window).resize(function() { });侦听器中。

setTimeout(function(){ 
  $j('.mceEditor').css('width','100%').css('minHeight','240px');
  $j('.mceLayout').css('width','100%').css('minHeight','240px');
  $j('.mceIframeContainer').css('width','100%').css('minHeight','240px');
  $j('#'+[INSERT TEXTAREA ID HERE]+'_ifr').css('width','100%').css('minHeight','240px');
},500) 

2
我不知道为什么人们会对这个答案投反对票。这是唯一一个与jQuery相关的有意义的答案。它简洁、智能而且实际有效。我很遗憾不能为此投+10票。这个两年前的答案仍然非常有效。将其与init_instance_callback:“[function_name]”选项结合在tinymce init部分中。 - C-TZ
1
同意,在撰写本文时已经投票回到零。好心的人会花时间回答这些问题,如果它被踩,难道不应该有人解释一下原因吗? - RichM
我不得不再进一步添加 if(var==null){setTimeout...},但仍然简单且有效。 - Michał Kluczka
谢谢。这是相当老的问题,但在当时,TinyMCE与动态JS不兼容。我相信对于那些使用最新和最棒的MCE的人来说,有更好的答案。 - Noel Baron

3

以上方法在TinyMCE v4中都无法正常工作,所以我的解决方案是根据工具栏/菜单栏/状态栏来计算高度,并在设置编辑器的高度时考虑这些高度。

function resizeEditor(myHeight) {
    window.console.log('resizeEditor');
    myEditor = getEditor();
    if (myEditor) {
        try {
            if (!myHeight) {            
                var targetHeight = window.innerHeight; // Change this to the height of your wrapper element
                var mce_bars_height = 0;
                $('.mce-toolbar, .mce-statusbar, .mce-menubar').each(function(){
                    mce_bars_height += $(this).height();
                });
                window.console.log('mce bars height total: '+mce_bars_height);                          
                myHeight = targetHeight - mce_bars_height - 8;  // the extra 8 is for margin added between the toolbars
            }
            window.console.log('resizeEditor: ', myHeight);
            myEditor.theme.resizeTo('100%', myHeight);  // sets the dimensions of the editable area
        }
        catch (err) {
        }
    }
}

在我的情况下,我希望编辑器窗口的宽度和高度与实际窗口匹配,因为编辑器将出现在弹出窗口中。为了检测更改并调整大小,我将其设置为回调函数:

window.onresize = function() {
    resizeEditor();
}

1
我猜 $('.mce-toolbar, .mce-statusbar, .mce-menubar') 只有在你只有一个 tinyMceEditor 的时候才能正常工作。 - Sebastian

2

在版本4中,浏览器提供了使用flexbox布局的选项。为了获得父级div的完整宽度和高度编辑体验,我采用了以下方法:

父级div{
  display: flex;
  flex-direction: column;
  width: 100vw;
  height: 100vh;
}

如果您喜欢将CSS添加到现有样式中,可以将其放入文件中。

var css = '.tinycme-full .mce-edit-area {display:flex;flex-flow:column;} .tinycme-full .mce-edit-area iframe {flex:1 1 auto;}  .tinycme-full {height:100%;} .tinycme-full .mce-tinymce.mce-container { width:100%;height:100%;border:0; } .tinycme-full .mce-panel{border:0} .tinycme-full .mce-container-body.mce-stack-layout {display: flex; flex-flow: column;height: 100%;} .tinycme-full .mce-stack-layout-item{  flex: 0 0 auto;} .tinycme-full .mce-edit-area{flex:1 1 auto;} ',
    head = document.head || document.getElementsByTagName('head')[0],
    style = document.createElement('style');

style.type = 'text/css';
if (style.styleSheet) {
    style.styleSheet["cssText"] = css;
} else {
    style.appendChild(document.createTextNode(css));
}

head.appendChild(style);

这个想法是让所有必需的div占据尽可能多的列空间,以填满父级100%,这是通过在文本区域周围放置一个div来实现的:<div class="tinycme-full"> <textarea ... /></div>。不需要jquery或其他依赖项,它现在可以填充父级100%。 enter image description here

功能正常,但它会裁剪掉底部的状态栏。 - gremwell
它对我来说很好用。状态栏正确显示。 - Sergey

1
SyCoDeR是正确的,但我走了一个稍微不同的路径,虽然可能达到了相同的结果。
/*Container, container body, iframe*/
.mce-tinymce, .mce-container-body, #code_ifr {
    min-height: 100% !important;
}
/*Container body*/
.mce-container-body {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
}
/*Editing area*/
.mce-container-body .mce-edit-area {
    position: absolute;
    top: 69px;
    bottom: 37px;
    left: 0;
    right: 0;
}
/*Footer*/
.mce-tinymce .mce-statusbar {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
}

由于TinyMCE添加或删除菜单/工具栏时会更改id,因此进行了修订。无论您对其进行何种操作,它都有效。


1

我遇到了同样的问题,在阅读了这个帖子之后,我最终使用了这段代码

init_instance_callback: function (inst) { 
  setTimeout(function () {
    document.getElementById(inst.id + '_ifr').style.height= (document.getElementById("theContainerDiv").offsetHeight-85) + 'px';
   },1000);
},

我调整了“_ifm”元素的大小,而不是“_tbl”,因为调整“_tbl”并未使编辑区域的大小发生变化。然后我通过将“_ifr”比容器div短85像素来留出工具栏和状态栏的空间。

我不得不使用setTimeout让它生效,可能是因为我有一个显示容器元素的动画。


1

我正在使用纯CSS解决方案实现此操作(tinyMCE 4.0.20)。

  1. 将iframe高度设置为100%:

    tinymce.init({ height: '100%' })

  2. 添加样式以自动调整iframe容器大小:

    .mce-tinymce { height: auto; width: 100%; position: absolute; left: 0; top: 0; bottom: 0; }

    .bq-editor .mce-container-body { height: 100%; }

    .bq-editor .mce-edit-area { position: absolute; top: 57px; bottom: 0; width: 100%; height: auto; }

注意:我只有一行工具栏,.bq-editor .mce-edit-area中的top: 57px;是工具栏填充。


1
这是一个老问题,但显然它仍然在现今(2020年下半年)引起了很多关注。
可悲的是,随着TinyMCE v5的发布,我发现大部分我找到的解决方法都不再起作用。我相信它们曾经有效,但每次TinyMCE发布似乎都会带来新的“限制”,使这些解决方法无法使用...
不想让这成为一场讨论,我认为这是进化的代价。对于像TinyMCE这样的老产品来说,它仍然存在并保持领先地位,这真是令人难以置信。它是迄今为止所有环境中最高效、最灵活的解决方案之一,包括移动设备和那些新的语言和框架(似乎最近有这种趋势,每天都有新的出现)。
因此,在我的思考中,经过多次(失败的)尝试,我决定深入研究源代码(TinyMCE v5.4)以更好地理解它。我发现整个产品要优秀得多,并且每个人一直在寻找的解决方案比我预期的要简单得多。
没有更多的拖延,这是我的解决方案,简单有效。它实现了一个编辑器,可以使用整个文档区域(或任何您想要的区域),它将随着浏览器的大小调整而自动适应,无需脚本、无需黑客和无需诡计,这可能会导致跨浏览问题。下面是具体步骤:
  1. 给你的 <html><body> DOM 对象添加缺失的尺寸属性,并根据您的需要调整间距:
html, body {
   width    : 100%;
   height   : 100%;
   margin   : 0 !important;
   padding  : 0 !important;
   overflow : hidden;  /* Required if you want to have the editor taking the entire page. */
                       /* Otherwise, set as you need it. */
}
  1. TinyMCE建议将<textarea>嵌入<form>对象中。无论您是否按照建议使用它,只需为其提供ID和以下CSS属性(在我的情况下,它被设置为<form method="post" id="editorBase">):
#editorBase {
   display : block !important;
   width   : 100%  !important;
   height  : 100%  !important;
}
  1. TinyMCE初始化方法中,添加或修改以下设置:
tinymce.init({
   // Required Settings:
   width  : '100%',  // Note value is set as "string".
   height : '100%',  // Note value is set as "string".
   resize : false,   // Suggestion: disable the statusbar resizing. :)
   
   // Suggested Settings:
   toolbar_sticky   : true,       // Keep the menu and tollbar in a fixed position .
   toolbar_location : 'top',      // You can try 'top', 'bottom' or 'auto'.
   toolbar_mode     : 'floating', // It is simply a button behavior settings. 
                                  // Options are: 'floating', 'sliding', 'scrolling', or 'wrap'.  
});
  1. 然而,在TinyMCE Init设置中,找到plugins选项,并删除其中的autoresize选项(这是最重要的步骤!)。

  2. 完成!尝试并测试它!(是的!全部完成了!)

通过这些简单的调整,您可以将编辑器设置为适应任何设计。随意根据需要进行调整。只需不要忘记在TinyMCE Init设置中将widthheight属性设置为字符串,并与<form>的CSS设置保持一致。

TinyMCE Init设置中使用widthheight属性中的字符串而不是数字值的原因是允许您使用“%”、“em”、“pt”等单位。否则,所提供的解决方案将永远无法实现。

让它更整洁的另一个技巧是将编辑器设置为无边框皮肤(仅在 TinyMCE 的“专业版”中提供)。不,这不是一种黑客行为,它只是对 CSS 进行简单调整,完全符合 TinyMCE 的 EULA 和许可条款。只需将以下 CSS 添加到您页面的样式表中,就可以免费享受无边框编辑器:

.tox-tinymce { border:none !important; }

这没有比那更容易的了。
编码愉快!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接