问题描述:
来到百度ueditor官网,下载一个你需要的版本(java,php等),页面头部引入如下标签,
//这里为了方便看源码,就不引用min.js了
然后在html body标签里面写下如下代码,你的ueditor应该就实例化成功了(我的页面上有至少2个ueditor编辑器,先将它定义为编辑器页面)
var editor=UE.getEditor('')
var editor1=UE.getEditor('')
随后,当我在第一次进入该页面时,采用编辑器内置的方法setContent,给编辑器设置初始值(成功了):
editor.ready(function(){//监听编辑器实例化完成的事件
console.log('编辑器1实例化完成')
editor.setContent('嘿嘿')
})
editor.ready(function(){
console.log('编辑器2实例化完成')
editor1.setContent('哈哈')
})
但是当我点击浏览器的后退键返回上一个页面(或者是点击页面上自己设置的后退按钮返回上一个页面)后,再一次进入到编辑器页面,同样调用
editor.setContent('嘿嘿')
editor1.setContent('哈哈')
的方法,浏览器控制台就报错了
Cannot set property 'innerHTML' of null .
意思就是需要赋值的对象是null(但为什么没有报
undefined
呢?答案接下来分析)
而且奇葩的是,editor编辑器内容赋值成功,但是editor1赋值失败.
思前想后,还是去看看
ueditor的源码
.
UE.getEditor = function (id, opt) {
var editor = instances[id];
if (!editor) {
editor = instances[id] = new UE.ui.Editor(opt);
editor.render(id);
}
return editor;
};
源码里的instances是一个初始化的空对象
代码的意思就是:先去页面找是否存在已经实例化的编辑器对象,如果没有,就新生成一个编辑器.否则直接将页面上找到的那个编辑器给返回.再联想到刚才的报错Cannot set property 'innerHTML' of null(而不是undefined,而且控制台也没有输出编辑器2实例化完成),
那么真相只有一个!
那就是当你在一次来到编辑器页面时,编辑器早已经存在,都已经存在的编辑器,自然不会触发ready事件,所以自然不能触发卸载ready事件里的setContent事件了.
好奇的小伙伴一定会想到,既然编辑器已经存在了,那么我们把setContent函数调到ready事件外,不就行了吗!!!! 然而,并没有任何luan用.....(设置setTimeout也不行)
按照我的猜想,此时当你第二次或者第三第四....次进入编辑器页面,虽然页面上存在这第一次你进入该页面时的那个实例化好的编辑器,但是现在的它,功能并不完整了,你可以理解成汽车没了发动机,残疾了哎.
好了,找到了问题的根本,那么我们就来解决问题吧,方法也有两个:
1.我的页面既然有返回的按钮,那么我只需要在每次点击返回的时候,将页面上的ueditor对象销毁了,这样一来,下次再进入到此页面,就会重新实例化一个功能健全的ueditor了,
2.上面的解决办法是从表象上去组织可能错误的发生,可以说是治标不治本,因为一些用户的操作习惯是直接点击浏览器的后退按钮回到上一个页面,下次进入到编辑器页面,同样会遇到之前的问题.当然大家也可以利用js动态去判断浏览器的地址,从而决定应该何时销毁编辑器对象,相信这个方法也是可以的.
不过我想说的是,我们就来点简单粗暴的方法吧,ok,再回到ueditor源码: