2009-09-09 34 views
24

Đây là tình huống. Tôi có một số javascript trông như thế này:Bắt buộc làm mới DOM trong trình khám phá Internet sau khi thao tác với javascript dom

function onSubmit() { 
    doSomeStuff(); 
    someSpan.style.display="block"; 
    otherSpan.style.display="none"; 
    return doLongRunningOperation; 
} 

Khi tôi làm cho một hình thức nộp hành động, và chạy nó từ một trình duyệt không phải IE, nó nhanh chóng hoán đổi khả năng hiển thị hai nhịp và chạy các hoạt động javascript dài. Nếu tôi làm điều này trong IE, nó sẽ không thực hiện hoán đổi cho đến khi onSubmit() trả về hoàn toàn.

tôi có thể buộc một dom vẽ lại bằng cách dán một hộp cảnh báo trong như vậy:

function onSubmit() { 
    doSomeStuff(); 
    someSpan.style.display="block"; 
    otherSpan.style.display="none"; 
    alert("refresh forced"); 
    return doLongRunningOperation; 
} 

Ngoài ra, jquery refactoring rõ ràng không ảnh hưởng đến hành vi của IE:

function onSubmit() { 
    doSomeStuff(); 
    $("#someSpan").show(); 
    $("#otherSpan").hide(); 
    return doLongRunningOperation; 
} 

Hành vi này tồn tại trên IE8 và IE6. Có anyway để buộc vẽ lại DOM trong các trình duyệt này không?

+0

Thứ nhất, bạn đang làm gì trong longRunningOperation? –

+0

Bạn đã thử di chuyển chế độ hiển thị chuyển sang chức năng riêng của nó chưa? – seth

+0

longRunningOperation đang thực hiện xác thực biểu mẫu. Biểu mẫu lớn trong một nhóm nhỏ các trường hợp. –

Trả lời

2

longRunningOperation của bạn có thể được gọi là không đồng bộ?

+1

Bạn đã kết thúc đúng, nhưng với một số công việc. Tôi gọi là hoạt động chạy dài không đồng bộ, có sự kiện gửi trả về false, và sau đó sự kiện async thực sự gửi biểu mẫu của tôi. Điều này dẫn đến hành vi thích hợp trong tất cả các trình duyệt, nhưng mất rất nhiều công việc và kinda cảm thấy kludgy. –

+1

Nó có thể cảm thấy kludgy, nhưng thiết kế tốt nhất của phía máy khách của ứng dụng của bạn sẽ là một thiết kế giúp trình duyệt đáp ứng. Khi bạn bắt đầu quá trình chạy dài, bạn sẽ treo trình duyệt (KHÔNG lớn!) Vì vậy tốt nhất là dành thời gian thiết kế cách quản lý các hoạt động không đồng bộ. Anyways .. vui chơi! – misteraidan

17

Mozilla (có thể là IE) sẽ cache/trì hoãn thực hiện thay đổi đối với DOM ảnh hưởng đến hiển thị, để nó có thể tính toán tất cả thay đổi cùng một lúc thay vì lặp đi lặp lại sau mỗi câu lệnh.

Để bắt buộc cập nhật (để buộc chỉnh lại hoặc chuyển tiếp đồng bộ ngay lập tức), javascript của bạn nên đọc thuộc tính bị ảnh hưởng bởi thay đổi, ví dụ: vị trí của someSpan và otherSpan.

(chi tiết thi hành Mozilla này được đề cập trong đoạn video Faster HTML and CSS: Layout Engine Internals for Web Developers.)

+0

thú vị. không biết điều này. –

+0

Tôi sẽ thử tính năng AM. –

+0

Tôi đã thử điều này, nhưng không thể làm cho nó hoạt động. –

3

Bạn cũng có thể bọc hàm dài hạn trong một hàm setTimeout (function() {longTerm();}, 1);

6

Để tiếp tục những gì ChrisW nói:

đây là tập lệnh khởi động cho flash DOM, vì vậy bạn không phải gọi cảnh báo (""); (Tìm thấy tại http://amolnw.wordpress.com/category/programming/javascript/):

function flushThis(id){ 
    var msie = 'Microsoft Internet Explorer'; 
    var tmp = 0; 
    var elementOnShow = document.getElementById(id); 
    if (navigator.appName == msie){ 
     tmp = elementOnShow.parentNode.offsetTop + 'px'; 
    }else{ 
     tmp = elementOnShow.offsetTop; 
    } 
} 

Nó làm việc cho tôi !!! Cảm ơn mẹo.

5

Tôi gặp sự cố này trong Chrome 21 kéo một từ có chữ cái có dấu ('g'). Nó để lại một vệt bụi sâu phía sau trên màn hình, thứ sẽ biến mất vào lần sau khi có thứ gì đó làm cho màn hình trở nên tươi mới. Giải pháp của ChrisW (thẩm vấn một thuộc tính nhạy cảm với bố cục) không hoạt động.

gì đã làm công việc là để thêm một 1-pixel div trống ở phía trên cùng của trang, sau đó loại bỏ nó một phần nghìn giây sau, bằng cách gọi sau chức năng ở phần cuối của các hoạt động kéo:

// Needed by Chrome, as of Release 21. Triggers a screen refresh, removing drag garbage. 
function cleanDisplay() { 
    var c = document.createElement('div'); 
    c.innerHTML = 'x'; 
    c.style.visibility = 'hidden'; 
    c.style.height = '1px'; 
    document.body.insertBefore(c, document.body.firstChild); 
    window.setTimeout(function() {document.body.removeChild(c)}, 1); 
} 

Lưu ý: Bạn cần sự chậm trễ. Chỉ cần thêm và xóa div không hoạt động. Ngoài ra, cần thêmphía trên phần của trang cần vẽ lại.

+0

Giải pháp này có tốt hơn là chỉ gọi chức năng không đồng bộ như tôi đã làm không? –

+0

Đã xảy ra sự cố với làm mới màn hình trong IE10 và điều này đã thực hiện mẹo, không giống như các mẹo khác. –

+1

IE8 tại đây. Đây là giải pháp duy nhất có hiệu quả đối với tôi. Cảm ơn. –

1

element.focus() làm việc cho tôi trong IE10

function displayOnOff(){ 
    var elm = document.getElementById("myDiv"); 
    elm.style.display="block"; 
    elm.focus(); 
    for(var i=0; i<1000000; i++){ 
     console.log("waiting..............."); 
    } 
    elm.style.display = "none"; 
} 
Các vấn đề liên quan