2012-02-23 37 views
5

Tôi cố gắng để phát hiện xem các tập tin javascript hiện tại đang được thực hiện được bao gồm đồng bộ (thông qua một thẻ script thường xuyên)Làm thế nào để phát hiện xem Javascript của bạn đã được bao gồm đồng bộ hoặc không đồng bộ

<script src="myscript.js"></script> 

hoặc không đồng bộ qua chèn một phần tử tập lệnh vào DOM theo chương trình, giống như

var script = document.createElement('script') 
script.src = 'myscript.js' 
document.body.appendChild(script) 

và do đó có thể sử dụng hay không document.write. Tôi đã tìm ra một giải pháp điên rồ để kiểm tra xem các tác phẩm document.write có hoạt động hay không, xem this gist.

Về cơ bản, nó hoạt động bằng cách sử dụng document.write để viết ra một phần tử - Tôi đã chọn một thẻ tập lệnh trống. Sau đó, nó truy vấn DOM để xác định liệu phần tử script đó đã được viết thành công hay chưa. Nếu nó là - tập lệnh phải được bao gồm đồng bộ, nếu nó không được - nó được đưa vào không đồng bộ.

Giải pháp này hoạt động trong tất cả các trình duyệt mà tôi đã thử nghiệm cho đến nay (tất cả các trình duyệt chính bao gồm IE7 +) ngoại trừ Opera.

Câu hỏi đặt ra là: có giải pháp nào tốt hơn không?

Lưu ý: Tôi cũng đã thử kiểm tra document.readyState, nhưng điều đó dường như không hữu ích trong IE.

Cũng lưu ý: Tôi không cần bài giảng document.write là điều xấu. Tôi biết.

Cập nhật: Hóa ra ngoài không làm việc trên Opera, kỹ thuật của tôi cũng là không đáng tin cậy trong những trường hợp nhất định trong IE và các trình duyệt khác - document.write thể hoặc không thể làm việc tùy thuộc vào thời gian hoặc kịch bản bộ nhớ đệm. Các spec dường như nói nhiều.

+2

Bạn có chắc chắn bạn không cần bài giảng không ??? Tôi đã sẵn sàng để cung cấp cho bạn một ...: P – Domenic

Trả lời

1

điều này là xấu nhưng bạn có thể xác định lại các chức năng của tài liệu và viết các hàm của riêng bạn. một cái gì đó giống như có lẽ đây:

var oldAppendChild = document.body.appendChild; 

document.body.appendChild = function(child) { 
    //examine if child is a script element, do stuff with it if it is 
    //finally do what the original function did and: 
    oldAppendChild(child); 
} 

tất nhiên bạn sẽ cần phải xử lý tất cả những khuyết tật trình duyệt khác nhau và và tất cả các cách khác nhau người ta có thể thêm một yếu tố kịch bản để trang, nhưng nó là một thay thế cho những gì bạn mô tả

+0

Tôi không chắc làm cách nào điều này giúp tôi phát hiện cách tập lệnh được bao gồm. – airportyh

+1

ah có vẻ như tôi đã hiểu lầm. Bạn muốn tập lệnh * thực thi * để biết cách * chính nó * được bao gồm? –

+0

Vâng, đó là chính xác. – airportyh

1

Nếu bạn có toàn quyền kiểm soát tất cả các bên, bạn có thể sử dụng trang máy chủ động cho tham số JS và truy vấn tới url khi cần và sau đó sử dụng để đặt biến bên trong tập lệnh.

var script = document.createElement('script'); 
script.src = 'myscript.php?type=asynch'; 
document.body.appendChild(script); 

Có thể thực hiện điều này tất cả phía máy khách bằng cách kiểm tra thuộc tính "src" của phần tử tập lệnh, nhưng tôi không tích cực về điều đó.

+0

Yup có thể hoạt động. tập lệnh của bạn sẽ cần phải duyệt qua tất cả các phần tử tập lệnh và khớp với URL để tìm kết quả phù hợp. Tôi hy vọng không phải đi tuyến đường này mặc dù. – airportyh

+0

Nếu câu trả lời của tôi hữu ích hoặc chính xác, vui lòng chấp nhận nó để tôi có thể được trao điểm. Bạn chấp nhận bằng cách nhấp vào dấu kiểm được hiển thị bên cạnh câu trả lời. –

0

Vâng, đây là giải pháp nhanh và bẩn. Chúng tôi giả định rằng nếu sự kiện DOMContentLoaded đã kích hoạt, toàn bộ tài liệu bao gồm tất cả các tập lệnh đã được tải. Nếu tập lệnh của bạn được thực thi trước đó, nó đã được thực hiện sắp xếp theo 'định nghĩa của bạn' đồng bộ '. Nếu nó được thực hiện sau đó, nó phải được nạp thông qua một cách khác ('asynchroneously').

Một lần nữa, nhanh chóng và bẩn: Trong tệp html của bạn, tạo thẻ tập lệnh trong đầu; Để tương thích với trình duyệt chéo, tôi tin rằng nó phải là thẻ script đầu tiên trong tệp html của bạn (lưu ý: window.DOMready là falsey nếu không được xác định trong các trình duyệt hiện đại).

<script> 
// this property by default is false 
window.DOMready = false; 

// all browsers but IE<8 
// wait for the DOMContentLoaded event and set window.DOMready to true 
if (document.addEventListener) { 
    document.addEventListener("DOMContentLoaded", function() { 
     window.DOMready = true; 
    }, false); 

} else { 
    // not entirely accurate but functioning in IE<8 
    // you may want to use another IE solution if you care 
    window.onload = function() { 
     window.DOMready = true; 
    } 
} 
</script> 

Sau đó, trong tệp tập lệnh, bạn có thể kiểm tra cửa sổ.DOMready property. Nếu đúng, tập lệnh của bạn đã được tải asynchroneously. Ví dụ:

// myscript.js 
if (window.DOMready) { 
    // we have been loaded asynchroneously 
} else { 
    // we have been loaded synchroneously 
} 

Tận hưởng!

+0

Điều này sẽ không thực sự hoạt động vì một tập lệnh async có thể hoàn tất tải xong trước khi đã có, ví dụ, có một kịch bản tải chậm gần cuối trang. – airportyh

+0

Tập lệnh có thể thực thi bất cứ lúc nào - bạn thường đợi cho dom sẵn sàng sử dụng thư viện trợ giúp như jquery để bạn có thể chắc chắn (các) thành phần đích thực tế trong DOM. –

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