jQuery CKEditor 未捕获类型错误:无法在具有多个编辑器的 EmberJS 单页应用程序中调用 null 的方法“unselectable”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19328548/
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
CKEditor Uncaught TypeError: Cannot call method 'unselectable' of null in EmberJS single page app with multiple editors
提问by Chuck
I have a single page app created using EmberJS.
我有一个使用 EmberJS 创建的单页应用程序。
I have 3 textareas on the page.
我在页面上有 3 个文本区域。
I am rendering the ckeditor once the textarea has been inserted into the dom and I am flagging a property on the controller recording that the ckeditor has been rendered so that I'm not rendering it more than once.
一旦将 textarea 插入到 dom 中,我就会渲染 ckeditor,并且我正在记录控制器上的一个属性,记录 ckeditor 已经渲染,以便我不会多次渲染它。
I'm even looking into the dom to verify that there isn't currently an editor there.
我什至在查看 dom 以验证那里当前没有编辑器。
When refreshing the page, I am getting this error at random:
刷新页面时,我随机收到此错误:
Uncaught TypeError: Cannot call method 'unselectable' of null
I do not know what's causing it or now to prevent it. When it doesn't throw that error, all 3 ckeditors appear just fine.
我不知道是什么导致了它或现在要防止它。当它不抛出该错误时,所有 3 个 ckeditor 看起来都很好。
Here is my intiation code for the editor:
这是我的编辑器启动代码:
Lrt.PrioritizationEditableTextArea = Ember.TextArea.extend({
areaVisible: false,
isRendered: false,
isInserted: false,
didInsertElement:function(){
this.set('isInserted', true);
},
renderEditor:function(){
var self = this;
var selfID = self.get('elementId');
if( !this.get('isRendered') && this.get('isInserted') && $('#'+selfID).parent().find('cke').length === 0 ){
var editor = $('#'+selfID).ckeditor({
toolbar:[
{ name: 'document', items:['Source'] },
{ name: 'clipboard', items:['Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo']},
{ name: 'editing', items:['scayt']},
{ name: 'basicstyles', items:['Bold', 'Italic', 'Underline', 'TextColor', 'BGColor', '-', 'RemoveFormat']},
{ name: 'styles', items:['FontSize']},
{ name: 'paragraph', items:['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-']}
]
}).editor;
editor.on('change', function(e){
if(e.editor.checkDirty()){
self.set('value', editor.getData());
}
});
this.set('isRendered', true);
}
}.observes('areaVisible')
});
I am also using the "onChange" plugin for ckeditor to fire off an "onChange" event when anything changes in the editor and am responding to it.
我还使用 ckeditor 的“onChange”插件在编辑器中发生任何更改并对其做出响应时触发“onChange”事件。
What I have tried:
我尝试过的:
- removing the onChange plugin
- changing ckeditor to the 4.3 beta version
- removing the toolbar customizations
- removing the onChange event listener
- verify that all textareas have content in them when render
- 删除 onChange 插件
- 将 ckeditor 更改为 4.3 测试版
- 删除工具栏自定义
- 删除 onChange 事件侦听器
- 渲染时验证所有文本区域都包含内容
What do I need to do to fix this?
我需要做什么来解决这个问题?
EDIT
编辑
Here's the stack trace: (I'm tacking on the ver string in my app)
这是堆栈跟踪:(我正在我的应用程序中添加 ver 字符串)
a (ckeditor.js?ver=2.0.0:291)
(anonymous function) (ckeditor.js?ver=2.0.0:287)
i (ckeditor.js?ver=2.0.0:10)
CKEDITOR.event.CKEDITOR.event.fire (ckeditor.js?ver=2.0.0:12)
CKEDITOR.editor.CKEDITOR.editor.fire (ckeditor.js?ver=2.0.0:13)
CKEDITOR.event.CKEDITOR.event.fireOnce (ckeditor.js?ver=2.0.0:12)
CKEDITOR.editor.CKEDITOR.editor.fireOnce (ckeditor.js?ver=2.0.0:13)
(anonymous function) (ckeditor.js?ver=2.0.0:223)
m (ckeditor.js?ver=2.0.0:203)
CKEDITOR.scriptLoader.load (ckeditor.js?ver=2.0.0:203)
(anonymous function) (ckeditor.js?ver=2.0.0:222)
(anonymous function) (ckeditor.js?ver=2.0.0:210)
(anonymous function) (ckeditor.js?ver=2.0.0:208)
m (ckeditor.js?ver=2.0.0:203)
CKEDITOR.scriptLoader.load (ckeditor.js?ver=2.0.0:203)
CKEDITOR.resourceManager.load (ckeditor.js?ver=2.0.0:207)
h (ckeditor.js?ver=2.0.0:209)
(anonymous function) (ckeditor.js?ver=2.0.0:210)
m (ckeditor.js?ver=2.0.0:220)
(anonymous function) (ckeditor.js?ver=2.0.0:220)
(anonymous function) (ckeditor.js?ver=2.0.0:397)
(anonymous function) (ckeditor.js?ver=2.0.0:208)
m (ckeditor.js?ver=2.0.0:203)
q (ckeditor.js?ver=2.0.0:203)
r (ckeditor.js?ver=2.0.0:203)
(anonymous function) (ckeditor.js?ver=2.0.0:204)
EDIT #2:
编辑#2:
Here is a fiddle of the specific area of the application where the issue is occuring: http://jsfiddle.net/sSaCd/3/
这是发生问题的应用程序特定区域的小提琴:http: //jsfiddle.net/sSaCd/3/
回答by mwalsher
I was having a similar problem with AngularJS and jQuery UI Sortable with multiple CKEditors on the page. Basically a nightmare setup. Not sure if this is even entirely related, but I figured I'd share anyway in case anyone else comes across this issue. It seems to be a bug in CKEditor (http://dev.ckeditor.com/ticket/11924?) more than anything.
我在页面上有多个 CKEditor 的 AngularJS 和 jQuery UI Sortable 也遇到了类似的问题。基本上是噩梦般的设置。不确定这是否完全相关,但我想无论如何我都会分享,以防其他人遇到这个问题。这似乎是 CKEditor ( http://dev.ckeditor.com/ticket/11924?) 中的一个错误。
Whenever the DOM is changed by sortable, I have callbacks that destroy/recreate the CKEs (long story).
每当 DOM 被 sortable 更改时,我都会有回调来销毁/重新创建 CKE(长话短说)。
I was calling CKEDITOR.remove(ckInstance)
, which resulted in the same error you were getting.
我正在调用CKEDITOR.remove(ckInstance)
,这导致了您遇到的相同错误。
I also tried calling calling ckInstance.destroy()
and ckInstance.destroy(true)
(to avoid updating the DOM which had already changed) in my callback, but got the error Cannot read property 'hasAttribute' of undefined
(and also Cannot read property 'clearCustomData' of null
somewhere along the line).
我还尝试在我的回调中调用调用ckInstance.destroy()
和ckInstance.destroy(true)
(以避免更新已经更改的 DOM),但是得到了错误Cannot read property 'hasAttribute' of undefined
(以及Cannot read property 'clearCustomData' of null
沿线的某个地方)。
I was able to resolve this issue via the following:
我能够通过以下方式解决这个问题:
ckInstance.removeAllListeners();
CKEDITOR.remove(ckInstance);
ckInstance.removeAllListeners();
CKEDITOR.remove(ckInstance);
CKEditor seems to do a terrible job of cleaning up after itself and handles DOM changes incredibly poorly (not to mention Angular...)
CKEditor 似乎在自我清理方面做得很糟糕,并且处理 DOM 更改的能力非常差(更不用说 Angular 了……)
Hopefully this saves someone else the ridiculous amount of time it took me to figure it out :)
希望这可以为其他人节省我花费大量时间来弄清楚它的荒谬时间:)
回答by thatgibbyguy
I had the same issue using Meteor and having multiple ckeditor instances as well. This is a common problem with reactive DOM loading in general in which your app has processed your javaScript calls in the order they're received but the DOM may not be fully loaded.
我在使用 Meteor 并有多个 ckeditor 实例时遇到了同样的问题。这是响应式 DOM 加载的一个常见问题,一般来说,您的应用程序已经按照接收到的顺序处理了您的 javaScript 调用,但 DOM 可能没有完全加载。
To solve this I just block the code with a setTimeout.
为了解决这个问题,我只是用 setTimeout 来阻止代码。
setTimeout(function(){
$('#content-area').ckeditor();
},100);
回答by AMAFsoft
jQuery doc ready function solved the problem for me
jQuery doc ready 函数为我解决了这个问题
$(document).ready(function () {
CKEDITOR.replace( 'content' );
});
回答by Valamas
I just edited the minified file (leaving notes in a text file for developers) and just changed where my error was occurring to check for null from
我刚刚编辑了缩小的文件(在文本文件中为开发人员留下了注释)并更改了发生错误的位置以检查来自
&&a.ui.space("top").unselectable();
to
到
&&a.ui.space("top")!=null&&a.ui.space("top").unselectable();
I did this in two places.
我在两个地方做了这个。
回答by Anand
I had put the CKEDITOR.replace line inside a function and while body onload called the function.
我已将 CKEDITOR.replace 行放在一个函数中,而 body onload 调用了该函数。
I have bumped into same kind of issue in laravel. The CKEDITOR.replace javascript was running before the page completely loaded due to which this error occured.
我在 Laravel 中遇到了同样的问题。由于发生此错误,CKEDITOR.replace javascript 在页面完全加载之前运行。
to make sure that page loaded completely I had put the CKEDITOR.replace line inside a function and while body onload called the function
为了确保页面完全加载,我将 CKEDITOR.replace 行放在一个函数中,而 body onload 调用了该函数
回答by LOTUSMS
To add to @thatgibbyguy answer, in case it's not clear. If his answer didn't work for you or returned ckeditor not found, it is becasue it doesn't exist as a function if you followed the laravel-ckeditor documentation with composer installation. Which in that case you need to slightly modify his answer this way and it will work
添加到@thatgibbyguy 的答案中,以防不清楚。如果他的回答对您不起作用或返回 ckeditor not found,那是因为如果您按照 laravel-ckeditor 文档安装 composer 时,它不作为函数存在。在这种情况下,您需要以这种方式稍微修改他的答案,它会起作用
<script src="/vendor/unisharp/laravel-ckeditor/ckeditor.js"></script>
<script>
setTimeout(function(){
CKEDITOR.replace( 'article-ckeditor' ); //Your selector must match the textarea ID
},400);
</script>
Mind you, I am referring to it as a vendor. Look up artisan instructions to include it in your vendor's resources. But I imagine it will work just the same with the CDN installation.
请注意,我指的是供应商。查找工匠说明以将其包含在供应商的资源中。但我想它与 CDN 安装的工作方式相同。
回答by wmarbut
Try calling ck_editor.destroy
where ck_editor
is your editor instance. For some reason CKEDITOR seems to hang on to old instances. If you destroy them, the error seemsto go away.
尝试调用您的编辑器实例ck_editor.destroy
在哪里ck_editor
。出于某种原因,CKEDITOR 似乎挂在旧实例上。如果您销毁它们,错误似乎就会消失。
MyView: Ember.View.extend
# Hang on to the reference for your editor
didInsertElement: ->
@set('ck_editor', CKEDITOR.replace('whatever'))
# Tear down your instanc
willDestroyElement: ->
if @get('ck_editor')
@get('ck_editor').destroy()