2009-09-24 35 views
13

Đây có thể là lỗi ít người biết đến nhất mà tôi chưa gặp phải trong nhiều năm làm việc với JavaScript và mọi phiên bản Internet Explorer. Chúng tôi đang sử dụng YUI 2.7 cho một số phương thức (không) tiện lợi. Sigh, những gì tôi sẽ làm cho jQuery ....JavaScript: Lỗi hiển thị trong Internet Explorer khi đặt tiêu điểm trên phần tử nhập

Điều này ảnh hưởng đến Internet Explorer 6 và Internet Explorer7. Internet Explorer 8 hoạt động đúng cách. Tất cả các trình duyệt khác cũng hoạt động bình thường.

Vấn đề: Khi tôi đặt trọng tâm vào một yếu tố đặc biệt, tôi nhận được lỗi sau:

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

Vì vậy, tôi có một div gọi là 'add-bình-login-overlay' có chứa các yếu tố đầu vào. Div này được hiển thị: không cho đến khi người dùng nhấp vào một trong một số liên kết được gọi là 'đăng nhập'.

Sau đây là mã JavaScript tôi đang sử dụng để chọn liên kết 'đăng nhập', di chuyển vị trí của 'add-comment-login-overlay' trong DOM, đặt display: block, sau đó đặt tiêu điểm trường đầu vào thứ nhất trong lớp phủ. Đó là quá trình thiết lập tiêu điểm gây ra lỗi tôi đã viết ở trên.

//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(); 
}); 

Tôi hoàn toàn có thể xác nhận rằng lớp phủ div hiển thị hoàn toàn. Tôi có thể nhìn vào nó. Tôi đã thêm một bộ đếm thời gian setInterval để đo lường những gì đang xảy ra và nó không có hiệu lực. Tại một thời điểm tôi đã có 10 giây đi giữa thời gian lớp phủ có thể nhìn thấy và khi focus() được gọi và lỗi vẫn xảy ra. Khác với lỗi, biểu mẫu hoàn toàn có chức năng khác với lỗi này.

Đây là phiên bản đơn giản của mã HTML lớp phủ làm tham chiếu.

<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> 

Trả lời

17

Đây là lỗi cũ như lỗi heck trong IE (vui mừng khi biết nó được sửa trong 8). Tôi không biết nguyên nhân chính thức, nhưng tôi tin rằng nó đã làm với IE không sơn lại DOM cho đến sau khi bối cảnh thực hiện hoàn tất, trong khi đó cố gắng để focus() nguyên tố này trong khi nó nghĩ rằng nó vẫn còn ẩn:

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) 

Tôi đã xảy ra nhiều lần, kể cả với jQuery. Đó không phải là lỗi của bất kỳ thư viện nào. Các setTimeout đã luôn luôn làm việc xung quanh nó cho tôi.

+0

Tôi đã gặp vấn đề này trong IE 8, nhưng tôi tin rằng vấn đề của tôi đã phải làm với thực tế là các hình thức đã được mở bằng một cuộc gọi đến window.showModalDialog (...).Cách giải quyết này làm việc hoàn hảo cho tôi. Cảm ơn! – Sanjamal

+0

Điều này làm việc cho tôi về vấn đề DotNetNuke! Cảm ơn bạn Crescent tươi! –

+0

Rõ ràng nó vẫn còn tồn tại trong IE11, chỉ có thời gian này một bộ đếm thời gian 500ms cần thiết cho hiệu quả. – Jason

1

Đặt trọng tâm trong khối thử/nắm bắt.

+0

Thật không may tôi không cố gắng để đặt một miếng kẹo cao su trong đập bị rò rỉ để vá nó hơn. Tôi muốn tìm ra cái quái gì đang gây ra điều này. – Geuis

+5

Vâng, theo tôi, một miếng kẹo cao su trong ví dụ6 là thực hành tốt nhất. Trình duyệt này có đầy đủ các lỗi lạ mà bạn không cố gắng hiểu chúng, bạn chỉ cần thử làm cho ứng dụng của bạn hoạt động. Tôi đã không thử nghiệm cách tiếp cận Iod3n, nhưng nếu nó hoạt động, nếu nó không làm tổn thương hiệu suất ở tất cả, bạn nên vá ứng dụng của bạn một đi ra ngoài cho một bia. – GmonC

0

Khi đoán, tôi muốn nói rằng cuộc gọi insertAfter gây nhầm lẫn với IE DOM. Bạn có thể kiểm tra mã mà không cần gọi số insertAfter không? Liệu nó có thất bại trong cùng một cách? Nếu không, có cách nào khác bạn có thể đạt được kết quả tương tự không? Có thể sao chép các nút và xóa bản gốc, thay vì di chuyển các nút?

Các vấn đề liên quan