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

af7jpaap  于 2022-12-05  发布在  其他
关注(0)|答案(3)|浏览(483)

我们希望能更好地控制工具栏的位置和放置方式。我们发现fixed_toolbar_container这个选项解决了很多问题,但也带来了一个令人不快的问题。文档中说fixed_toolbar_container(http://www.tinymce.com/wiki.php/Configuration:fixed_toolbar_container)可以用来放置固定的工具栏。但我们实际上希望它是绝对的,这样我们就可以相对于它的容器来放置它。
我创建了一个JS Fiddle来演示这个问题: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>

有没有办法让子菜单在绝对定位和滚动时粘在工具栏上?请记住,当工具栏离开屏幕时,我们将切换到固定位置。
我们认为我们可以通过使用下面的代码修改子菜单的容器元素来修复它,覆盖子菜单的顶部位置,并使用css将定位器设置为绝对位置。但这似乎会弄乱工具提示,并且tinymce不会重新计算子菜单的“left”css属性,因此位置仍然关闭。

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

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

xytpbqjk

xytpbqjk1#

尝试将工具栏 Package 在div中,并使用position:relative;尝试将其组合在一起,但这次没有合作。
看起来工具栏实际上是在考虑它在点击时的位置。所以你唯一的冲突是如果打开的工具栏是position:absolute,然后更改为position:fixed,反之亦然。
最好的[手动]方法是在更改工具栏位置的同时调用一个函数:
1.检测是否打开了任何菜单。
1.变更工具列位置。
1.重新打开已打开的菜单。
懒惰的(不鼓励的)修复方法是在位置改变时关闭所有子菜单。这将修复布局,但需要用户再次单击以恢复菜单。
对不起,这不是一个银回答:(

aiazj4mn

aiazj4mn2#

此答案遵循 *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`;
    }

我发现需要调用它的示例:

  • 在窗口滚动时(或者如果编辑器被 Package 在滚动容器中,则每当 that 滚动时)
  • 在窗口调整大小时(或者如果编辑器被 Package 在一个容器中,该容器在调整大小时没有调整窗口大小,则每当 * 该容器 * 调整大小时)

下面是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();
            });
        }
    });
};
wsewodh2

wsewodh23#

我认为TinyMCE 6文档中对配置设置fixed_toolbar_container的解释很差,但当您正确配置它时,您会发现它比试图模拟position:sticky的默认配置工作得更好(特别是对于inline模式)。
实际上,您希望将fixed_toolbar_container设置为容器的CSS选择器字符串,通常类似于"#mycontainer"
之后,您可以使用容器元素的CSS属性移动容器元素,TinyMCE用户界面会很好地跟随它。(当然,这是典型的TinyMCE错误。例如,子菜单向右溢出, windows 非常窄。)
请注意,TinyMCE将使用position:absolute的元素定位在相对于fixed_toolbar_container容器的位置,如果您移动该容器,在某些情况下,您必须执行editor.dispatch("ResizeWindow")来触发TinyMCE重新计算绝对定位的元素。
请参阅在https://jsfiddle.net/8bndv26t/1/上使用position:sticky的自定义容器的演示。

相关问题