17

Tôi có một số mã (được viết bởi một nhà phát triển khác) đang thực hiện tải trang AJAX bên trong WordPress (ví dụ: không tải lại trang) khi bạn nhấp vào mục điều hướng, làm mới AJAX vùng nội dung chính. Vấn đề của tôi là nó bị hỏng trong IE7 và tôi không biết bắt đầu từ đâu về gỡ lỗi.Nhận sự kiện hashchange để làm việc trong tất cả các trình duyệt (bao gồm IE7)

Các dòng mở ban đầu là

var queue = 0; 

$('document').ready(function() { 
    window.addEventListener("hashchange", hashChange, false); 

    // Define window location variables 
    var windowHost = window.location.host, 
     windowHash = window.location.hash, 
     windowPath = window.location.pathname; 

Nhưng tôi đã thay đổi chúng để làm cho addEventListener có điều kiện về cơ sở cho dù phương pháp đó đã có mặt hay không. Một số nghiên cứu đã nói với tôi rằng phương pháp này không có sẵn trong các phiên bản IE cũ hơn (ví dụ 7 trong trường hợp của tôi). Ngoài ra, giao diện điều khiển gỡ lỗi IE7 đã xác định rằng đó là một phương thức không khả dụng, vì vậy điều đó khá rõ ràng. Tôi viết lại những dòng như sau, nhưng mã vẫn chưa làm việc:

var queue = 0; 

$('document').ready(function() { 
    if(window.addEventListener) { 
     window.addEventListener("hashchange", hashChange, false); 
    } 
    else if (window.attachEvent) { 
     window.attachEvent("hashchange", hashchange, false);  
    } 
    // Define window location variables 
    var windowHost = window.location.host, 
     windowHash = window.location.hash, 
     windowPath = window.location.pathname; 

Kịch bản đầy đủ ban đầu có thể được xem trong pastebin này: http://pastebin.com/Jc9ySvrb

Trả lời

30
  • attachEvent đòi hỏi sự kiện được bắt đầu bằng on.
  • Bạn đã viết hoa khác nhau cho phương pháp. Thay đổi hashchange trong attachEvent thành hashChange để nhận sự kiện hoạt động trong IE8.
  • Sử dụng triển khai được đề xuất để hỗ trợ triển khai hashchange cho IE7- và các trình duyệt cũ khác.

Tôi đã tạo triển khai trình duyệt chéo, bổ sung thêm tính năng hashchange cho trình duyệt, ngay cả những người thực hiện not support. Dự phòng dựa trên the specification.

//function hashchange is assumed to exist. This function will fire on hashchange 
if (!('onhashchange' in window)) { 
    var oldHref = location.href; 
    setInterval(function() { 
     var newHref = location.href; 
     if (oldHref !== newHref) { 
      var _oldHref = oldHref; 
      oldHref = newHref; 
      hashChange.call(window, { 
       'type': 'hashchange', 
       'newURL': newHref, 
       'oldURL': _oldHref 
      }); 
     } 
    }, 100); 
} else if (window.addEventListener) { 
    window.addEventListener("hashchange", hashChange, false); 
} 
else if (window.attachEvent) { 
    window.attachEvent("onhashchange", hashChange);  
} 

Lưu ý: Mã này rất hữu ích cho một hashchange kiện. Nếu bạn muốn thêm nhiều bộ xử lý hashchange, hãy sử dụng phương pháp sau.
Định nghĩa hai hàm, addHashChangeremoveHashChange. Cả hai phương thức đều có chức năng như một đối số.

(function() { 
    if ('onhashchange' in window) { 
     if (window.addEventListener) { 
      window.addHashChange = function(func, before) { 
       window.addEventListener('hashchange', func, before); 
      }; 
      window.removeHashChange = function(func) { 
       window.removeEventListener('hashchange', func); 
      }; 
      return; 
     } else if (window.attachEvent) { 
      window.addHashChange = function(func) { 
       window.attachEvent('onhashchange', func); 
      }; 
      window.removeHashChange = function(func) { 
       window.detachEvent('onhashchange', func); 
      }; 
      return; 
     } 
    } 
    var hashChangeFuncs = []; 
    var oldHref = location.href; 
    window.addHashChange = function(func, before) { 
     if (typeof func === 'function') 
      hashChangeFuncs[before?'unshift':'push'](func); 
    }; 
    window.removeHashChange = function(func) { 
     for (var i=hashChangeFuncs.length-1; i>=0; i--) 
      if (hashChangeFuncs[i] === func) 
       hashChangeFuncs.splice(i, 1); 
    }; 
    setInterval(function() { 
     var newHref = location.href; 
     if (oldHref !== newHref) { 
      var _oldHref = oldHref; 
      oldHref = newHref; 
      for (var i=0; i<hashChangeFuncs.length; i++) { 
       hashChangeFuncs[i].call(window, { 
        'type': 'hashchange', 
        'newURL': newHref, 
        'oldURL': _oldHref 
       }); 
      } 
     } 
    }, 100); 
})(); 
// Usage, infinitely many times: 
addHashChange(function(e){alert(e.newURL||location.href);}); 
+0

+1 aha snap đã bỏ lỡ! – gideon

+2

Trình nghe sự kiện bị ràng buộc chính xác ngay bây giờ, nhưng sẽ không làm bất cứ điều gì trong IE7, bởi vì nó [không được hỗ trợ] (http://caniuse.com/hashchange). [IE8 không hỗ trợ] (http://msdn.microsoft.com/en-us/library/cc891506 (v = vs.85) .aspx) sự kiện 'hashchange' mặc dù. Đối với IE7, bạn phải phát hiện hashchanges thông qua 'setInterval'. –

+0

Vâng bạn chắc chắn kiếm được danh tiếng của bạn ở đây @RobW - cảm ơn một triệu. Bạn chỉ cần tiết kiệm cho tôi giờ, tôi thành thật không biết nếu nó có giá trị đi qua toàn bộ 'setInterval' điều. Trông giống như một cơn đau đầu lớn. – Brian

3

attachEvent mất trên hai params:

bSuccess = object.attachEvent(sEvent, fpNotify) 

[Và cần thiết cho tất cả các phiên bản IE dưới IE9! :(Xem MDN reference ]

Điều này có thể làm việc:.

if(window.addEventListener) { 
    window.addEventListener("hashchange", hashChange, false); 
} 
else if (window.attachEvent) { 
    window.attachEvent("onhashchange", hashchange);//SEE HERE... 
    //missed the on. Fixed thanks to @Robs answer. 
} 

Tất nhiên nếu có thể, bạn nên chỉ cần sử dụng JQuery, vì nó gói gọn tất cả điều này cho bạn

Và như mọi khi có một plugin trên mạng: http://benalman.com/projects/jquery-hashchange-plugin/

+2

Điều đó thật tuyệt vời, cảm ơn bạn đã tipoff. Câu hỏi: Ngay cả trong chế độ gỡ lỗi JS IE7, tôi không nhận được bất kỳ lỗi nào từ chính hàm đó (chỉ có 'addEventListener' trước khi tôi thực hiện nó có điều kiện). Bất kỳ đề xuất nào khác để gỡ lỗi? Tôi đã thử mã của bạn nhưng vẫn không có súc sắc ...bực bội, không có lỗi:/ – Brian

+0

hey nhìn vào câu trả lời @Robs !! – gideon

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