为什么我无法在jQueryUI模态对话框中输入TinyMCE?

9
我有一个基本的模态对话框,其中包含一个 TinyMCE 实例。每次打开时都会动态创建此模态对话框,并在对话框关闭时销毁和删除对话框及其元素。
第一次打开对话框时一切正常。表单加载(ajax调用),表单应用了 uniform 样式,并将 TinyMCE 应用于文本区域。我可以正常执行所有操作。随后每次打开表单时,过程重复,不同之处在于尽管 TinyMCE 应用于文本区域,但我无法再其中输入内容。
这是在链接点击时触发的方法:
$('<div id="perspDlg">').dialog({
    title:'My Dialog',
    width:900,
    height:575,
    modal:true,
    create: function(){
        $('span.ui-icon-closethick').html("");
    },
    close:function(){
        $('form#myForm').unbind('submit');
        $('textarea[name="discussion"]').tinymce().destroy();
        $(this).html('').dialog('destroy');
        setTimeout("$('#perspDlg').remove();",100);
    },
    open:function(){
        var dlg = $(this);
        $.ajax({
            url:_cfcPath+'/lessons/myTemplate.cfm',
            dataType:'script',
            data:{id:id},
            success:function(d,r,o){
                dlg.html(d);
                $('form#myForm').bind('submit',formHandler);
            }
        });
    },
    buttons:[
        {text:'Save Form',
        click:function(){
            $('form#myForm').submit();
            //$(this).dialog('close');
        }},
        {text:'Cancel',
        click:function(){
            $(this).dialog('close');
        }}
    ]
});

当模板加载时,最后几行会将TinyMCE应用于加载的表单中的文本区域:
$('textarea.tinyMCE').tinymce({
    script_url : '/assets/scripts/_lib/tiny_mce/tiny_mce.js',
    mode : "textareas",
    editor_deselector : "mceNoEditor",
    theme : "advanced",
    plugins : pluginVal,
    //Paste options
    extended_valid_elements : "a[name|href|target|rel|title|style|class],div[align|class|style|height|width],form[accept|accept-charset|action|class|dir<ltr?rtl|enctype|id|lang|method<get?post|name|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|onreset|onsubmit|style|title|target],hr[class],span[align|class|style],img[class|src|style|alt|title|name],input[accept|accesskey|align<bottom?left?middle?right?top|alt|checked<checked|class|dir<ltr?rtl|disabled<disabled|id|ismap<ismap|lang|maxlength|name|onblur|onclick|ondblclick|onfocus|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|onselect|readonly<readonly|size|src|style|tabindex|title|type<button?checkbox?file?hidden?image?password?radio?reset?submit?text|usemap|value],table[border|class|style|cellpadding|cellspacing|background|height|width],td[background|style|class|valign|align|height|width],p",
    invalid_elements: "font,align,script,applet,iframe",
    paste_auto_cleanup_on_paste : true,
    paste_remove_styles: true,
    paste_remove_styles_if_webkit: true,
    paste_strip_class_attributes: true,
    paste_retain_style_properties: "none",
    paste_block_drop: true,
    remove_linebreaks : false,
    paste_create_paragraphs : false,
    paste_create_linebreaks : false,
    relative_urls : false,
    remove_script_host : false,
    document_base_url : baseURL,
    theme_advanced_buttons1 : btn1Val,
    theme_advanced_buttons2 : btn2Val,
    theme_advanced_buttons3 : btn3Val,
    theme_advanced_buttons4 : btn4Val,
    theme_advanced_toolbar_location : "top",
    theme_advanced_toolbar_align : "left",
    theme_advanced_resizing : true
});

这使用了TinyMCE的JQuery插件,将编辑器加载到所有class为tinyMCE的文本区域中,它可以正常工作。

我在StackOverflow上阅读了几个类似问题的帖子,但没有一个提供了解决此问题的答案。有人有什么想法吗?

一些后续:我进行了一些输出比较,比较了初始对话框打开和后续打开之间的差异,并注意到了一些情况。在初始加载和TinyMCE应用于文本区域时,我看到应用程序创建了一个iframe,加载了一个包含菜单行和一个包含其他iframe的行的表格。该iframe的内容(首次加载)如下:

<tr class="mceLast">
    <td class="mceIframeContainer mceFirst mceLast">
        <iframe id="mce_0_ifr" frameborder="0" src="javascript:""" allowtransparency="true" title="Rich Text AreaPress ALT-F10 for toolbar. Press ALT-0 for help" style="width: 100%; height: 204px; display: block;">
            <html>
                <head xmlns="http://www.w3.org/1999/xhtml">
                    <base href="http://dev.nsite.loc">
                    <meta content="IE=7" http-equiv="X-UA-Compatible">
                    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
                    <link href="http://dev.nsite.loc/assets/scripts/_lib/tiny_mce/themes/advanced/skins/default/content.css" rel="stylesheet" type="text/css">
                    <link rel="stylesheet" data-mce-href="http://dev.nsite.loc/assets/scripts/_lib/tiny_mce/plugins/spellchecker/css/content.css?110120111025" href="http://dev.nsite.loc/assets/scripts/_lib/tiny_mce/plugins/spellchecker/css/content.css?110120111025">
                    <link rel="stylesheet" data-mce-href="http://dev.nsite.loc/assets/scripts/_lib/tiny_mce/plugins/class_U/css/content.css?110120111025" href="http://dev.nsite.loc/assets/scripts/_lib/tiny_mce/plugins/class_U/css/content.css?110120111025">
                    <link rel="stylesheet" data-mce-href="http://dev.nsite.loc/assets/scripts/_lib/tiny_mce/plugins/noneprovided/css/content.css?110120111025" href="http://dev.nsite.loc/assets/scripts/_lib/tiny_mce/plugins/noneprovided/css/content.css?110120111025">
                    <link rel="stylesheet" data-mce-href="http://dev.nsite.loc/assets/scripts/_lib/tiny_mce/themes/advanced/skins/default/content.css?110120111025" href="http://dev.nsite.loc/assets/scripts/_lib/tiny_mce/themes/advanced/skins/default/content.css?110120111025">
                </head>
                <body id="tinymce" class="mceContentBody " contenteditable="true" dir="ltr">
                    <br data-mce-bogus="1">
                </body>
            </html>
        </iframe>
    </td>
</tr>

但是,在后续的加载中,我得到了菜单,但是内部IFrame看起来像这样:

<tr class="mceLast">
    <td class="mceIframeContainer mceFirst mceLast">
        <iframe id="mce_12_ifr" frameborder="0" src="javascript:""" allowtransparency="true" title="Rich Text AreaPress ALT-F10 for toolbar. Press ALT-0 for help" style="width: 100%; height: 204px; display: block;">
            <html>
                <head>
                </head>
                <body>
                </body>
            </html>
        </iframe>
    </td>
</tr>

可能是什么原因导致这种情况发生?

更新2: 根据帕特里夏的建议,我将对话框的关闭事件更改为以下内容:

close:function(){
    $('form#perspectiveForm').unbind('submit');
    var id = $('textarea:tinymce').attr('id');
    tinyMCE.execCommand('mceRemoveControl', false, id);
    $('textarea#'+id).remove();
    $(this).empty().dialog('destroy');
    setTimeout("$('#perspDlg').remove();",100);
},

通过一些步骤的调试和 FireBug,我确认了编辑器已被销毁,然后文本区域被完全删除,在销毁对话框并移除 div 前。即便如此,在重新初始化对话框后,我仍然无法在新的 TinyMCE 实例中键入内容,底层代码显示为上次更新的内容。它似乎与之前元素的不正确销毁无关。
更新:Patricia 的最后建议是将加载表单到对话框的 ajax 调用移到.load() 方法中,然后创建对话框。我尝试了这个方法,事情很快就变得糟糕了。远程内容包含必须执行的脚本,因此在 .ajax() 方法上使用 script 数据类型。.load() 方法没有这个选项,而且它非常不喜欢这样做。所以现在我不知道该尝试什么了。

你在这里使用ajaxSetup吗? - Mark Schultheiss
我不会这样做。这里有很多ajax操作,有很多不同的要求,因此我不会应用任何全局设置,因为每个实现都是不同的。 - Steve -Cutter- Blades
只是一个小问题:data:{id:id,} 应该改为 data:{id:id}。 - Mark Schultheiss
我会进行更正。这只是在这段代码中。我在示例中删除/更改了一些较小的代码(模板路径、数据键/值等),以保护我的雇主。 - Steve -Cutter- Blades
3个回答

1

当我使用按钮刷新一个区域时,我遇到了类似的问题。

在重新实例化之前,您必须完全销毁tinyMCE控件。

我在我的刷新按钮处理程序中使用这个逻辑:

$('#sectionToRefresh').find('textarea:tinymce').each(function(){
     var id = $(this).attr('id');
     tinyMCE.execCommand('mceRemoveControl', false, id);
     $(this).remove();

});

对于对话框,我设置了以下“关闭”处理程序:

close: function (ev, ui) {
            if (typeof tinyMCE != 'undefined') {
                $(this).find(':tinymce').remove();
            }
            $(this).dialog("destroy");
            $(this).remove();



        }

以下任何一种方法都应该可以解决您的问题!

编辑:

我不知道这是否是问题,但是:

 $(this).html('').dialog('destroy');

使用 .html('') 并不能完美地清除内容,建议使用 .empty() 来实现。如果仍然出现问题,可能是由于某些事件未被完全清除。

同时,在关闭处理程序中添加 $(this).remove(); 也可以尝试解决问题。


我已经尝试了这两种解决方案,但都没有解决我的问题。 - Steve -Cutter- Blades
谢谢你提醒我 .html("") 这个方法,我之前不知道。我的 remove 方法已经在 setTimeout() 里面了。我曾经遇到过一个问题,就是当 dialog 'close' 还在执行的时候,我试图 'remove' 元素,所以我把它稍微延迟了一下(根据 Firebug 的结果是有效的)。不幸的是,从 .html("") 切换到 .empty() 也没有解决这个问题。 - Steve -Cutter- Blades
哦,我现在明白了。嗯,这很奇怪。这可能看起来像一个疯狂/没有理由可行的想法,但你尝试过使用.load而不是.ajax吗? - Patricia
我还没有(请看我的最新评论),但我可以查看一下。不过,在数据预处理和加载之前和之后,我需要做几件事情(尚未编码),所以这可能对我来说不是一个很好的选择。不过我会先看看它。 - Steve -Cutter- Blades
嗯,好的。我已经没有更多的想法了。我看到你在使用Firebug,它在IE中的表现如何?另外还有一件小事:你有一些选择器,比如form#myForm,这实际上不如一个简单的#id选择器高效。 - Patricia

0

我必须确保我的tinymce init在对话框配置之后执行。这样就为我解决了问题。

 $("#editDialog").dialog({
               ...           
            });
            tinymce.init({
                selector: '#txtCourseDesc'
            });
            $('#editDialog').show();

0

这对我有用。

$('.jq_tinymce').each(function(idx, el)
    {
        toggle_editor('textarea[name="'+ $(this).attr('name') +'"]', $(this).data('tinymce_theme'));
    });

你所需要做的就是在打开对话框后运行此代码。我正在使用jq_tinymce来让它知道哪些文本区域需要初始化。在html标签上使用data-tinymce_theme属性将使您能够指定tinymce主题。
toggle_editor是什么?
function toggle_editor(selector, theme)
{
if (theme == undefined)
{
    theme = 'simple';
}

if($(selector+':first').css('display') == 'none')
{
    $(selector).each(function(){
        $(this).tinymce().hide();
    })
}
else
{
    $(selector).tinymce({
        script_url : Vega.base_url+'ext/tinymce_3.5_jquery/tiny_mce.js',
        // General options
        theme : theme,
        width: '100%',
        language: Vega.tinyMceLocale,
        plugins : "autolink,lists,pagebreak,style,layer,table,save,advimage,advlink,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,advlist",
        file_browser_callback : "tinymce_uploader",

        // Theme options
        theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,styleselect,formatselect,fontselect,fontsizeselect,styleprops",
        theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
        theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,iespell,media,|,print,|,fullscreen,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,pagebreak",
        theme_advanced_toolbar_location : "top",
        theme_advanced_toolbar_align : "left",
        theme_advanced_statusbar_location : "bottom",
        theme_advanced_resizing : true
    });
}

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接