Javascript:无意的焦点模糊

时间:2012-08-19 08:46:30

标签: javascript html

在努力学习Javascript的过程中,我一直在努力实现一个WYSIWYG代码编辑器。我没有实现内容可编辑的divtextarea,而是从Ajax.org的ACE书中抽出一片叶子(而不是很多叶子)。

我有一个监听器divtabIndex设置为0,以处理所有输入事件。编辑器的所有组件(如文本区域,光标和装订线)都是此侦听器的子组件。自从实现鼠标事件处理程序以来,我一直遇到焦点在mousedown事件上丢失的问题。显然,即使在侦听器中发生blur事件,也会触发mousedown事件。

在评论出某些方法调用并试图确切地看到导致问题的原因之后,我注意到罪魁祸首是render方法。现在,我在每次输入后调用此方法,因此特别是当我为mousedown事件调用它时,焦点丢失是非常奇怪的。在评论render方法时,如果发生blur事件,则不会触发mousedown事件。

进一步说,事实证明,在评论我替换文本容器的innerHTML的部分时,问题就会消失。这又是非常奇怪的,因为我在replaceInnerHTML函数的不同位置使用render函数,但问题似乎只是因为特别更新文本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事件的情况下调用它时才会变得模糊?

或者我在试图调试这个问题时走向了一个完全错误的方向,这个问题是由于其他原因造成的?

修改

感谢pimvdb,这是一个重现问题的小提琴。 http://jsfiddle.net/wG4Yy/39/

blur事件似乎因重组mousedown事件上的节点而触发。我不知道如何解决问题。我曾尝试使用文档片段而不是innerHTML,我也尝试使用setTimeout安排更新,但两种尝试均无效。

我该怎么做才能解决这个问题?

1 个答案:

答案 0 :(得分:1)

当你想要一个元素获得焦点时,你似乎必须点击一个留在那里的元素。如果你用另一个元素替换它,浏览器显然不会被欺骗聚焦那个元素。

您可以做的是让浏览器完成其mousedown / focus等过程,然后手动关注元素。这可以通过setTimeout(..., 0)来电完成:http://jsfiddle.net/wG4Yy/41/

setTimeout(function() {
    wrapper.focus();
}, 0);