Accessing WordPress's TinyMCE iFrame

2019-07-26 06:41发布

问题:

Using jQuery I'm trying to manipulate the WordPress content editor, which uses TinyMCE inside of an iframe. I can't seem to get the following code to work as intended:

jQuery(document).ready(function($) {
$('#content_ifr').ready(function() {
    $('#content_ifr').contents().find('body').css('background-color', '#f33');
});

Regardless of whether I use ".ready()" or ".load()", the event will fire before the TinyMCE editor (the body of the iframe) is completely finished loading.

However, the following code will work if I wait for the iframe to load before manually clicking the title textbox to fire the click event:

jQuery(document).ready(function($) {
$('#title').click(function() {
    $('#content_ifr').contents().find('body').css('background-color', '#f33');
});

I've searched exhaustively on the subject of jQuery and iFrames, and it seems it's a hit or miss depending on the situation. Some code works for some people and not for others.

Does anyone know of a way to get the first code snippet to fire after the TinyMCE iframe body is completely finished loading? Because it's just the WordPress content editor, the iframe content is on the same domain.

What I really want to do is add a class to the body element in the iframe via .addClass()

jQuery(document).ready(function($) {
$('#content_ifr').ready(function() {
    $('#content_ifr').contents().find('body').addClass('ui-droppable');
});

so that I can apply the drag n' drop code in the following tutorial:

http://skfox.com/2008/11/26/jquery-example-inserting-text-with-drag-n-drop/

回答1:

You can use the tiny_mce_before_init hook to add a class to the body before tinymce.init

function my_tiny_mce_before_init( $init_array ) {
    $init_array['body_class'] = 'some-class some-other-class';
    return $init_array;
}
add_filter('tiny_mce_before_init', 'my_tiny_mce_before_init');


回答2:

I use this function to access or style iframe (inside tinymce) in Wordpess: this script is added to wordpress dashboard scripts, and detects while TINYMCE iframe is loaded, then actions to it.

add_action('admin_head', 'my_tinymce_styler',99,99);
function my_tinymce_styler()
{
    ?>
    <script>
    function myExec() 
    {
        var theFrame = document.getElementsByTagName("iframe")[0];
        if (!theFrame) { window.setTimeout(myExec, 1000);  }
        else
        {
            var theFrameDocument = theFrame.contentDocument || theFrame.contentWindow.document;
            theFrameDocument.body.innerHTML += '<?php echo json_encode('
                <style>
                    .parentt{
                    border:5px solid red !important;
                    }
                </style>');?>';
        }
    };
    window.onload = myExec;
    </script>
    <?php
}


回答3:

After more digging, it appears the problem is the way in which WordPress interacts with TinyMCE. The post by kovshenin in the following thread shed some light on this: change textarea value doesn't work In order to manipulate the WordPress content, I need to work with the hidden textarea and not the iframe content itself.



回答4:

Have a look at your tinymce configuration. All you need to so is to use the "setup"-setting and set the onInit-Handler there. Here is an example:

tinyMCE.init({
   ...
   setup : function(ed) {
      ed.onInit.add(function(ed, evt) {
          window.console && window.console.log('Tinymce Iframe loaded!');
          // do whatever you like here
      });
   }
});