Tengo este problema (estoy usando jQuery, pero no estoy reducen a ella):onhashchange con botones del navegador solamente
estoy usando una combinación de ancla de navegación (#id) y las peticiones Ajax . Para que las páginas se coloquen en su lugar (usando la navegación de ancla) o para buscar información (usando Ajax), utilizo el evento onhashchange.
EDIT: Tuve un pequeño error tipográfico. Me olvidé de comprobar si la bandera mouseDown era verdadera y se desencadenó el evento hashchange, así que agregué esa declaración if.
con jQuery que se parece a esto: (por supuesto, este código se envuelve en una función de la carga y se inicializa DOM, pero no importa para la pregunta)
$(window).bind('hashchange', function(e) { }
para asegurar que sólo los navegadores apoyo a la onhashchange lee el código que encapsulan así:
if ('onhashchange' in window) {
$(window).bind('hashchange', function(e) { }
}
Mi aplicación web se hace de tal manera que sólo quiero el evento onhashchange para disparar cuando pulso los botones de atrás/adelante en el navegador. Para hacer esto, me gusta:
if ('onhashchange' in window) {
$(window).bind('mousedown hashchange', function(e) { }
}
Ahora, si hago clic dentro de la ventana de visualización activaré el evento mousedown. Si se activa el evento MouseDown Sé que no hizo clic en el navegador hacia atrás/adelante botones y puedo detener el evento onhashchange usando una bandera de esta manera:
var mouseDown = false;
if ('onhashchange' in window) {
$(window).bind('mousedown hashchange', function(e) {
if (e.type === 'mousedown') {
mouseDown = true;
}
if (mouseDown && e.type === 'hashchange') {
// if the mousedown event was triggered and when the haschange event triggers,
// we need to stop the hashchange event and restore the mouseDown flag
mouseDown = false;
e.stopPropagation();
}
if (!mouseDown && e.type === 'hashchange') {
// Do the onhashchange stuff here
}
}
}
Esto causa un problema para IE, ya que Las costuras no pueden unir eventos del mouse al objeto ventana (?). IE nunca "verá" el evento mousedown.
Para resolver este problema de IE puedo tomar la propiedad "clientY". Esta propiedad se pasa en todas las llamadas a eventos en IE y le indica las coordenadas del mouse. Si e.clientY es menor que 0, el mouse se encuentra fuera de la ventana gráfica y sabré que activé el onhashchange haciendo clic en los botones de navegación hacia atrás/adelante. Ahora parece que esto:
var mouseDown = false;
if ('onhashchange' in window) {
$(window).bind('mousedown hashchange', function(e) {
// IE: Use e.clientY to check if the mouse position was within the viewport (i.e. not a nagative value for Y)
// !IE: Use e.type
if (e.type === 'mousedown' || e.clientY > 0) {
mouseDown = true;
}
if (mouseDown && e.type === 'hashchange') {
// if the mousedown event was triggered and when the haschange event triggers,
// we need to stop the hashchange event and restore the mouseDown flag
mouseDown = false;
e.stopPropagation();
}
if (!mouseDown && e.type === 'hashchange') {
// Do the onhashchange stuff here
}
}
}
Esta solución estaba funcionando a las mil maravillas hasta que he tenido que añadir soporte para la navegación con las flechas del teclado. Ahora no importa en qué parte de la pantalla está el mouse. Siempre que la ventana de IE esté "activa", el evento de pulsación para escuchar la entrada del teclado se activa al presionar el teclado. Esto significa que el control de clienteY ya no funciona como se esperaba.
El problema:
Por lo que yo sé, el onhashchange debe estar enlazado al objeto de ventana. Todos los eventos deben procesarse dentro de la misma función de devolución de llamada si deseo poder controlar un evento escuchando otro.
¿Cómo puedo hacer que funcione?
('onhashchange' en la ventana) siempre devolverá falso si aún no está definido y verdadero ya está definido. No significa que el navegador realmente ejecutará el código en un hashchange Esto es similar a window.onload que no está definido a menos que se le haya asignado una función, aunque prácticamente todas las browswers lo admiten. – qwertymk
Sí, dejé intencionalmente la declaración de función porque no la consideré relevante para la pregunta. La función que vincula el evento hashchange se invoca cuando se carga el DOM. – Patrik