Firefox 下的 focus() 没有按预期工作?

focus() under Firefox not working as expected?

我试图阻止用户在 contentedtiable 元素上书写。为此,我正在检索插入符的父容器并检查它是否是 ID 为 dnd-textarea.

的文本区域

下面的代码在 Chrome 上运行良好,但在 Firefox 上运行失败。 preventWritingOnTextArea() 的日志输出显示,在 Firefox 下,父级没有改变,但仍然是 dnd-textarea 而不是 ID newId.

InlinePanel
private native Node getCaretParent() /*-{

    var target = null;

    if($wnd.getSelection) {
        target = $wnd.getSelection().getRangeAt(0).commonAncestorContainer;
        return ((target.nodeType===1) ? target:target.parentNode);
    }
    else if($doc.selection) {
        target = $doc.selection.createRange().parentElement();
    }

    return target;
}-*/;

在我的 textarea 的 onKeyPress() 方法中,我检查小车是否尝试在其上书写。如果是这样,我会进入 preventWritingOnTextArea() 以防止出现这种情况。

@Override
public void onKeyPress(KeyPressEvent event) {

    Node parent = getCaretParent();

    GWT.log("Caret parent: " + parent);

    if(parent == textarea.getElement()) {                       
        preventWritingOnTextArea();         
    }           
}

方法 preventWritingOnTextAread() 应该添加一个新的 InlinePanel 并通过在这个新面板上设置焦点来从文本区域移除焦点。恕我直言,这只能意味着 focus() 不能像预期的那样在 Firefox 上工作 and/or 会做其他事情。

private void preventWritingOnTextArea() {

    GWT.log("preventWritingOnTextArea()");

    InlineLabel textWrapper = new InlineLabel();

    int pos = getCursorPosition(textarea.getElement());

    if(pos == 0) {
        textarea.getElement().insertFirst(textWrapper.getElement());
    } else {
        textarea.getElement().appendChild(textWrapper.getElement());
    }

    String newId = "wrap-"+(nextId++);

    // Tried that too but this loses the focus completely under Firefox.
    //textarea.getElement().blur();

    textWrapper.getElement().setId(newId);
    textWrapper.getElement().focus();   

    Node parent = getCaretParent(); 
    Element newParent = parent.cast();  
    GWT.log("New parent " + newParent.getId());
}

我怎样才能在 Firefox 下工作,是的..所有其他浏览器也一样..

是的,我曾尝试先 blur() textarea,然后将焦点重新放在 textWrapper 上,但效果不佳。

好吧,Firefox 不想按照它应该的方式来做。我现在的解决方案是标记新的 span 元素(显然是空的)的文本,以真正将焦点放在它上面。这很丑陋,但话又说回来,我们在这里谈论的是网络开发,对吧?感谢@TimDown for this answer.

private void preventWritingOnTextArea() {

    GWT.log("preventWritingOnTextArea()");

    InlineLabel textWrapper = new InlineLabel();

    // ...

    textWrapper.getElement().setId(newId);
    textWrapper.getElement().focus();

    // Firefox didn't want to play with us.
    markText(textWrapper.getElement());
}

private native void markText(Element element) /*-{

    win = $wnd;
    var doc = win.document, sel, range;

    if (win.getSelection && doc.createRange) {      
        sel = win.getSelection();
        range = doc.createRange();
        range.selectNodeContents(element);
        sel.removeAllRanges();
        sel.addRange(range);

    } else if (doc.body.createTextRange) {      
        range = doc.body.createTextRange();
        range.moveToElementText(element);
        range.select();
    }       
}-*/;