javascript TinyMCE:事件初始化后如何绑定

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18514994/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 12:14:15  来源:igfitidea点击:

TinyMCE: How bind on event after its initialized

javascripteventscallbacktinymcehandler

提问by diosney

I already searched a lot but by google-fu'ing don't get me any results :(

我已经搜索了很多,但是通过google-fu'ing 没有给我任何结果:(

I have an already initialized tinyMCEeditor which initialization process I cannot control, so code like the following don't work at all:

我有一个已经初始化的tinyMCE编辑器,我无法控制它的初始化过程,所以像下面这样的代码根本不起作用:

tinyMCE.init({
   ...
   setup : function(ed) {
          ed.onChange.add(function(ed, l) {
                  console.debug('Editor contents was modified. Contents: ' + l.content);
          });
   }
});

Code like the following doesn't work either since the jQuery tinymce plugin isn't defined:

由于未定义 jQuery tinymce 插件,以下代码也不起作用:

$('textarea').tinymce({
    setup: function(ed) {
        ed.onClick.add(function(ed, e) {
            alert('Editor was clicked: ' + e.target.nodeName);
        });
    }
});

I mean, it has to be using the tinymce.somethingsyntax.

我的意思是,它必须使用tinymce.something语法。

How can I bind a callback function to whatever tinyMCE event after tinyMCE is already initialized?

在 tinyMCE 已经初始化之后,如何将回调函数绑定到任何 tinyMCE 事件?

回答by Luci

Although this post is old now but I think other people will need this answer. I had the same problem and to fix it I did this:

虽然这篇文章现在已经过时了,但我认为其他人会需要这个答案。我遇到了同样的问题,为了解决它,我这样做了:

tinyMCE.init({
        ...
        init_instance_callback : "myCustomInitInstance"
});

Based on http://www.tinymce.com/wiki.php/Configuration3x:init_instance_callback

基于http://www.tinymce.com/wiki.php/Configuration3x:init_instance_callback

回答by diosney

After hacking into the tinymce object with console.log(), I found a working solution:

在使用 console.log() 侵入 tinymce 对象后,我找到了一个可行的解决方案:

setTimeout(function () {
       for (var i = 0; i < tinymce.editors.length; i++) {
             tinymce.editors[i].onChange.add(function (ed, e) {
             // Update HTML view textarea (that is the one used to send the data to server).
         ed.save();
       });
            }
}, 1000);

Inside that callback function one can set the whatever event binding one wants.

在该回调函数中,您可以设置想要的任何事件绑定。

The setTimeoutcall is to overcome the racing condition of tinymceand jQuery, since when the call to tinymce.editors[i].onChange.add()is made tinymce wasn't initialized yet.

setTimeout调用是为了克服tinymceand的竞争条件jQuery,因为调用tinymce.editors[i].onChange.add()tinymce时还没有初始化。

回答by tsdexter

EDIT: oops - I thought this was another question I was looking at that was specific to WordPress + TinyMCE, guess not. Though I'll leave the answer here as it may be helpful to others.

编辑:哎呀 - 我认为这是我正在研究的另一个问题,它特定于 WordPress + TinyMCE,猜猜不是。虽然我会在这里留下答案,因为它可能对其他人有帮助。

The proper way to do this would be to append to the tinyMCE init with the WordPress filter. For example:

执行此操作的正确方法是使用 WordPress 过滤器附加到 tinyMCE init。例如:

PHP (in functions.php or other location that is run on edit page load):

PHP(在functions.php或编辑页面加载时运行的其他位置):

  add_action( 'init', 'register_scripts' );     
  function register_scripts(){
    if ( is_admin() ) {
      wp_register_script(
        'admin-script',
        get_stylesheet_directory_uri() . "/js/admin/admin.js",
        array('jquery'),
        false,
        true
      );
    }
  }

  add_action( 'admin_enqueue_scripts', 'print_admin_scripts' );
  function print_admin_scripts() {        
    wp_enqueue_script('admin-script');
  }

  add_filter( 'tiny_mce_before_init', 'my_tinymce_setup_function' );
  function my_tinymce_setup_function( $initArray ) {
    $initArray['setup'] = 'function(ed){
      ed.onChange.add(function(ed, l) {
        tinyOnChange(ed,l);
      });
    }';
    return $initArray;
  }

JavaScript (/js/admin/admin.js)

JavaScript (/js/admin/admin.js)

  (function($){
    window.tinyOnChange = function(ed, l){        
      console.log('Editor contents was modified. Contents: ' + l.content);      
    }
  }(jQuery);

This is tested and working in WordPress 3.9 (though I am simply getting the console output:

这是在 WordPress 3.9 中测试和工作的(虽然我只是得到控制台输出:

Deprecated TinyMCE API call: <target>.onChange.add(..) 

But that's due to tinyMCE deprecating code you're trying to use. This method does still work to modify to any of the tinyMCE init options - I'm currently using it for init_instance_callbackand it's working great.

但这是由于您尝试使用的 tinyMCE 弃用代码。这种方法仍然适用于修改任何 tinyMCE init 选项 - 我目前正在使用它init_instance_callback并且它工作得很好。

-Thomas

-托马斯

回答by Gabe Hiemstra

Here is my solution for binding events to one or multiple textareas at any time, given this code is appended after including the tinymce javascript file into your page. (In other words, the only thing required for this to work, is the existence of the 'tinymce' variable)

这是我随时将事件绑定到一个或多个 textarea 的解决方案,因为在将 tinymce javascript 文件包含到您的页面后附加了此代码。(换句话说,这个工作唯一需要的是'tinymce'变量的存在)

// Loop already initialised editors
for(id in tinymce.editors){
    if(id.trim()){
        elementReady(id);
    }
}

// Wait for non-initialised editors to initialise
tinymce.on('AddEditor', function (e) {
    elementReady(e.editor.id);
});

// function to call when tinymce-editor has initialised
function elementReady(editor_id){

    // get tinymce editor based on instance-id
    var _editor = tinymce.editors[editor_id];

    // bind the following event(s)
    _editor.on("change", function(e){

        // execute code
    });
}

Note that the 'change' event is not bound to always trigger instantly after something changed. According to the documentation, it “gets fired when changes are made inside the editor that cause an undo level to be added.” Which in my experience, does not always happen when you expect it to happen.

请注意,“更改”事件不一定会在更改后立即触发。根据文档,它“在编辑器内部进行更改导致添加撤消级别时被触发。” 根据我的经验,这并不总是在您期望它发生时发生。

One way to overcome this is by binding multiple events, such as 'input change', however, there will be some overlapping, which should then be filtered.

解决这个问题的一种方法是绑定多个事件,例如“输入更改”,但是,会有一些重叠,然后应该对其进行过滤。

回答by Ed Zavada

In TinyMCE 4, onChange doesn't exist. You have to use:

在 TinyMCE 4 中,onChange 不存在。你必须使用:

tinymce.get('myeditorname').on("change", function() { alert("stuff"); });