5

Tôi có một mã ví dụ dưới đây, nếu bạn nhấp vào các liên kết, sau đó sử dụng trở lại và chuyển tiếp, mỗi thay đổi trạng thái sẽ gây ra nhiều lần truy cập hơn vào sự kiện 'statechange'. Thay vì cái tôi mong đợi.cách bắt sự kiện thay đổi trạng thái ONCE bằng history.js?

Links:

Code:

<!DOCTYPE html> 
<html> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
    <title>History start</title> 
</head> 
<body> 
    <h1>Headline</h1> 
    <hr> 
    <div id="menu"> 
     <ul> 
      <li> 
       <a href="page-1">Page 1</a> 
       <div style="display:none;"> 
        <h2>Page 1</h2> 
        <p>Content 1</p> 
       </div> 
      </li> 
      <li> 
       <a href="page-2">Page 2</a> 
       <div style="display:none;"> 
        <h2>Page 2</h2> 
        <p>Content 2</p> 
       </div> 
      </li> 
     </ul> 
    </div> 
    <hr> 
    <div id="content"> 
     <h2>Start page</h2> 
     <p>Paragraf</p> 
    </div> 
    <script src="external/jquery-1.6.2.min.js"></script> 
    <script>if (typeof window.JSON === 'undefined') { console.log("Loaded json2"); document.write('<script src="external/json2.js"><\/script>'); }</script> 
    <script src="external/history.adapter.jquery.js"></script> 
    <script src="external/history.js"></script> 
    <script> 
    $(document).ready(function() { 
     History.enabled = true; 

     $('a').each(function() { 
      $(this).click(function(e) { 
       e.preventDefault(); 
       var $link = $(e.target), 
        state = {'href': $link.attr('href'), 'title': $link.html()}, 
        $div = $link.siblings('div'), 
        content = $div.html(); 

       $('#content').html(content); 

       History.pushState(state, state.title, state.href); 

       return false; 
      }); 
     }); 

     History.Adapter.bind(window, 'statechange', function() { 
      var State = History.getState(); 
      // remove double hit on event 
      console.log(State); 

     }); 

    }); 
    </script> 
</body> 
</html> 

Trả lời

6

Đó là bởi vì bạn đang gọi hàm pushState khi bạn tải trang, mà còn gây ra một statechange. Tôi đã ở trong một tình huống tương tự và sử dụng một nhưng boolean trước pushStates của tôi vì vậy tôi biết tôi đã làm một pushState. Có vẻ như thế này ...

historyBool = true; 
History.Adapter.bind(window,'statechange',function(){ // Note: We are using statechange instead of popstate 

var State = History.getState(); // Note: We are using History.getState() instead of event.state 

    //don't run our function when we do a pushState 
    if(historyBool){ 
     historyBool = false; 
     tempFunction = new Function(State.data.ajaxRunFunction); 
     tempFunction(); 
    } 
    historyBool = true; 
}); 

historyBool = false; 
historySet = {ajaxRunFunction: "upc('" + pageID + "','')"}; 
History.pushState(historySet,"",""); 
4

Trong khi không liên quan đến vấn đề cụ thể của bạn, tôi có kịch bản cần hủy bộ xử lý sự kiện khỏi Bộ điều hợp lịch sử. Để làm như vậy, bạn có thể unbind "statechange" sự kiện từ cửa sổ, đó là những gì History.Adapter liên kết với khi bạn gọi History.Adapter.bind():

$(window).unbind('statechange.namespace'); 

Bạn có thể thêm vào một không gian tên cho sự kiện này để tránh unbinding xử lý sự kiện không liên quan khác như trên, hoặc sử dụng một chức năng được đặt tên để unbind chức năng đó đặc biệt. Để sử dụng không gian tên ở trên, bạn sẽ cần phải ràng buộc xử lý bằng cách sử dụng không gian tên tương tự, tức là

History.Adapter.bind(window,'statechange.namespace',function(){...} 
+1

Cảm ơn, tôi đã cố gắng để tìm chức năng unbind trong đối tượng Adapter: / – Tamara

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