¿Cómo simulo un mouseover en JavaScript puro que activa el CSS ":hover"?
He estado tratando de encontrar código para simular mouseover
en Chrome, pero aunque se activa el oyente "mouseover", la declaración CSS "hover" nunca se establece.
Intenté también hacer:
//Called within mouseover listener
theElement.classList.add("hover");
Pero nada parece cambiar el elemento a lo declarado en su hover
declaración.
es posible?
No puedes. No es un evento confiable .
El agente de usuario confía en los eventos generados por el agente de usuario, ya sea como resultado de la interacción del usuario o como resultado directo de cambios en el DOM, con privilegios que no se otorgan a los eventos generados por el script a través de DocumentEvent.createEvent. ("Evento"), modificado mediante el método Event.initEvent() o enviado mediante el método EventTarget.dispatchEvent(). El atributo isTrusted de eventos confiables tiene un valor de verdadero, mientras que los eventos que no son de confianza tienen un valor de atributo isTrusted de falso.
La mayoría de los eventos que no son de confianza no deberían desencadenar acciones predeterminadas , con la excepción de los eventos click o DOMActivate.
Debe agregar una clase y agregarla/eliminarla manualmente en los eventos de mouseover/mouseout.
Puedes simular el evento del mouseover de esta manera:
HTML
<div id="name">My Name</div>
javascript
var element = document.getElementById('name');
element.addEventListener('mouseover', function() {
console.log('Event triggered');
});
var event = new MouseEvent('mouseover', {
'view': window,
'bubbles': true,
'cancelable': true
});
element.dispatchEvent(event);
Fondo
Me topé con esta pregunta mientras intentaba escribir pruebas automatizadas, para verificar, que un cierto conjunto de elementos en una página determinada reciban un conjunto de propiedades CSS establecidas por el CSS para eventos al pasar el mouse.
Si bien la respuesta anterior explica perfectamente por qué no es posible simplemente activar el evento de desplazamiento mediante JS y luego probar algún valor CSS de interés, responde a la pregunta inicial "¿Cómo simulo un mouseover en JavaScript puro que activa el CSS?" :flotar"?" sólo en parte.
Descargo de responsabilidad
Esta no es una solución eficaz. Lo utilizamos sólo para pruebas automatizadas, donde el rendimiento no es una preocupación.
Solución
simulateCssEvent = function(type){
var id = 'simulatedStyle';
var generateEvent = function(selector){
var style = "";
for (var i in document.styleSheets) {
var rules = document.styleSheets[i].cssRules;
for (var r in rules) {
if(rules[r].cssText && rules[r].selectorText){
if(rules[r].selectorText.indexOf(selector) > -1){
var regex = new RegExp(selector,"g")
var text = rules[r].cssText.replace(regex,"");
style += text+"\n";
}
}
}
}
$("head").append("<style id="+id+">"+style+"</style>");
};
var stopEvent = function(){
$("#"+id).remove();
};
switch(type) {
case "hover":
return generateEvent(":hover");
case "stop":
return stopEvent();
}
}
Explicación
generateEvent lee todos los archivos css, reemplaza :hover con una cadena vacía y la aplica. Esto tiene el efecto de que se aplican todos los estilos :hover. Ahora se puede buscar un estilo adormecido y volver al estado inicial deteniendo la simulación.
¿Por qué aplicamos el efecto de desplazamiento para todo el documento y no solo para el elemento de interés obteniendo el de las hojas y luego ejecutando un element.css(...)?
Hecho así, el estilo se aplicaría en línea, esto anularía otros estilos, que podrían no ser anulados por el estilo CSS original.
¿Cómo simularía ahora el desplazamiento sobre un solo elemento?
Esto no funciona, así que será mejor que no lo hagas. Si es necesario, puede verificar con element.is(selectorOfInterest) si el estilo se aplica a su elemento y solo usar esos estilos.
Ejemplo
En Jasmine ahora puedes, por ejemplo, realizar:
describe("Simulate CSS Event", function() {
it("Simulate Link Hover", function () {
expect($("a").css("text-decoration")).toBe("none");
simulateCssEvent('hover');
expect($("a").css("text-decoration")).toBe("underline");
simulateCssEvent('stop');
expect($("a").css("text-decoration")).toBe("none");
});
});