2013-08-23 40 views
8

Giả sử tôi có tiện ích mở rộng khi bạn truy cập trang video YouTube. Tôi đã nhận thấy rằng khi điều hướng qua lại bằng nút Chrome, tiện ích mở rộng có thể giành được nhiều nhất không tải.Tiện ích mở rộng của Chrome không tải trên điều hướng của trình duyệt tại YouTube

Ví dụ, tôi có 2 tác phẩm, biểu hiện:

{ 
    "name": "back forth", 
    "version": "0.1", 
    "manifest_version": 2, 
    "description": "back forth", 
    "permissions": ["storage", "*://www.youtube.com/watch*"], 
    "content_scripts": [ 
     { 
      "matches": ["*://www.youtube.com/watch*"], 
      "js": ["contentscript.js"] 
     } 
    ] 
} 

và contentscript

alert("loaded"); 

Cảnh báo không phải lúc nào xuất hiện khi điều hướng qua lại. Làm thế nào tôi có thể khắc phục điều này, để phần mở rộng tải mỗi lần?

+0

Tương tự http://stackoverflow.com/a/34100952/72321 – Dennis

Trả lời

17

YouTube đã bắt đầu dùng thử với điều hướng dựa trên pushState. Nói chung, các điều hướng như vậy chỉ có thể được phát hiện trong các tập lệnh nội dung bằng cách tiêm mã chặn cuộc gọi đến history.replaceState/history.pushState (hoặc bằng cách sử dụng sự kiện chrome.webNavigation.onHistoryStateUpdated trong trang nền).

Phần còn lại của câu trả lời này dành riêng cho YouTube.
YouTube hiển thị thanh tiến trình (màu đỏ) ở đầu trang trong khi tải. Thanh tiến trình này là hoạt ảnh bằng cách sử dụng chuyển đổi CSS. Vì bong bóng sự kiện chuyển tiếp, bạn có thể liên kết trình xử lý sự kiện chuyển đổi thành <body> và kiểm tra điều hướng trong các trường hợp này.

Bạn phải chèn tập lệnh nội dung của mình tại *://www.youtube.com/* thay vì *://www.youtube.com/watch*, vì có thể sử dụng pushState để điều hướng từ / đến /watch...

function afterNavigate() { 
    if ('/watch' === location.pathname) { 
     alert('Watch page!'); 
    } 
} 
(document.body || document.documentElement).addEventListener('transitionend', 
    function(/*TransitionEvent*/ event) { 
    if (event.propertyName === 'width' && event.target.id === 'progress') { 
     afterNavigate(); 
    } 
}, true); 
// After page load 
afterNavigate(); 

Lưu ý: Phương pháp này phụ thuộc vào thực tế là thanh tiến trình được chèn vào. Bất cứ khi nào Google quyết định đổi tên ID của thanh tiến trình hoặc xóa toàn bộ thanh tiến trình, mã của bạn sẽ ngừng hoạt động.

Lưu ý 2: Tính năng này chỉ hoạt động đối với các tab đang hoạt động. Nếu bạn cần phát hiện các thay đổi điều hướng trong khi tab không được tập trung, thì bạn cần phải ràng buộc sự kiện window.onfocuswindow.onblur và kiểm tra xem document.title có thay đổi giữa các sự kiện này hay không.

+0

Cảm ơn câu trả lời này. Sử dụng phương thức này nó hoạt động nhưng nó không sớm như DOMContentLoaded, có vẻ như nó tương đương với 'load', có cách nào để phát hiện điểm giống như DOMContentLoaded'? – Noitidart

+1

@Noitidart Nếu bạn thực sự muốn được thông báo càng sớm càng tốt, bạn có thể liên kết với sự kiện 'transitionstart', cuộc thăm dò thay đổi tài liệu (sử dụng' setTimeout' hoặc 'setInterval'). Khi bạn đã tìm thấy phần tử mong muốn, hãy hủy đăng ký sự kiện chuyển tiếp + dừng bỏ phiếu + gọi lại cuộc gọi lại tùy chỉnh của bạn. Để đảm bảo rằng bạn không lãng phí các chu kỳ CPU, hãy kết hợp điều này với sự kiện chuyển tiếp; nếu logic bỏ phiếu của bạn không phát hiện bất cứ điều gì tại thời điểm đó, hãy loại bỏ các trình lắng nghe sự kiện, dừng poller và gọi lại cuộc gọi lại. –

+0

Ý tưởng thiên tài @RobW cảm ơn! Tôi đã thử thêm 'window.onpopstate = function (e) {console.log (e)}' tôi nghĩ rằng sẽ làm các trick nhưng im không nhận được bất kỳ callbacks cho nó. – Noitidart

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