2010-11-05 17 views
44

Estoy usando hash para cargar contenido dinámicamente. Para hacer que el botón Atrás funcione, estoy capturando cambios hash. Sin embargo, algunas veces necesito cambiar el hash sin activar la función hash changed (por ejemplo, cuando la página fue redirigida al servidor y necesito actualizar el hash una vez que el contenido ha regresado).Cambiar hash sin activar un evento hashchange

La mejor solución que he encontrado es desvincular el evento hashchange, hacer el cambio y luego volver a vincularlo. Sin embargo, como esto ocurre de forma asíncrona, estoy descubriendo que se vuelve a enlazar demasiado rápido y todavía capta el cambio de hash.

Mi solución en este momento es muy pobre: ​​volver a vincular en un setTimeout. ¿Alguien tiene una idea mejor?

$(window).unbind('hashchange', hashChanged); 
    window.location.hash = "!" + url; 
    setTimeout(function(){ 
     $(window).bind('hashchange', hashChanged); 
    }, 100); 


Editar: sugerencia
de Amir Raminfar me llevó a una solución que no requiere un tiempo de espera. He añadido una variable de clase

_ignoreHashChange = false; 

Cuando quiero cambiar el hash en silencio hago esto:

_ignoreHashChange = true; 
window.location.hash = "!" + url; 

y el hash cambiado evento hace esto:

function hashChanged(event){ 
    if(_ignoreHashChange === false){ 
     url = window.location.hash.slice(2); 
     fetchContent(url); 
    } 
    _ignoreHashChange = false; 
} 
+4

una solución simple y agradable, usted debe hacer una respuesta – Peter

+1

El lo único que queda es comprobar que el nuevo hash no es igual al anterior antes de configurar _ignoreHashChange = true; – Kasheftin

+1

Es posible que desee consultar la biblioteca Cowboy's BBQ que le proporciona un control preciso sobre todas las cosas Back y Hashchange: http://benalman.com/code/projects/jquery-bbq/docs/files/jquery-ba-bbq-js. html – hybernaut

Respuesta

5

Usted puede tener una función como esta:

function updateHash(newHash){ 
    ... 
    oldHash = newHash 
} 

entonces en su setTimeOut que tiene que hacer

function(){ 
    if(oldHash != currenHash){ 
    updateHash(currenHash); 
    } 
} 

Así que ahora puede llamar a la actualización de hash de forma manual y no va a ser activado por el evento. También puede tener más parámetros en updateHash para hacer otras cosas.

Por cierto, ¿has mirado el plugin jquery history? http://tkyk.github.com/jquery-history-plugin/

+0

Tendría que ser un intervalo establecido, pero sí, en principio, esto funcionaría. Gracias. – SystemicPlural

+1

Sí, he visto varios complementos. Están demasiado hinchados o con errores para mis necesidades. – SystemicPlural

+0

Me indicó una mejor solución que no requiere tiempo de espera. ver la edición en mi publicación principal para más detalles. Gracias por su ayuda – SystemicPlural

5

Usted podría utilizar history.replaceState y anexar el hash, para reemplazar el actual URI sin desencadenar la hashchange evento:

var newHash = 'test'; 

history.replaceState(null, null, document.location.pathname + '#' + newHash); 

JSFiddle example

+0

'history.replaceState' tampoco empuja el hashchange en el historial, pero si lo desea, puede usar' history.pushState;;) – qdev

+0

@qdev Sí, pero eso no era lo que pedía la garantía de calidad ... – Tim

Cuestiones relacionadas