javascript - example - html ui framework
Un clic en iOS Safari activa un "estado flotante" en el elemento debajo de donde pulsó (10)
En iOS Safari ( no creo que importe qué versión de iOS, pero estoy probando en iOS (Safari) 11 ), si tengo una <div>
posicionada sobre un elemento que tiene un efecto de :hover
y <div>
tiene un evento que lo hace desaparecer cuando se hace clic, luego mi enlace "debajo" obtiene el efecto de desplazamiento que se aplica después de que el elemento se elimine del DOM.
Vea a continuación un GIF animado de lo que estoy hablando:
Le he dado al botón un fondo transparente para que pueda ver el enlace detrás de él. Cuando toco el botón en un lugar donde no se encuentra el enlace, el enlace (es decir, Some link
) permanece en azul y no cambia a su estado de desplazamiento de rojo.
Sin embargo, cuando toco el div
en un punto que está directamente sobre el enlace, después de que el div
se elimina del DOM, el enlace se aplica al estado de activación.
Al hacer clic en el enlace después de cada uno de estos, se activa correctamente su evento on.click
(una ventana de alerta).
No veo este problema en Android en Chrome (vea el ejemplo a continuación):
A continuación también encontrará la muestra HTML / CSS / JS que usé; La configuración es bastante simple.
Me gustaría que iOS Chrome actúe de la misma manera que lo hace Android Chrome: es decir, al hacer clic en un elemento que se elimina inmediatamente del DOM no se debe activar el estado: para un elemento situado inmediatamente detrás.
document.addEventListener("DOMContentLoaded", function ready() {
var button = document.querySelector(".button");
button.addEventListener("click", function() {
button.parentNode.removeChild(button);
});
document.querySelector(''a'').addEventListener("click", function() {
window.alert(''clicked!'');
});
});
a:link { color: blue }
a:visited { color: blue }
a:hover { color: red }
a:active { color: green }
.button {
background: rgba(100, 0, 0, .4);
position: absolute;
top: 2px;
left: 2px;
z-index: 1;
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
border-radius: 5px;
}
.button:hover {
background: rgba(0, 100, 0, .4);
cursor: pointer;
}
<a href="#">Some link</a>
<div class="button">Click me!</div>
¿Ha intentado usar una consulta de medios para probar la capacidad de desplazamiento?
... se puede ver claramente que este es el comportamiento previsto en iOS, incluso cuando se desliza sobre una lista de elementos que se pueden desplazar.
Si lo que intentas evitar es solo el efecto de desplazamiento, esto es lo que haría. Obtendría el dispositivo utilizando una función JS, aplicaría una clase en la etiqueta del body
y eliminaría cualquier efecto de desplazamiento según sea necesario.
Javascript:
function isAppleDevice() {
return (
(navigator.userAgent.toLowerCase().indexOf("ipad") > -1) ||
(navigator.userAgent.toLowerCase().indexOf("iphone") > -1) ||
(navigator.userAgent.toLowerCase().indexOf("ipod") > -1)
);
}
if (isAppleDevice() {
$(''body'').addClass(''is_apple'')
}
CSS:
.is_apple a:hover {
// same styling as not hovering
}
Creo que este hack puede funcionar.
Debe deshabilitar el desplazamiento con una clase y, cuando se haga clic en la división superior, agregue un detector de eventos que elimine la clase de bloqueo del desplazamiento al mover el mouse.
document.addEventListener("DOMContentLoaded", function ready() {
var button = document.querySelector(".button");
button.addEventListener("click", function() {
button.parentNode.removeChild(button);
var body = document.querySelector("body");
body.addEventListener("mousemove", function() {
var someLink = document.querySelector(".some-link");
someLink.classList.remove("no-hover");
});
});
document.querySelector(''a'').addEventListener("click", function() {
window.alert(''clicked!'');
});
});
a:link { color: blue }
a:visited { color: blue }
a:hover { color: red }
a:active { color: green }
a.no-hover:hover { color: blue }
.button {
background: rgba(100, 0, 0, .4);
position: absolute;
top: 2px;
left: 2px;
z-index: 1;
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
border-radius: 5px;
}
.button:hover {
background: rgba(0, 100, 0, .4);
cursor: pointer;
}
<a href="#" class="some-link no-hover">Some link</a>
<div class="button">Click me!</div>
El uso de eventos punteros podría ayudar aquí.
document.addEventListener("DOMContentLoaded", function ready() {
var button = document.querySelector(".button");
button.addEventListener("click", function() {
button.parentNode.removeChild(button);
});
document.querySelector(''a'').addEventListener("click", function() {
window.alert(''clicked!'');
});
});
a {pointer-events: none;}
a:link { color: blue; pointer-events: auto; }
a:visited { color: blue }
a:hover { color: red; pointer-events: auto; }
a:active { color: green; pointer-events: auto; }
.button {
background: rgba(100, 0, 0, .4);
position: absolute;
top: 2px;
left: 2px;
z-index: 1;
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
border-radius: 5px;
}
.button:hover {
background: rgba(0, 100, 0, .4);
cursor: pointer;
}
<a href="#">Some link</a>
<div class="button">Click me!</div>
Esta parece ser una decisión de diseño inherente en iOS (o tal vez la forma de Chrome es la decisión de diseño, tomada por ellos; no puedo decirlo). Parece que iOS está diseñado para ser "como un ratón". Incluso lanza "mouseovers" en las páginas web, incluso en sus dispositivos táctiles. He estado tratando de encontrar una manera de determinar si el usuario tiene un mouse para que pueda deshabilitar los efectos de desplazamiento si hay uno, pero no puedo encontrar nada que funcione correctamente.
Creo que Windows también hace lo mismo con el tacto. Al tocar un punto, el puntero del mouse se mueve allí de manera efectiva y hace clic, dejando el puntero del mouse.
Es posible que tenga que cambiar su diseño si se trata de un factor decisivo.
Este es un problema con los navegadores. El estado de hover existe en todas partes, incluso cuando no debería.
Yo agregaría una clase de .no-touch
al cuerpo y estilo solo aquellos.
if (!("ontouchstart" in document.documentElement)) {
document.body.classList.add(''no-touch'')
}
Aquí está todo junto
if (!("ontouchstart" in document.documentElement)) {
document.body.classList.add(''no-touch'')
}
document.addEventListener("DOMContentLoaded", function ready() {
var button = document.querySelector(".button");
button.addEventListener("click", function(e) {
button.parentNode.removeChild(button);
});
document.querySelector(''a'').addEventListener("click", function() {
window.alert(''clicked!'');
});
});
a:link { color: blue }
a:visited { color: blue }
.no-touch a:hover { color: red }
a:active { color: green }
.button {
background: rgba(100, 0, 0, .4);
position: absolute;
top: 2px;
left: 2px;
z-index: 1;
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
border-radius: 5px;
}
.button:hover {
background: rgba(0, 100, 0, .4);
cursor: pointer;
}
<a href="#">Some link</a>
<div class="button">Click me!</div>
Aprecio que esta no sea la respuesta que está buscando, pero definitivamente la mantendrá consistente entre Android y iOS. Potencialmente ayudará a otros con el mismo problema en el futuro.
Este parece ser el comportamiento previsto en Safari. La documentation de Apple dice que los toques con un solo dedo se manejan como eventos del mouse, y muestra qué eventos se activan durante un toque. Hay un mouseover
al inicio del grifo, pero un mouseout
solo se activa cuando haces clic en otra cosa. Esto implica que Safari asume que el puntero permanece en el mismo lugar hasta el siguiente toque, lo que significaría que tiene sentido que el elemento inferior se encuentre en el estado de desplazamiento.
Probé tu código en Chrome en Android, y Chrome y Firefox en Windows (no tengo un dispositivo Apple). En los tres casos, cuando hago clic en <div>
utilizando un mouse (sobre el enlace), el estilo de desplazamiento se aplica al enlace después, a menos que mueva el cursor del enlace antes de soltar el mouse. Si toco en <div>
con el dedo en la pantalla táctil, el enlace no obtiene el estilo de desplazamiento.
Firefox y Chrome parecen ser coherentes entre sí para el tacto y el mouse, pero Safari parece (por diseño) tratar la pantalla táctil como un mouse: se comporta de la misma manera que con una pulsación al tacto como Chrome y Firefox hacen con un clic del mouse.
No creo que esto sea un error que deba corregir o solucionar. A menos que sepa que todos sus usuarios usarán una combinación específica de hardware / navegador, probablemente necesite planificar la eventualidad de que puedan usar un mouse, una pantalla táctil o tal vez ambos al mismo tiempo; y diseñar una interfaz de usuario que funcione para todos estos casos. Mi computadora portátil con Windows y mi tableta con Android tienen mousepads y pantallas táctiles, y a veces uso un mouse USB OTG con mi teléfono Android.
También puede consultar la API de eventos de puntero , que funciona en Chrome, IE y Edge (no debe confundirse con la propiedad de CSS de pointer-events mencionada por @erier). Como la API se ocupa de eventos en lugar de CSS, esto no ayudará directamente a mejorar su estilo, sino que muestra los esfuerzos realizados para hacer que los navegadores reaccionen de manera coherente a diferentes tipos de dispositivos de entrada.
No sé si esto funcionaría en su código de producción, pero debería hacerlo para este ejemplo.
Podría escupir sus reglas de desplazamiento a una clase y aplicar esta clase al enlace en la devolución de llamada de eliminación de botón, después de haberla eliminado del DOM.
Si eso todavía no funciona, puede agregar la clase en una devolución de llamada de onmouseover
. Esto solo funcionaría después de quitar el botón y después de salir (si corresponde) y volver a ingresar el enlace.
Todo es un poco intrincado, pero te permitiría ajustar el comportamiento a cualquiera de los navegadores / sistemas operativos.
Si tiene la opción de deshabilitar el desplazamiento, puede hacerlo con un poco de pirateo.
Primero agregue esta línea en el controlador de eventos "DOMContentLoaded".
var canHover = !(matchMedia(''(hover: none)'').matches);
if (canHover) {
document.body.classList.add(''can-hover'');
}
Agregará la clase .can-hover al cuerpo de su documento html.
Luego simplemente edita una regla de desplazamiento para que coincida con esto
su regla css:
a:hover {
color: red;
}
debiera ser:
.can-hover a:hover {
color: red;
}
Esto debería evitar que los dispositivos con pantalla táctil apliquen el estilo de hover a cualquier ancla.
Tuve un problema similar que resolví agregando eventos de puntero ninguno por una fracción de segundo justo antes de que se elimine el elemento y luego lo configuré nuevamente después de que desapareció.
document.addEventListener("DOMContentLoaded", function ready() {
var button = document.querySelector(".button");
button.addEventListener("click", function() {
document.querySelector(''a'').classList.add("no-click");
button.parentNode.removeChild(button);
setTimeout(function() {
document.querySelector(''a'').classList.remove("no-click");
},1);
});
document.querySelector(''a'').addEventListener("click", function() {
window.alert(''clicked!'');
});
});
a:link { color: blue }
a:visited { color: blue }
a:hover { color: red }
a:active { color: green }
.button {
background: rgba(100, 0, 0, .4);
position: absolute;
top: 2px;
left: 2px;
z-index: 1;
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
border-radius: 5px;
}
.button:hover {
background: rgba(0, 100, 0, .4);
cursor: pointer;
}
.no-click {
pointer-events: none;
}
<a href="#">Some link</a>
<div class="button">Click me!</div>