¿Cómo puedes verificar un #hash en una URL usando JavaScript?


783

Tengo un código jQuery / JavaScript que quiero ejecutar solo cuando hay un #enlace de anclaje hash ( ) en una URL. ¿Cómo puedes verificar este personaje usando JavaScript? Necesito una prueba general que detecte URL como estas:

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

Básicamente algo en la línea de:

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

Si alguien pudiera señalarme en la dirección correcta, sería muy apreciado.

Respuestas:


1406

Simple:

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

43
Adicional: el objeto .location solo está disponible en la URL de la ventana actual, no puede hacerlo para una URL arbitraria (por ejemplo, una almacenada en una variable de cadena)
Gareth

64
Además, las propiedades de ubicación como .hash y .query también están disponibles en elementos <a>
Gareth,

19
.searchestá disponible en un <a>, no .query. JQuery muestra: $("<a/>").attr({ "href": "http://www.somewhere.com/a/b/c.html?qs=1#fragmenttest" })[0]. .hash => "#fragmenttest"y .search= ?qs=1. A partir de ahí, presione la pregunta de extracción de la cadena de consulta para obtener algo más que una cadena.
patridge

1
@hitautodestruct: esta pregunta no se trata de cambios en el hash, solo si uno está presente en la carga de la página o no.
Gareth

2
@Gareth Sí, tienes razón. Me acabo de dar cuenta de que el enlace que publiqué era para el hashchangeevento y no window.location.hash. Aunque este último no es compatible con IE <8.
hitautodestruct

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

Pon lo siguiente:

<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
Gracias, window.location.hash solo tiene un valor si hay un valor que sigue al #. por ejemplo. //www.example.com# devuelve '' al verificar el hash.
Jessy

33

Si el URI no es la ubicación del documento, este fragmento hará lo que desee.

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

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

+1 para Javascript sin saber lo que está fuera de límites :)
Dunc

2
@Dunc: Bueno, las matrices JS son básicamente objetos. Acceder a ellos por el índice es igual que el acceso a una propiedad de objeto, así: obj['0']. En JS esto es cierto: por lo arr[0] === arr['0']tanto, si el índice / clave no existe, el valor devuelto no está definido en lugar de estar fuera de los límites. jsfiddle.net/web5me/Mw376
Marc Diethelm

21

¿Has probado esto?

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

(¿Dónde urlestá la URL que desea verificar, obviamente?)


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!
});

Esto solucionará el problema ;)


Me gustó esta respuesta porque mezcla JS + JQ, navegador cruzado y solución simple, ya implementó este enfoque.
Arthur Kushman



6

Esto es lo que puede hacer para verificar periódicamente un cambio de hash y luego llamar a una función para procesar el valor de hash.

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
eso es solo necesario en 6 + 7. Todos los otros navegadores han incluido el evento
onhashchange

@Tokimon - ¡genial! No lo sabia. Pero supongo que todavía tenemos que soportar esas versiones antiguas de IE
Emmanuel

1
Sí, lamentablemente ... Incluso IE 8 no desaparecerá pronto ya que IE 9 no es compatible con XP :(
Tokimon

1
modernizr.com implementa el evento hashchange en navegadores antiguos (junto con un montón de otras características modernas)
guigouz

44
Este no es un código recomienda en absoluto: por lo menos debería ser: setTimeout(checkHash, 400). Además, los navegadores modernos tienen el hashchangeevento para que pueda hacer una window.addEventListener('hashchange', function(){ … }). Finalmente, filtrar la hashvariable global es otra práctica no recomendada, incluso por ejemplo.
Oncle Tom

5

La mayoría de las personas conocen las propiedades de URL en document.location. Eso es genial si solo estás interesado en la página actual. Pero la pregunta era sobre poder analizar anclas en una página, no en la página en sí.

Lo que la mayoría de las personas parecen perderse es que esas mismas propiedades de URL también están disponibles para anclar elementos:

// 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
¿No debería ser "hash.length" en lugar de "hash.length ()"? :)
Nathan Pitman

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

3

Los comentarios de Perdiz y Gareth anteriores son geniales. Se merecen una respuesta por separado. Aparentemente, las propiedades de hash y búsqueda están disponibles en cualquier objeto de enlace html:

<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>

O

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

Si necesita esto en una variable de cadena regular y tiene jQuery, esto debería funcionar:

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

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

(pero tal vez es un poco exagerado ...)


3

Lanzar esto aquí como un método para abstraer propiedades de ubicación de cadenas arbitrarias similares a URI. Aunque window.location instanceof Locationes cierto, cualquier intento de invocación Locationle dirá que es un constructor ilegal. Todavía se puede llegar a cosas como hash, query, protocoletc. mediante el establecimiento de su cadena como la hrefpropiedad de un elemento DOM ancla, se podrán compartir todas las propiedades de dirección conwindow.location .

La forma más simple de hacer esto es:

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

string.hash;

Por conveniencia, escribí una pequeña biblioteca que utiliza esto para reemplazar el Locationconstructor nativo con uno que tome cadenas y produzca window.locationobjetos similares: Location.js


1

Por lo general, los clics van primero que los cambios de ubicación, por lo que después de un clic es una buena idea configurar TimeOut para obtener window.location.hash actualizado

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

o puedes escuchar la ubicación con:

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

Escribí un complemento jQuery que hace algo como lo que quieres hacer.

Es un simple enrutador de ancla.


1

Aquí hay una función simple que devuelve trueo false(tiene / no tiene un 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
}

Devoluciones trueen este caso.

Basado en el comentario de @ jon-skeet.


0

Esta es una manera simple de probar esto para la URL de la página actual:

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

-2

a veces se obtiene la cadena de consulta completa como "#anchorlink? firstname = mark"

Este es mi script para obtener el valor hash:

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

returns -> #anchorlink

66
No es posible ya que el hash se agrega después de la cadena de consulta y nunca se envía al servidor. El único hash de tiempo que aparecerá antes de la cadena de consulta es cuando modificó la url a mano.

1
Sí, pero a veces las personas envían URL en este formato. esto es solo para que pueda obtener solo el valor hash y descuidar a los demás. :)
markg
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.