为啥我不能在我的 jQueryUI 模式对话框中输入 TinyMCE?

Posted

技术标签:

【中文标题】为啥我不能在我的 jQueryUI 模式对话框中输入 TinyMCE?【英文标题】:Why can't I type in TinyMCE in my jQueryUI modal dialog?为什么我不能在我的 jQueryUI 模式对话框中输入 TinyMCE? 【发布时间】:2011-12-31 09:06:31 【问题描述】:

我有一个基本的模式对话框,其中包含一个 TinyMCE 实例。此模式在每次打开时动态创建,对话框(和元素)在对话框关闭时被销毁和删除。

我第一次打开对话框时,一切都很好。表单加载(ajax 调用),uniform 应用于表单,TinyMCE 应用于 textarea。我可以很好地执行所有操作。随后我打开表单的所有时间都会重复这个过程,不同之处在于,虽然 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 插件将编辑器加载到具有 tinyMCE 类的所有文本区域中,按预期工作。

我在 *** 上阅读了几个关于类似问题的不同问题,但没有一个提供此问题的答案。有人有什么想法吗?

一些跟进:我在初始对话框打开和后续打开之间进行了一些输出比较,并注意到了一些东西。在初始加载中,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:根据 Patricia 的建议,我将对话的关闭事件更改为以下内容:

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,我已经确认编辑器已被销毁,然后 textarea 完全删除,然后再销毁对话框并删除 div。也就是说,重新初始化对话框我仍然无法输入新的 TinyMCE 实例,底层代码显示就像我上次更新一样。这似乎与对前一个元素的不当破坏无关。

更新: Patricia 的最后一个建议是将 ajax 调用(将表单加载到对话框中)移到 .load() 方法中,然后创建对话框。我试过这个,事情很快就向南了。远程内容包含必须执行的脚本,因此 .ajax() 方法上的脚本数据类型。 .load() 方法没有这个选项,它真的不喜欢它。所以现在我不确定下一步该尝试什么。

【问题讨论】:

你这里碰巧有 ajaxSetup 吗? 我没有。这里有很多 ajax,有很多不同的要求,所以我没有应用任何全局设置,因为每个实现都是不同的。 只是一件小事:data: id:id, , 应该是 data: id:id , 我会纠正的。仅在此代码中。我在示例中删除/更改了一些次要代码(模板路径、数据键/值等)以保护我的雇主。 【参考方案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();到您的关闭处理程序。

【讨论】:

我已经尝试了这两种解决方案,但都没有解决我的问题。 感谢 .html("") 的提醒。不知道那个。我的删除在那里,但在那个 setTimeout() 中。当对话框“关闭”仍在执行时,我在尝试“删除”el 时遇到了问题,因此将其设置为稍晚一点(根据 Firebug,这有效)。不幸的是,从 .html("") 切换到 .empty() 也没有解决这个问题。 哦,对了,我现在明白了。 hmmmmmmmmmm 这很奇怪。这似乎是一个古怪/没有理由的想法,但是您是否尝试过使用 .load 而不是 .ajax ? 我没有(请参阅我的最新评论),但我可以看看。不过,我需要对数据加载前和加载后做几件事(尚未编码),所以这对我来说可能不是一个很好的选择。不过我还是先看看吧。 嗯,好的。我的想法不多了,我看到你在使用萤火虫,它在 IE 中的表现如何?哦,还有一件小事:你有一些选择器,比如:form#myForm 这实际上比普通的#id 选择器效率低。【参考方案2】:

这对我有用。

$('.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
    );

【讨论】:

【参考方案3】:

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

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

【讨论】:

以上是关于为啥我不能在我的 jQueryUI 模式对话框中输入 TinyMCE?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能使用 vs 2015、vs2017、vs2019 在我的 Windows 上创建 VC++ 空项目

jquery datatable - “jqueryui modal”正在页面中创建重复的对话框 html

为啥我的页面上没有出现 JQuery UI 滑块?

django admin jQueryUI对话框

Django/Jquery UI 对话框 - 如何将 Django 与 JqueryUI 对话框集成?

为啥我的 jqueryUI 自动完成显示在左上角?