在我努力学习Javascript的过程中,我一直在努力实现一个WYSIWYG代码编辑器 . 我没有实现内容可编辑的 div
或 textarea
,而是从Ajax.org _474020的书中摘了一片叶子(而不是很多叶子) .
我有一个 div
, tabIndex
设置为0,以处理所有输入事件 . 编辑器的所有组件(如文本区域,光标和装订线)都是此侦听器的子组件 . 自从实现鼠标事件处理程序以来,我一直遇到焦点在 mousedown
事件上丢失的问题 . 显然,即使在侦听器中发生 mousedown
事件,也会触发 blur
事件 .
在评论出某些方法调用并试图确切地看到导致问题的原因之后,我注意到罪魁祸首是 render
方法 . 现在,我在每次输入后调用此方法,因此焦点丢失是非常奇怪的,特别是当我为 mousedown
事件调用它时 . 在注释掉 render
方法时,如果存在 mousedown
事件,则不会触发 blur
事件 .
进一步说,事实证明,在评论我替换文本容器的 innerHTML
的部分时,问题就消失了 . 这又是非常奇怪的,因为我在 render
函数的不同位置使用了 replaceInnerHTML
函数,但问题似乎只是因为特别更新了文本 div
.
这是replaceInnerHTML方法(我发现here):
function replaceInnerHTML(el, html) {
var newEl = el.cloneNode(false);
newEl.innerHTML = html;
el.parentNode.replaceChild(newEl, el);
return newEl;
}
这是文本层的更新函数,省略了不会发生此问题:
TextLayer.prototype.update = function(config) {
html = [];
var top = config.topRow;
var last = config.lastRow;
for(var i=top; i<=last; i++) {
var line = this._session.getLine(i);
if(line) {
html.push('<div class="line" style="height:'+this.$characterSize.height+'px;">');
this.renderLine(html, line);
html.push('</div>');
}
}
this._text = replaceInnerHTML(this._text, html.join(''));
this.setSize(config.totalWidth, config.scrollHeight);
};
为什么焦点只会因替换特定节点的 innerHTML
而变得模糊,而且只有在 mousedown
事件的情况下被调用时才会变焦?
或者我在尝试调试这个问题时走向完全错误的方向,这个问题是由于其他原因造成的?
EDIT:
感谢pimvdb,这是一个重现问题的小提琴 . http://jsfiddle.net/wG4Yy/39/
blur
事件似乎因为重组 mousedown
事件上的节点而触发 . 我不知道如何解决问题 . 我曾尝试使用文档片段而不是innerHTML,我也尝试使用 setTimeout
安排更新,但两种尝试均无效 .
我该怎么办才能解决这个问题?
1 回答
当你想要一个元素获得焦点时,你似乎必须点击一个留在那里的元素 . 如果你用另一个元素替换它,浏览器显然不会被欺骗聚焦那个元素 .
您可以做的是让浏览器完成其mousedown / focus等过程,然后手动关注元素 . 这可以通过
setTimeout(..., 0)
调用来完成:http://jsfiddle.net/wG4Yy/41/ .