Google Chrome和Javascript存在问题。大师需要!

时间:2010-08-29 22:05:26

标签: javascript iframe google-chrome

我有一个奇怪的问题仅在Chrome 中使用iframe,但在所有其他常用浏览器中工作。

问题:如果我输入IFRAME然后按下按钮发送,它工作正常,焦点回到IFRAME和光标BLINK。

但是如果我输入然后按ENTER键调用事件处理函数,焦点会回来,但光标会消失。然后,如果你进入另一个窗口,然后返回光标出现。 仅在Chrome中发生。我做了示例页面以显示操作中的问题。点击下面的链接查看。

更新:我在下面添加了代码

    var editorFrame = 'myEditor'

function addFrame() {

    var newFrame = new Element('iframe', {
        width: '520', 
        height: '100',
        id: editorFrame,
        name: editorFrame,
        src: 'blank.asp',
        class: 'myClass'
    });

    $('myArea').appendChild(newFrame);

    window.iframeLoaded = function() {
        // this is call-back from the iframe to be sure that is loaded, so can safety attach the event handler

        var iframeDoc, UNDEF = "undefined";
        if (typeof newFrame.contentDocument != UNDEF) {
            iframeDoc = newFrame.contentDocument;
        } else if (typeof newFrame.contentWindow != UNDEF) {
            iframeDoc = newFrame.contentWindow.document;
        }
        if (typeof iframeDoc.addEventListener != UNDEF) {
            iframeDoc.addEventListener('keydown', keyHandler, false);
        } else if (typeof iframeDoc.attachEvent != UNDEF) {
            iframeDoc.attachEvent('onkeydown', keyHandler);  
        }
    };
}

function resetContent() 
{   
    var myIFrame = $(editorFrame);

    if (myIFrame) myIFrame.contentWindow.document.body.innerHTML='';
}

function setEditFocus() 
{

    var iFrame = document.frames ? document.frames[editorFrame] : $(editorFrame);
    var ifWin = iFrame .contentWindow || iFrame;

    ifWin.focus();

}

function send()
{
    resetContent();
    setEditFocus(); 
}

function keyHandler (evt) {

    var myKey=(evt.which || evt.charCode || evt.keyCode)

    if (myKey==13)  {

        if (!evt) var evt = window.event;

        evt.returnValue = false;

        if (Prototype.Browser.IE) evt.keyCode = 0;

        evt.cancelBubble = true;

        if (evt.stopPropagation) evt.stopPropagation();

        if (evt.preventDefault) evt.preventDefault();

        send();

    }
}

在HTML页面

<body onload="addFrame()">

<div id="myArea"></div>
<input id="myButton" type="button" value="click me to send [case 1]" onclick="send()">

为了更容易理解问题,我创建了一个特定页面来重现问题,其中包含完整的示例和来源。

您可以使用Google Chrome查看此处: example of the problem

我真的需要你的帮助,因为我试图解决这个问题很多天没有运气。并且所有建议,提示和解决方法都被广泛接受。

提前致谢。

3 个答案:

答案 0 :(得分:3)

我不确定问题的原因是什么,因为Chrome 有时会正确地关注元素,尽管大部分时间它没有。您根本不需要请求焦点,因为按键时焦点不会丢失。如果您省略setEditFocus()来电,您应该会注意到除了Chrome之外,它仍能正常运行,因为Chrome显然已经删除了您已删除正文中的所有内容。

当您设置contenteditable时,每个浏览器都会将iframe文档的innerHTML元素的body设置为不同的内容:

Browser           | innerHTML
-----------------------------
Internet Explorer | ''
Opera             | '<br>\n'
Firefox           | '<br>'
Chrome/Safari     | '\n'

如果您以后在解析内容时不希望看到额外的内容,则可能需要在addFrame()中预先删除它。

通过执行以下操作,我能够“解决”问题:

首先,更新事件处理程序,以便我们可以在其中返回false并阻止Opera在我们稍后调用getSelection()时生成HTML以获得乐趣...

function addFrame() {
    ...
    window.iframeloaded = function() {
       ...
       if (typeof iframeDoc.addEventListener != UNDEF) {
           iframeDoc.addEventListener('keypress', keyHandler, false);
       } else if (typeof iframeDoc.attachEvent != UNDEF) {
           iframeDoc.attachEvent('onkeypress', keyHandler);
       }
    }
}

编辑:删除原始功能,转而使用下面的新功能

最后,从按键处理程序返回false以修复上面提到的Opera问题。

function keyHandler (evt) {
    var myKey=(evt.which || evt.charCode || evt.keyCode)

    if (myKey==13) {
        ...
        return false;
    }
}

我最初做过syockit建议的内容,但我发现它在Chrome中使用插入符大小做了奇怪的事情,这种方法似乎避免了(尽管Firefox还有点偏离......)。如果您不关心这一点,将innerHTML设置为非空白可能是一种更简单的解决方案。

另请注意,您应该在传递给className的对象中使用class而不是new Element(),因为IE似乎认为它是一个保留字,并说它是语法错误

编辑:在使用它之后,以下功能似乎可以在IE8 / Firefox / Chrome / Safari / Opera中可靠地运行,以获得更高级的测试用例。不幸的是,我确实必须包含Prototype的浏览器检测以解释Opera,因为尽管JavaScript的所有内容都看起来相同,但实际行为需要与其他浏览器冲突的不同代码,而我无法找到更好的区分方法。

这是新功能,它专注于iframe的可编辑内容,并确保如果已经有内容,则将插入符号移动到该内容的末尾:

function focusEditableFrame(frame) {
    if (!frame)
        return;

    if (frame.contentWindow)
        frame = frame.contentWindow;

    if (!Prototype.Browser.Opera) {
        frame.focus();

        if (frame.getSelection) {
            if (frame.document.body.innerHTML == '')
                frame.getSelection().extend(frame.document.body, 0);
            else
                frame.getSelection().collapseToEnd();
        } else if (frame.document.body.createTextRange) {
            var range = frame.document.body.createTextRange();

            range.moveEnd('character', frame.document.body.innerHTML.length);
            range.collapse(false);
            range.select();
        }
    } else {
        frame.document.body.blur();
        frame.document.body.focus();
    }
}

更新setEditFocus()(现在不是必需的,但因为你已经拥有它):

function setEditFocus()
{
    focusEditableFrame($(editorFrame));
}

答案 1 :(得分:1)

你知道我是怎么解决这个的吗?在resetContent()中,将''替换为' '

if (myIFrame) myIFrame.contentWindow.document.body.innerHTML=' ';

如果有效,那就好。不要问为什么,它可能是带有Range对象的Webkit故障之一,如果你愿意,可以提交一个bug。

答案 2 :(得分:0)

很快,您可以尝试在send()函数内的行末尾添加分号吗?看看是否有效。

function send() {
  resetContent();
  setEditFocus();
}