2009-09-24 6 views
13

Może to być najbardziej niejasny błąd, z którym miałem do czynienia w ciągu wielu lat pracy z JavaScriptem i dowolną wersją przeglądarki Internet Explorer. Używamy YUI 2.7 dla niektórych (nie) metod wygody. Sigh, co bym zrobił dla jQuery ....JavaScript: Błąd widoczności w przeglądarce Internet Explorer podczas ustawiania fokusu na element wejściowy

Ma to wpływ na Internet Explorer 6 i Internet Explorer7. Internet Explorer 8 zachowuje się prawidłowo. Wszystkie inne przeglądarki również zachowują się poprawnie.

Problem: Kiedy ustawić ostrość na konkretnym elemencie, pojawia się następujący błąd:

Can't move focus to the control because it is invisible, not enabled, or of a type that does not accept focus. 

więc mam div nazwie 'dodatek komentarz Login-overlay', który zawiera element wejściowy. Ten element div jest wyświetlany: brak, dopóki użytkownik nie kliknie jednego z kilku łączy o nazwie "login".

Poniżej znajduje się kod JavaScript, którego używam, który wybiera linki "login", które przesuwa pozycję "add-comment-login-overlay" w DOM, ustawia display: block, a następnie ustawia fokus pierwsze pole wprowadzania w nakładce. Właśnie ten proces ustawiania ostrości powoduje błąd, który napisałem powyżej.

//Get Login links in comment forms. 
links = YAHOO.util.Dom.getElementsByClassName('addCommentLoginLink'); 

//Set click event for login links. 
YAHOO.util.Event.addListener(links, "click", function(el){ 

    //Stop link. 
    YAHOO.util.Event.preventDefault(el); 

    //Move login overlay in DOM. 
    if(el.srcElement){ 
     var target = el.srcElement; 
    }else{ 
     var target = el.currentTarget; 
    } 

    YAHOO.util.Dom.insertAfter(overlay, target.parentNode.parentNode.parentNode.parentNode); 

    //Set to visible. 
    YAHOO.util.Dom.setStyle(overlay,'display', 'block'); 

    //Set focus to username field. 
    document.getElementById('add-comment-login-overlay-username-input').focus(); 
}); 

Mogę bezwzględnie potwierdzić, że nakładka div jest całkowicie widoczna. Mogę na to patrzeć. Dodałem timer setInterval do pomiaru tego, co się dzieje i nie ma on żadnego efektu. W pewnym momencie miałem 10 sekund na przejście między czasem, w którym nakładka była widoczna, a wywołaniem focus(), a błąd nadal występuje. Poza błędem, formularz jest całkowicie funkcjonalny, inny niż ten błąd.

To jest uproszczona wersja kodu HTML nakładki jako odnośnika.

<div id="add-comment-login-overlay" class="add-comment-login-overlay" style="display: block;"> 
    <div class="add-comment-login-overlay-content clearfix"> 
     <div class="add-comment-login-overlay-signin clearfix"> 
      <input type="text" tabindex="2001" id="add-comment-login-overlay-username-input"/> 
      <input type="password" tabindex="2002" id="add-comment-login-overlay-password-input"/> 
     </div> 
    </div> 
</div> 

Odpowiedz

17

To jest stary jak cholera błąd w IE (cieszę się, że wiem, że został naprawiony w 8). Nie wiem oficjalną przyczynę, ale wierzę, że ma do czynienia z IE nie odświeżający DOM aż po kontekst wykonanie jest kompletny, w międzyczasie próbując focus() element podczas gdy uzna to wciąż ukryty:

function calledAtSomePoint() { // begin execution 

    // ... 

    element.style.display = ''; // show container 
    input.focus(); // IE thinks element is hidden 

    // end of execution, IE repaints the DOM but it's too late 
} 

The solution is to use setTimeout:

setTimeout(function() { 
    document.getElementById('add-comment-login-overlay-username-input').focus() 
}, 0) 

miałem zdarzyć się wiele-do-czasu, włącznie z jQuery. To nie wina żadnej biblioteki. setTimeout zawsze pracował dla mnie.

+0

Miałem ten problem w IE 8, ale myślę, że mój problem miał do czynienia z faktem, że formularz został otwarty przez wywołanie window.showModalDialog (...).To obejście działa doskonale dla mnie. Dzięki! – Sanjamal

+0

To działało dla mnie w sprawie DotNetNuke! Dziękuję Crescent Fresh! –

+0

Wygląda na to, że nadal istnieje w IE11, tylko tym razem jest to czas wystarczający na 500ms dla skuteczności. – Jason

1

Ustaw fokus w bloku try/catch.

+0

Niestety, nie próbuję włożyć gumy do dziurawej tamy, żeby ją przykryć. Chciałbym dowiedzieć się, co do cholery to powoduje. – Geuis

+5

Cóż, moim zdaniem, guma w ie6 jest najlepszą praktyką. Ta przeglądarka jest pełna dziwnych błędów, których nie próbujesz zrozumieć, po prostu spróbuj zrobić swoją aplikację działa. Nie testowałem podejścia do Iod3n, ale jeśli to działa, jeśli w ogóle nie szkodzi wydajności, to załóż aplikację i idź na piwo. – GmonC

0

Podejrzewam, że wywołanie insertAfter jest mylące DOM IE. Czy możesz przetestować kod bez wywołania insertAfter? Czy to się nie udaje w taki sam sposób? Jeśli nie, czy istnieje inny sposób osiągnięcia tego samego rezultatu? Może skopiować węzły i usunąć oryginały zamiast przesuwać węzły?

Powiązane problemy