如何检测菜单何时在 tinymce 4 中呈现

How to detect when a menu is rendered in tinymce 4?

本文关键字:tinymce 何时 菜单 何检测 检测      更新时间:2023-09-26

tinymce 4中,菜单栏被渲染,但每个菜单仅在单击时呈现。

为了说明这一点,请注意菜单栏中的每个菜单都有 mce-menu 类。

在任何时候,如果没有打开菜单,如果您尝试获取菜单集,您将失败,因为它们尚未呈现:

var menuSet = $('.mce-menu');
// menuSet.length : 0

但是,如果您单击菜单栏标题,例如insert菜单,它将被呈现并打开。现在,保持打开状态,转到控制台并重试:

var menuSet = $('.mce-menu');
// menuSet.length : 1

你会得到打开的菜单。

现在,如果您关闭它,请单击打开的菜单中的任意位置,然后重试:

var menuSet = $('.mce-menu');
// menuSet.length : 1

。菜单不会从 DOM 中删除。这是一个好消息:由于菜单渲染过一次,我们可以获取并操作它。

我对每个.mce-menu元素都进行了一些 DOM 操作,但是我现在必须在第一次打开每个菜单时进行操作。

但是如何处理这样的事件呢?

我无法从官方文档、论坛或任何地方获得任何线索。

这绝对是可能的,但我们都不够了解 JS 事件的管理方式。

我尝试以旧方式对事件处理程序进行编码:

$('body').on('click', function() { 
    do_stuff();
});

虽然我必须以新的正确方式进行操作:

$('body').on('click', '.mce-btn', function() { 
    do_stuff();
});

这样,事件就可以得到正确管理。

尝试使用 onPostrender 功能:

editor.addMenuItem("mybtn", {
    type: "menuitem",
    name: 'mybtn',
    onPostRender:function (){
        // write your code here//
    },

我通过编写一个方便的"Tinymce 4"插件解决了这个问题,专注于此目的。

当然,这个插件是由GNU GPL v2许可证开源的,遵循原始的Tinymce许可政策。

Tinymce 插件菜单控制器:

https://github.com/sirap-group/tinymce-plugin-menuscontroller

但是我还没有写文档,我很抱歉。

但是,以下是使用它的方法:

安装插件

从github下载最新版本的tarball,或者更好的是从bower安装它:

bower install tinymce-plugin-menuscontroller

如果您不知道bower,请在此处发现:https://bower.io(npm i -g bower; bower --help)。

npm 包尚不可用,我很快就会提供(但欢迎 github 上的任何拉取请求......

默认情况下,插件文件夹将被下放并放置在 ./bower_components 中。如果您以相同的方式安装了 tinymce,那么您也有./bower_components/tinymce./bower_components/tinymce-dist

您无需将脚本添加到index.html文件中,因为如果设置正确,tinymce 会自行加载它。

所以你需要:

  1. 将其符号链接到 Tinymce 插件文件夹:

    $ cd ./bower_components/tinymce/plugins
    $ ln -s ../../tinymce-plugin-menuscontroller menuscontroller
    
  2. 将其加载到Tinymce init中。例如:

    tinymce.init({ 选择器:"文本区域", //[...] 插件:"菜单控制器"})

获取插件实例:

var editor = window.tinymce.activeEditor
var menusCtl = editor.plugins.menuscontroller
// at this point, if menusCtl is undefined, something gone wrong in the setup step: please check the previous steps.

插件接口 (v0.2.1)

实例方法

获取菜单栏:

menusCtl.getMenubar()

按注册时使用的名称获取每个菜单:

menusCtl.getMenuByName(String: name)

获取工具栏

menusCtl.getToolbars

事件

事件:menusController:mceMenuRendered事件

呈现任何 tinymce 菜单时

$('body').on('menusController:mceMenuRendered', function (evt, menuDomNode) {
  console.log(menuDomNode)
})

menusController:mceMenuRendered 事件在呈现时,对于活动编辑器菜单栏的每个菜单调用一个,因此当用户单击下拉菜单时("文件"菜单的File链接,Insert"插入"菜单等)。

事件: menusController:mceMenuItemRendered:<menuDomID>

呈现任何菜单项时。假设我们创建了一个具有my-custom-menu-item标识符的菜单项。所以 tinymce 将其 DOM ID 设置为 my-custom-menu-item 。因此,MenusController 插件将创建以下事件并将其绑定到正文:

menusController:mceMenuItemRendered:my-custom-menu-item

因此,您可以处理侦听它的自定义菜单项的呈现事件:

$('body').on('menusController:mceMenuItemRendered:my-custom-menu-item',
  function (evt, menuItemDomNode) {
    console.log(menuItemDomNode)
  }
)

菜单控制器 API (v0.3.0+)

A 皱纹的时间(2017 年 3 月 13 日,星期一),最后发布的版本是 v0.2.1 .但该v0.3.0计划很快发布,并将提供一个比上一个更有用的新事件。

事件: menusController:mceMenuItemRendered

当您需要知道菜单项 ID 来处理事件menusController:mceMenuItemRendered:<menuDomID>并获取菜单项 DOM Node 作为回调参数时,事件menusController:mceMenuItemRendered不需要它,而是为每个新呈现的菜单项提供它作为回调参数:

$('body').on('menusController:mceMenuItemRendered',
  function (evt, menuItemID) {
    console.log(menuItemID) // 'my-custom-menu-item'
    // So you can hanlde all menu item even if you don't know its ID
    // And you can also handle the DOM Node with the selector by ID
    var selector = '#' + menuItemID
    var menuItem = $(selector)
    console.log(menuItem) // jQuery object (the menu item)
  }
)

使用 tinymce,您可以通过编辑器对象完全自定义菜单按钮:

tinymce.init({
  /*....*/
  setup: function(editor) {
    editor.addButton('mybutton', {
      type: 'menubutton',
      text: 'My button',
      icon: false,
      onclick: function(){
        alert('Some Message');
      },
      menu: [{
        text: 'Menu item 1',
        onclick: function() {
          alert('Some Message');
        }
      }]
    });
  }
 /*....*/
});

不幸的是,您不能在文本属性中插入html,但我认为您可以通过更多的研究来做到这一点。您还可以在菜单按钮上为单击事件创建回调函数。

就个人而言,我将使用 tinymce 官方 api 来修改 dom,而不是进行其他一些事件驱动的 dom 操作。

你可以在这里找到更多一个很好的例子