首页 文章

Javascript:Unitentional Focus Blur

提问于
浏览
3

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

我有一个 divtabIndex 设置为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 回答

  • 1

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

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

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

相关问题