Javascript:联合焦点模糊

Javascript: Unitentional Focus Blur

本文关键字:焦点 模糊 Javascript      更新时间:2023-09-26

在学习Javascript的过程中,我一直在尝试实现所见即所得的代码编辑器。我没有实现内容可编辑的divtextarea,而是借鉴了Ajax的ACE的书(更确切地说,有很多借鉴)。

我有一个侦听器divtabIndex设置为0,用于处理所有输入事件。编辑器的所有组件,如文本区域、光标和排水沟,都是此侦听器的子级。自从实现了鼠标事件处理程序以来,我一直有一个问题,即焦点不在mousedown事件上。显然,即使侦听器中发生了mousedown事件,也会触发blur事件。

在注释掉某些方法调用并试图查看问题的确切原因后,我注意到罪魁祸首是render方法。现在,我在每次输入后都调用这个方法,所以焦点丢失是非常奇怪的,尤其是当我为mousedown事件调用它时。在注释掉render方法时,当存在mousedown事件时,不会触发blur事件。

进一步说,在注释掉我替换文本容器的innerHTML的部分后,问题就消失了。同样,这是非常奇怪的,因为我在render函数中的不同位置使用了replaceInnerHTML函数,但问题似乎只出现在特别更新文本div时。

这是replaceInnerHTML方法(我在这里发现了它):

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来安排更新,但都没有成功。

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

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

您可以让浏览器完成mousedown/focus等过程,然后手动聚焦元素。这可以通过setTimeout(..., 0)调用来实现:http://jsfiddle.net/wG4Yy/41/.

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