使用fixed_toolbar_container和绝对位置时,TinyMce子菜单不会粘在工具栏上

时间:2014-12-10 10:27:43

标签: javascript css tinymce

我们想要更好地控制我们定位tinymce工具栏的位置和方式。我们发现这个选项fixed_toolbar_container为我们解决了很多问题,但却给我们带来了一个烦人的问题。文档说fixed_toolbar_container(http://www.tinymce.com/wiki.php/Configuration:fixed_toolbar_container)可以用来拥有一个固定的工具栏。但我们实际上想要使用它是绝对的,所以我们可以将它相对于它的容器定位。

我创建了一个JS小提琴来演示这个问题:http://jsfiddle.net/ronfmLym/2/。通过单击文本打开工具栏时,工具栏将定位为绝对。当您打开子菜单时(即通过单击"文件"),将打开一个子菜单。现在,当您开始滚动时,子菜单不会粘在工具栏上。这是因为这些子菜单得到了mce-fixed类,因为我们设置了fixed_toolbar_container属性。

<div class="element">
    <div class="toolbar-container"></div>
    <div class="content">
        <p>Text</p>
    </div>
</div>

当定位绝对和滚动时,有没有办法让子菜单粘在工具栏上?请记住,当工具栏离开屏幕时,我们将切换到固定位置。

我们认为我们可以通过使用下面的代码修改de子菜单的容器元素来修复它,并覆盖子菜单的顶部位置并使用css将定位器设置为绝对值。但这似乎弄乱了工具提示,并且没有重新计算&#34; left&#34;子菜单的css-property使位置仍处于关闭状态。

tinymce.ui.Control.prototype.getContainerElm = function() {
    return document.getElementById('toolbar-container');
};

我在stackoverflow上找到的唯一相应问题是这一个:TinyMCE push down submenus using fixed_toolbar_container,没有答案。

2 个答案:

答案 0 :(得分:3)

尝试将工具栏包装在div中,然后使用position:relative;尝试将其破解,但这次没有合作。

似乎工具栏实际上是在点击时计算其位置。因此,唯一的冲突是,如果打开的工具栏为position:absolute,然后更改为position:fixed,反之亦然。

您最好的[手动]下注是在更改工具栏位置的同时调用函数:

  1. 检测是否有任何菜单打开。
  2. 更改工具栏位置。
  3. 重新打开已打开的菜单。
  4. 懒惰(气馁)解决方法是在位置发生变化时关闭所有子菜单。这将修复布局,但需要用户再次单击才能恢复菜单。

    对不起,这不是一个银弹答案:(

答案 1 :(得分:0)

此答案遵循 Brian John的建议:

我正在使用此方法来放置任何打开的mce-floatpanel(这是打字稿,但转换为ES或您所需的任何东西都不太难。):

   positionTinyMceDropdowns() {
        // TODO: You'll need to replace all occurrences 
        // of this.mceWrapperElement with whatever is
        // wrapping your TinyMCE. If you have only a 
        // single instance, you can just replace it
        // with document
        const button = <HTMLElement> this.mceWrapperElement.getElementsByClassName('mce-opened').item(0);
        const items = document.getElementsByClassName('mce-floatpanel');

        let wrapperNode: HTMLElement;
        for (let i = 0; i < items.length; i++) {
            const currentItem = <HTMLElement> items.item(i);
            if (currentItem.style.display !== 'none') {
                wrapperNode = currentItem;
                break;
            }
        }

        if (!wrapperNode || !button) {
            return;
        }

        const styles = wrapperNode.style;
        styles.display = 'block';
        styles.position = 'absolute';

        const bodyRect = document.body.getBoundingClientRect();
        const buttonRect = button.getBoundingClientRect();

        // get absolute button position:
        let y   = buttonRect.top - bodyRect.top;
        y += 33; // toolbar line height;

        styles.top = `${Math.floor(y)}px`;
    }

我在其中需要调用的实例:

  • 在窗口上滚动(或者如果编辑器包裹在滚动容器中,则只要 滚动)
  • 关于调整窗口大小(或者如果编辑器包裹在无需调整窗口大小的情况下调整大小的容器中,那么只要该容器的大小被调整大小)

因此,这是有关angular最简单情况的示例(同样适用于您使用的js框架):

import { HostListener } from '@angular/core';

// ...

    @HostListener('window:resize', ['$event'])
    @HostListener('window:scroll', ['$event'])
    public onResize() {
        this.positionTinyMceDropdowns();
    }

有趣的是,在iOS设备(也许还有其他移动设备?)上,mce-floatpanel刚打开后甚至没有正确定位。所以我必须添加这个:

tinymceConfig.setup = (editor: TinyMceEditor) => {
    editor.on('init', () => {
        const panel = this.mceWrapperElement.querySelector('.mce-tinymce.mce-panel');
        if (panel) {
            panel.addEventListener('touchend', () => {
                this.positionTinyMceDropdowns();
            });
        }
    });
};