2012-05-17 35 views
6

Tôi đang làm việc trên một dự án nhỏ mà tôi muốn tạo một trang web theo phong cách Ajax. Nội dung được tải bằng số load() của jQuery. Như một số bạn đã biết, mặt trái của điều này là URL không thay đổi tương ứng với nội dung được hiển thị. Để thực hiện công việc này, bạn có thể sử dụng pushState(). Vì đây không phải là trình duyệt được hỗ trợ, tôi đã sử dụng trình cắm thêm history.js.pushState() và popState(): thao tác lịch sử của trình duyệt

Điều này hoạt động khá độc đáo, nhưng vấn đề là các nút quay lại và tiến của tôi không hoạt động như chúng cần và tôi không biết mình đang làm gì sai. URL đang thay đổi chính xác và nội dung cũng vậy, nhưng tiêu đề không thay đổi chút nào. Với tiêu đề tôi có nghĩa là những gì được hiển thị dưới dạng tiêu đề của cửa sổ (hoặc tab) của cửa sổ trình duyệt. I E. <title> của trang được tải HOẶC thuộc tính tiêu đề của liên kết đề cập đến trang đó (chúng giống nhau). Tôi nghĩ rằng nó đã làm với thực tế là tôi chỉ gọi một phần của trang có tiêu đề tôi cần (tức là bằng cách thêm #content vào load()). Tuy nhiên, tôi vẫn muốn tiêu đề của trang đó. Đây là một trường hợp thử nghiệm của những gì tôi có cho đến bây giờ. (Không có sẵn nữa kể từ ngày 28 tháng 12 năm 2013.) tập tin jQuery:

$(document).ready(function() { 
    var firstLink = $("ul > li:first-child > a"); 
    var menuLink = $("ul > li > a"); 
    var firstLoadedHtml = firstLink.attr("href") + " #content"; 

    $("#sectionContainer").hide().load(firstLoadedHtml).fadeIn("fast"); 
    firstLink.addClass("active"); 

    menuLink.click(function(e) { 
     history.pushState(null, null, this.href); 

     e.preventDefault(); 
     e.stopImmediatePropagation(); 

     var CurLink = $(this); 
     var newLoadedHtml = CurLink.attr("href") + " #content"; 
     var oldSection = $(".contentPage"); 

     $("#sectionContainer").hide().load(newLoadedHtml).fadeIn("fast"); 
     menuLink.removeClass("active"); 
     CurLink.addClass("active"); 
    }); 

    $(window).bind('popstate', function() { 
      var returnLocation = history.location || document.location; 

      $('#sectionContainer').load(returnLocation + "#content"); 
    }); 
}); 

tôi cũng lưu ý rằng khi đi trở lại trang cơ bản (ví dụ/sectionLoaderTest /) nó trở nên trống rỗng một lúc và chỉ sau một thời gian nội dung của trang đầu tiên được tải. Có cách nào để tối ưu hóa điều này không?

Ngoài ra, tôi đang sử dụng jQuery để thêm lớp đang hoạt động vào liên kết đã được nhấp. Làm thế nào tôi có thể chắc chắn rằng điều này thay đổi cho phù hợp với lịch sử? Để liên kết chính xác được đánh dấu khi người dùng điều hướng trở lại?

Vì vậy, ba câu hỏi là:

  1. Lấy tên tạm thời khi đi về phía trước và lạc hậu
  2. Tối ưu hóa thời gian tải của mainpage
  3. Fix các hoạt động lớp khi đi về phía trước và lạc hậu

Tất cả trợ giúp đều được chào đón!

GHI CHÚ 1: Tôi muốn xây dựng trên history.js và kịch bản của riêng tôi và như vậy giữ hỗ trợ cho < HTML5 trình duyệt. Tôi thích điều này bởi vì 1. Tôi biết điều này phải làm việc, chỉ có một cái gì đó đó là đi sai. 2. Nó sẽ tiết kiệm thời gian nếu tôi có thể xem giải pháp của một người và thực hiện nó trong kịch bản mà tôi đã viết thay vì tìm ra một kịch bản hoàn toàn mới.

LƯU Ý 2: Tiền thưởng sẽ chỉ được trao cho người có thể trả lời tất cả các câu hỏi của tôi (3)!

+0

Bạn vẫn không đúng, xem ví dụ tại đây http://stackoverflow.com/questions/6622449/why-is-history-pushstate-not-supported-in-ie-are-there-some -other-ways-to-ach/9470183 # 9470183 – devote

+0

Nhận xét của bạn không thực sự hữu ích. Tôi không cần phải thực hiện history.js (chưa), tôi chỉ đang cố gắng hiểu những gì pushState đang làm bây giờ. Tôi muốn khắc phục sự cố này. –

+0

Nhận xét của tôi chỉ ra sai lầm của bạn, cách chọn phương pháp xử lý sự kiện.Phương pháp chặn popstate sự kiện, bạn đã đăng không chính xác, loại bỏ nó khỏi phương thức hoạt động khi được nhấp. – devote

Trả lời

11

trả lời 1 - Lấy tên tạm thời khi đi về phía trước và lạc hậu

Theo như tôi hiểu bạn muốn thay đổi html tiêu đề tài liệu từ liên kết được nạp trong một div. Khi bạn đang tải một tệp trong div qua jQuery .load, bạn chỉ cần chèn văn bản trả lời đầy đủ sau một yêu cầu ajax trong đó. Vì vậy, với tất cả những thứ không nên nằm trong div như thẻ title hoặc meta. Tuy nhiên, tiêu đề của tài liệu hiện tại (http://bramvanroy.be/sectionLoaderTest/index.html) được xác định trong title nằm trong thẻ head và không nằm trong thẻ title bên trong div vì vậy đó là lý do tại sao tiêu đề tài liệu không thay đổi.

Vậy làm cách nào để khắc phục sự cố?

Tốt câu hỏi, bởi vì các yếu tố bên trong title một yếu tố div là không hợp lệ, hầu hết các trình duyệt sẽ loại bỏ nó nên bạn không thể chỉ cần sử dụng này:

document.title = $("#sectionContainer title").text(); 

vì các yếu tố title có thể không tồn tại.

Vì vậy, những gì chúng tôi cần là phản hồi trực tiếp từ hàm jQuery .load. Tôi có thể lấy nó bằng cách thêm tham số callback để chức năng:

$("#sectionContainer") 
    .hide() 
    .load(newLoadedHtml, function(responseText) { 
     document.title = $(responseText).filter("title").text(); 
    }) 
    .fadeIn("fast"); 

Những gì bạn có thể không hiểu là tại sao tôi sử dụng .filter và không phải là .find chức năng. Điều này là do jQuery phân tích các thẻ html, headbody ra khỏi html nhưng không loại bỏ các phần tử con đó.

trả lời 2 - Tối ưu hóa thời gian tải của mainpage

Một tài liệu được nhận được nạp từ lên đầu để phía dưới.

Vì vậy, trước hết, css, JavaScript, v.v. nên được tải và sau đó là tài liệu chính. Vì jQuery luôn chờ đợi tài liệu trước khi thực thi nó sẽ không phải là một ý tưởng rất tồi khi đặt tất cả các thành phần script của bạn ngay trước khi kết thúc phần thân, để HTML của bạn có thể được tải trước đó.

BtW Tôi chỉ gặp vấn đề này ở lần đầu tiên sau khi mọi thứ được lưu vào bộ nhớ cache và tài liệu đang tải rất nhanh.

Trả lời 3 - Fix các hoạt động lớp khi đi về phía trước và lạc hậu

tôi sẽ nói lặp trough href thuộc tính của a yếu tố và so sánh nó với các dữ liệu từ History.getState(). Nên dễ dàng.

Bạn đã một số lỗi trong mã của bạn - Mã cố định của bạn:

Bạn nối băm #content để tất cả các URL .. nó không có ý nghĩa và nó sẽ được gỡ bỏ bởi jQuery một lần nữa: https://github.com/jquery/jquery/blob/master/src/ajax.js#L617 (Đi kèm từ dòng: 158, 190, 337, 617 - rhash là trên dòng 6)

$(document).ready(function() { 
    var firstLink = $("ul > li:first-child > a"); 
    var menuLink = $("ul > li > a"); 
    var firstLoadedHtml = firstLink.attr("href"); 

    $("#sectionContainer").hide().load(firstLoadedHtml).fadeIn("fast"); 
    firstLink.addClass("active"); 

    menuLink.click(function(e) { 

     e.preventDefault(); 
     e.stopImmediatePropagation(); 

     var newLoadedHtml = $(this).attr("href"); 

     History.pushState(null, newLoadedHtml, newLoadedHtml); 

     $("#sectionContainer") 
      .hide() 
      .load(newLoadedHtml, function(responseText) { 
       document.title = $(responseText).filter("title").text(); 
      }) 
      .fadeIn("fast"); 
    }); 

    History.Adapter.bind(window, "statechange", function() { 
     menuLink.removeClass("active"); 
     $("a[href='" + History.getState().title + "']").addClass("active"); 
     $('#sectionContainer').load(document.location.href, function(responseText) { 
      document.title = $(responseText).filter("title").text(); 
     }); 
    }); 
}); 
+0

Tôi có thể bỏ lỡ một thứ gì đó (khá bận rộn với rất nhiều thứ cùng một lúc) nhưng nó không hoạt động. Tiêu đề về các thay đổi trên liên kết đầu tiên và cuối cùng đến liên kết được xác định trong 'bao gồm'. Ngoài ra (và quan trọng hơn) các nút quay lại không thay đổi nội dung nữa. Tôi có cảm giác đó là một điều rất cơ bản mà tôi đang nhìn qua. Trường hợp thử nghiệm đã được chỉnh sửa: http://bramvanroy.be/sectionLoaderTest/ –

+0

Trang đầu tiên ('Home') có tiêu đề tốt trên tài liệu, tất cả các trang khác đều có tiêu đề 'Untitled Document' làm tiêu đề. Xin lỗi bạn nói đúng, nó không làm thay đổi nội dung trên lịch sử quay lại/chuyển tiếp nữa. Đó là vì 'document.location' là một đối tượng và bạn cần một chuỗi, trước khi nó là' document.location + "#content" 'Nó trả về một chuỗi. Vì vậy, bạn cần 'document.location.href', hãy xem bản chỉnh sửa của tôi. – noob

+1

Sau khi tất cả tôi đã thực hiện một chỉnh sửa mới sẽ hoạt động! ** KIỂM TRA ** Ngay cả liên kết chính xác sẽ luôn luôn có lớp 'hoạt động'! – noob

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