Làm cách nào tôi có thể xóa băm vị trí mà không làm cho trang cuộn?


77

Có thể loại bỏ hàm băm window.locationmà không làm cho trang nhảy lên đầu không? Tôi cần có thể sửa đổi hàm băm mà không gây ra bất kỳ bước nhảy nào.

Tôi có cái này:

$('<a href="#123">').text('link').click(function(e) {
  e.preventDefault();
  window.location.hash = this.hash;
}).appendTo('body');

$('<a href="#">').text('unlink').click(function(e) {
  e.preventDefault();
  window.location.hash = '';
}).appendTo('body');

Xem ví dụ trực tiếp tại đây: http://jsbin.com/asobi

Khi người dùng nhấp vào ' liên kết ', thẻ băm được sửa đổi mà không có bất kỳ bước nhảy trang nào, vì vậy điều đó hoạt động tốt.

Nhưng khi người dùng nhấp vào ' hủy liên kết ', thẻ has sẽ bị xóa và cuộn trang sẽ nhảy lên đầu. Tôi cần loại bỏ hàm băm mà không có tác dụng phụ này.


Hãy để tôi đoán: khách hàng của bạn nghĩ rằng hàm băm xấu và đang làm ô nhiễm URL đẹp và sạch có nội dung: http: // www.example.com/ (không có khoảng trắng)?
anddoutoi

Đoán tốt, nhưng không. Tôi có các cửa sổ phương thức có thể đánh dấu dựa trên các url băm và khi người dùng đóng cửa sổ, hàm băm cần phải chạy.
David Hellsing

1
Tôi biết rằng câu hỏi này đã gần 2 năm, nhưng nhận xét này có thể giúp ích cho một độc giả trong tương lai. Nếu bạn thực sự muốn loại bỏ băm, bạn có thể thay đổi url bằng cách sử dụng history.pushState (). developer.mozilla.org/en/DOM/…
dirtymouse

@joshli, thật đáng buồn là nó sẽ không hoạt động IE9.
Tsukimoto Mitsumasa 19/09/12

Câu trả lời:


97

Tôi tin rằng nếu bạn chỉ đặt một hàm băm giả, nó sẽ không cuộn vì không có kết quả phù hợp nào để cuộn đến.

<a href="#A4J2S9F7">No jumping</a>

hoặc là

<a href="#_">No jumping</a>

"#"tự nó tương đương với việc "_top"gây ra cuộn lên đầu trang


12
Không tối ưu, nhưng đủ tốt. Tôi đã sử dụng '# /' với cùng một kết quả.
David Hellsing

window.location.hash = (new_hash === '') ? '_' : new_hash;
tester

Không hài lòng với giải pháp này, còn: stackoverflow.com/questions/19728020/…
stephen

21
Tôi sử dụngwindow.location.hash = "💩";
Aeyoun

37

Tôi sử dụng phần sau trên một số trang web, KHÔNG CÓ JUMPS TRANG!

Thanh địa chỉ sạch đẹp cho các trình duyệt thân thiện với HTML5 và chỉ là dấu # cho các trình duyệt cũ hơn.

$('#logo a').click(function(e){
    window.location.hash = ''; // for older browsers, leaves a # behind
    history.pushState('', document.title, window.location.pathname); // nice and clean
    e.preventDefault(); // no page reload
});

12
history.replaceStatecó thể thích hợp hơn, vì nhấn lại sau đó sẽ quay lại URL hợp lệ cuối cùng .
orlade

Ngoài ra, cần lưu ý rằng mã này đang thiết lập thực hiện hai thay đổi đối với lịch sử điều hướng. Kết quả là khi người dùng nhấn nút quay lại, trước tiên họ sẽ được chuyển đến [url] # và sau đó sẽ yêu cầu nhấp chuột thứ hai để truy cập [url] w / o #. Nếu bạn đang phát triển trải nghiệm nút quay lại, hãy xem xét cách tiếp cận có điều kiện để không đặt trạng thái hai lần.
Vinney Kelly

18

Thuộc tính băm của window.location là ngu ngốc theo một vài cách. Đây là một trong chúng; còn lại là có các giá trị nhận và đặt khác nhau:

window.location.hash = "hello";  // url now reads *.com#hello
alert(window.location.hash);   // shows "#hello", which is NOT what I set.
window.location.hash = window.location.hash; // url now reads *.com##hello

Lưu ý rằng việc đặt thuộc tính băm thành '' cũng sẽ xóa dấu thăng; đó là những gì chuyển hướng trang. Để đặt giá trị của phần băm của url thành '', để lại dấu băm và do đó không làm mới, hãy viết như sau:

window.location.href = window.location.href.replace(/#.*$/, '#');

Không có cách nào để xóa hoàn toàn dấu thăng một khi đã đặt mà không làm mới trang.

CẬP NHẬT 2012:

Như Blazemonger và thinkdj đã chỉ ra, công nghệ đã được cải thiện. Một số trình duyệt cho phép bạn xóa thẻ bắt đầu bằng # đó, nhưng một số thì không. Để hỗ trợ cả hai, hãy thử một số thứ như:

if ( window.history && window.history.pushState ) { 
    window.history.pushState('', '', window.location.pathname) 
} else { 
    window.location.href = window.location.href.replace(/#.*$/, '#'); 
}

2
Không đúng. Các trình duyệt hỗ trợ window.historycho phép bạn thực hiện chính xác điều này.
Blazemonger 20/12/12

@Blazemonger Đúng là như vậy! Bạn có thể sử dụng history.pushState ('', document.title, window.location.pathname);
Deepak Thomas

Nhưng sau đó một lần nữa, nhận xét này được đưa ra vào ngày 10 tháng 2 và các trình duyệt bắt đầu hỗ trợ các pushstates vào khoảng giữa năm 2011
Deepak Thomas

Đoạn mã trên không bảo toàn chuỗi truy vấn. Sử dụngwindow.history.pushState('', '', window.location.pathname + window.location.search);
dipole_moment

3

Đây là một bài đăng cũ nhưng tôi muốn chia sẻ giải pháp của mình Tất cả các liên kết trong dự án của tôi đang được JS xử lý đều có thuộc tính href = "#_ js" (hoặc bất kỳ tên nào bạn chỉ muốn sử dụng cho mục đích đó) và trên trang khởi tạo Tôi làm:

$('body').on('click.a[href="#_js"]', function() {
    return false;
});

Đó sẽ là thủ thuật


2

Đặt window.location.hash thành tên liên kết trống hoặc không tồn tại, sẽ luôn buộc trang chuyển lên đầu. Cách duy nhất để ngăn chặn điều này là lấy vị trí cuộn của cửa sổ và đặt nó lại vị trí đó sau khi thay đổi hàm băm.

Điều này cũng sẽ buộc phải sơn lại trang (không thể tránh nó), mặc dù vì nó được thực thi trong một quy trình js duy nhất nên nó sẽ không nhảy lên / xuống (về mặt lý thuyết).

$('<a href="#123">').text('link').click(function(e) {
    e.preventDefault();
    window.location.hash = this.hash;
}).appendTo('body');

$('<a href="#">').text('unlink').click(function(e) {
    e.preventDefault();
    var pos = $(window).scrollTop(); // get scroll position
    window.location.hash = '';
    $(window).scrollTop(pos); // set scroll position back
}).appendTo('body');

Hi vọng điêu nay co ich.


1
không hoàn toàn chính xác ... đặt băm thành "" sẽ cuộn lên trên cùng, nhưng nếu không có liên kết được đặt tên hoặc phần tử có idthuộc tính phù hợp , trình duyệt sẽ không cuộn.
scunliffe

1

Tôi không chắc liệu điều này có tạo ra kết quả mong muốn hay không, hãy thử:

$('<a href="#">').text('unlink').click(function(e) {
    e.preventDefault();
    var st = parseInt($(window).scrollTop())
    window.location.hash = '';
    $('html,body').css( { scrollTop: st });  
});

Về cơ bản, lưu phần bù cuộn và khôi phục nó sau khi gán giá trị băm trống.


1
nó làm việc cho tôi, ngoại trừ tôi sử dụng $(window).scrollTop(st)thay vì.css()
Thomas Joulin

Đã thử cái này, vì tôi cần thay đổi hàm băm thành #id hiện có. Mọi thứ hoạt động tốt, nhưng khi tôi cố gắng cuộn bằng chuột, sau khi thay đổi hàm băm, cuộn chuyển về không. Bất kỳ ý tưởng về những gì có thể gây ra điều này?
lucascaro

1

Bạn đã thử return false;trong trình xử lý sự kiện chưa? jQuery làm điều gì đó đặc biệt khi bạn làm điều đó, tương tự như AFAIK nhưng có tác động hơn e.preventDefault.


2
return false;trong jQuery và trong trình xử lý sự kiện gốc trong các trình duyệt tuân thủ tương đương với e.preventDefault(); e.stopPropagation();. Tôi không nghĩ rằng ngừng truyền bá sẽ giúp giải quyết vấn đề này.
Jesse Hallett,

0

Hi vọng điêu nay co ich

html

<div class="tabs">
  <ul>
    <li><a href="#content1">Tab 1</a></li>
    <li><a href="#content2">Tab 2</a></li>
    <li><a href="#content3">Tab 3</a></li>
  </ul>
</div>
<div class="content content1">
    <p>1. Content goes here</p>
</div>
<div class="content content2">
    <p>2. Content goes here</p>
</div>
<div class="content content3">
    <p>3. Content goes here</p>
</div>

js

function tabs(){
  $(".content").hide();

  if (location.hash !== "") {
    $('.tabs ul li:has(a[href="' + location.hash + '"])').addClass("active");
    var hash = window.location.hash.substr(1);
    var contentClass = "." + hash;
    $(contentClass).fadeIn();
  } else {
    $(".tabs ul li").first().addClass("active");
    $('.tabs').next().css("display", "block");
  }
}
tabs();

$(".tabs ul li").click(function(e) {
  $(".tabs ul li").removeAttr("class");
  $(this).addClass("active");
  $(".content").hide();
  var contentClass = "." + $(this).find("a").attr("href").substr(1);
  $(contentClass).fadeIn();
  window.location.hash = $(this).find("a").attr("href");
  e.preventDefault();
  return false;
});

URL không có bất kỳ hàm băm nào.
http://output.jsbin.com/tojeja

URL có thẻ bắt đầu bằng # không chuyển sang neo.
http://output.jsbin.com/tojeja#content1

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.