Làm cách nào bạn có thể kiểm tra #hash trong URL bằng JavaScript?


783

Tôi có một số mã jQuery / JavaScript mà tôi muốn chạy chỉ khi có một #liên kết neo băm ( ) trong một URL. Làm thế nào bạn có thể kiểm tra ký tự này bằng JavaScript? Tôi cần một thử nghiệm bắt tất cả đơn giản để phát hiện các URL như sau:

  • example.com/page.html#anchor
  • example.com/page.html#anotheranchor

Về cơ bản một cái gì đó dọc theo dòng:

if (thereIsAHashInTheUrl) {        
    do this;
} else {
    do this;
}

Nếu bất cứ ai có thể chỉ cho tôi đi đúng hướng, điều đó sẽ được đánh giá cao.

Câu trả lời:


1405

Đơn giản:

if(window.location.hash) {
  // Fragment exists
} else {
  // Fragment doesn't exist
}

42
Bổ sung: đối tượng .location chỉ khả dụng trên URL của cửa sổ hiện tại, bạn không thể làm điều này cho một URL tùy ý (ví dụ: một được lưu trữ trong một biến chuỗi)
Gareth

64
Ngoài ra, các thuộc tính vị trí như .hash và .query cũng có sẵn trên <a> phần tử
Gareth

19
.searchcó sẵn trên một <a>, không .query. Mẫu jQuery : $("<a/>").attr({ "href": "http://www.somewhere.com/a/b/c.html?qs=1#fragmenttest" })[0]. .hash => "#fragmenttest".search= ?qs=1. Từ đó, đánh lên câu hỏi trích xuất chuỗi truy vấn để lấy thứ gì đó ngoài chuỗi.
patridge

1
@hitautodesturation: câu hỏi này không phải là về những thay đổi đối với hàm băm, chỉ là liệu nó có xuất hiện trên tải trang hay không.
Gareth

2
@Gareth Vâng, bạn nói đúng. Chỉ cần nhận ra rằng các liên kết tôi đăng là cho hashchangesự kiện và không window.location.hash. Mặc dù cái sau không được IE hỗ trợ <8.
hitautodesturation

334
  if(window.location.hash) {
      var hash = window.location.hash.substring(1); //Puts hash in variable, and removes the # character
      alert (hash);
      // hash found
  } else {
      // No hash found
  }

54

Đặt như sau:

<script type="text/javascript">
    if (location.href.indexOf("#") != -1) {
        // Your code in here accessing the string like this
        // location.href.substr(location.href.indexOf("#"))
    }
</script>

1
Cảm ơn, window.location.hash chỉ có một giá trị nếu có một giá trị theo sau #. ví dụ. //www.example.com# trả về '' khi kiểm tra hàm băm.
Jessy

33

Nếu URI không phải là vị trí của tài liệu, đoạn trích này sẽ làm những gì bạn muốn.

var url = 'example.com/page.html#anchor',
    hash = url.split('#')[1];

if (hash) {
    alert(hash)
} else {
    // do something else
}

+1 cho Javascript không biết giới hạn là gì :)
Dunc

2
@Dunc: Các mảng JS về cơ bản là các Đối tượng. Truy cập chúng theo chỉ mục cũng giống như truy cập một thuộc tính Object như vậy : obj['0']. Trong JS, điều này là đúng: arr[0] === arr['0']Do đó, nếu chỉ mục / khóa không tồn tại, giá trị trả về không được xác định thay vì nằm ngoài giới hạn. jsfiddle.net/web5me/Mw376
Marc

21

Bạn đã thử điều này?

if (url.indexOf('#') !== -1) {
    // Url contains a #
}

( urlRõ ràng URL bạn muốn kiểm tra ở đâu.)


17
$('#myanchor').click(function(){
    window.location.hash = "myanchor"; //set hash
    return false; //disables browser anchor jump behavior
});
$(window).bind('hashchange', function () { //detect hash change
    var hash = window.location.hash.slice(1); //hash to string (= "myanchor")
    //do sth here, hell yeah!
});

Điều này sẽ giải quyết vấn đề;)


Thích câu trả lời này vì đã trộn lẫn JS + JQ, trình duyệt chéo và giải pháp đơn giản, đã triển khai phương pháp này.
Arthur Kushman



6

Dưới đây là những gì bạn có thể làm để định kỳ kiểm tra sự thay đổi của hàm băm và sau đó gọi một hàm để xử lý giá trị băm.

var hash = false; 
checkHash();

function checkHash(){ 
    if(window.location.hash != hash) { 
        hash = window.location.hash; 
        processHash(hash); 
    } t=setTimeout("checkHash()",400); 
}

function processHash(hash){
    alert(hash);
}

11
đó chỉ là không cần thiết trong tức là 6 + 7. Al các trình duyệt khác đã bao gồm sự kiện
onhashchange

@Tokimon - tuyệt vời! Tôi không biết điều đó. Nhưng tôi đoán chúng ta vẫn phải hỗ trợ các phiên bản IE cũ
Emmanuel

1
Vâng thật đáng buồn ... Ngay cả IE 8 cũng sẽ không biến mất vì IE 9 không được hỗ trợ trên XP :(
Tokimon

1
modernizr.com dụng cụ sự kiện hashchange trên các trình duyệt cũ (cùng với một loạt các tính năng hiện đại khác)
guigouz

4
Đây hoàn toàn không phải là một mã được đề xuất: ít nhất nó phải là : setTimeout(checkHash, 400). Thêm vào đó, các trình duyệt hiện đại có hashchangesự kiện để bạn có thể làm window.addEventListener('hashchange', function(){ … }). Cuối cùng, rò rỉ hashbiến toàn cục là một thực tiễn không được khuyến nghị khác, ngay cả đối với một ví dụ.
Oncle Tom

5

Hầu hết mọi người đều biết các thuộc tính URL trong document.location. Thật tuyệt nếu bạn chỉ quan tâm đến trang hiện tại. Nhưng câu hỏi là về việc có thể phân tích các neo trên một trang chứ không phải chính trang đó.

Điều mà hầu hết mọi người dường như bỏ lỡ là các thuộc tính URL tương tự cũng có sẵn cho các phần tử neo:

// To process anchors on click    
jQuery('a').click(function () {
   if (this.hash) {
      // Clicked anchor has a hash
   } else {
      // Clicked anchor does not have a hash
   }
});

// To process anchors without waiting for an event
jQuery('a').each(function () {
   if (this.hash) {
      // Current anchor has a hash
   } else {
      // Current anchor does not have a hash
   }
});

5
function getHash() {
  if (window.location.hash) {
    var hash = window.location.hash.substring(1);

    if (hash.length === 0) { 
      return false;
    } else { 
      return hash; 
    }
  } else { 
    return false; 
  }
}

3
Không nên là "hash.length" trái ngược với "hash.length ()"? :)
Nathan Pitman

4
var requestedHash = ((window.location.hash.substring(1).split("#",1))+"?").split("?",1);

3

Nhận xét của Partridge và Gareths ở trên là tuyệt vời. Họ xứng đáng có một câu trả lời riêng biệt. Rõ ràng, các thuộc tính băm và tìm kiếm có sẵn trên bất kỳ đối tượng Liên kết html nào:

<a id="test" href="foo.html?bar#quz">test</a>
<script type="text/javascript">
   alert(document.getElementById('test').search); //bar
   alert(document.getElementById('test').hash); //quz
</script>

Hoặc là

<a href="bar.html?foo" onclick="alert(this.search)">SAY FOO</a>

Nếu bạn cần điều này trên một biến chuỗi thông thường và tình cờ có jQuery, điều này sẽ hoạt động:

var mylink = "foo.html?bar#quz";

if ($('<a href="'+mylink+'">').get(0).search=='bar')) {
    // do stuff
}

(nhưng nó có thể hơi quá ..)


3

Ném cái này vào đây như một phương thức để trừu tượng hóa các thuộc tính vị trí từ các chuỗi giống như URI tùy ý. Mặc dù window.location instanceof Locationlà sự thật, bất kỳ nỗ lực nào để gọi Locationsẽ cho bạn biết rằng đó là một nhà xây dựng bất hợp pháp. Bạn vẫn có thể có được những thứ như hash, query, protocolvv bằng cách thiết lập chuỗi của bạn như là hreftài sản của một phần tử DOM neo, sau đó sẽ chia sẻ tất cả các thuộc tính địa chỉ vớiwindow.location .

Cách đơn giản nhất để làm điều này là:

var a = document.createElement('a');
a.href = string;

string.hash;

Để thuận tiện, tôi đã viết một thư viện nhỏ sử dụng cái này để thay thế hàm Locationtạo riêng bằng một hàm sẽ lấy chuỗi và tạo window.locationcác đối tượng giống như: Location.js


1

Thông thường các lần nhấp đi trước thay đổi vị trí, vì vậy sau khi nhấp là một ý tưởng hay để setTimeOut để cập nhật window.location.hash

$(".nav").click(function(){
    setTimeout(function(){
        updatedHash = location.hash
    },100);
});

hoặc bạn có thể nghe vị trí với:

window.onhashchange = function(evt){
   updatedHash = "#" + evt.newURL.split("#")[1]
};

Tôi đã viết một plugin jQuery làm một cái gì đó giống như những gì bạn muốn làm.

Đó là một bộ định tuyến neo đơn giản.


1

Đây là một hàm đơn giản trả về truehoặc false(có / không có hashtag):

var urlToCheck = 'http://www.domain.com/#hashtag';

function hasHashtag(url) {
    return (url.indexOf("#") != -1) ? true : false;
}

// Condition
if(hasHashtag(urlToCheck)) {
    // Do something if has
}
else {
    // Do something if doesn't
}

Trả về true trong trường hợp này.

Dựa trên nhận xét của @ jon-skeet.


0

Đây là một cách đơn giản để kiểm tra điều này cho URL trang hiện tại:

  function checkHash(){
      return (location.hash ? true : false);
  }

-2

đôi khi bạn nhận được chuỗi truy vấn đầy đủ, chẳng hạn như "#anchorlink? Firstname = mark"

đây là tập lệnh của tôi để lấy giá trị băm:

var hashId = window.location.hash;
hashId = hashId.match(/#[^?&\/]*/g);

returns -> #anchorlink

6
Không thể vì hàm băm được nối sau chuỗi truy vấn và không bao giờ được gửi đến máy chủ. Thời gian băm duy nhất sẽ xuất hiện trước chuỗi truy vấn là khi bạn sửa đổi url bằng tay.

1
vâng, nhưng đôi khi mọi người gửi url trên định dạng này. điều này chỉ để bạn có thể nhận được giá trị băm và bỏ bê những người khác. :)
markg
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.