2012-05-25 15 views
11

En mi aplicación web, intento implementar algunas funciones de arrastrar y soltar. Tengo un componente global de JavaScript que hace las cosas básicas. Este objeto también es responsable de cambiar el cursor del mouse, dependiendo de la operación de arrastre actual (mover, copiar, vincular). En mi página web hay varios elementos HTML que definen un estilo de cursor propio, ya sea en línea o mediante un archivo CSS.Anulación global del cursor del mouse con JavaScript

Entonces, ¿hay alguna manera para que mi componente central de arrastrar y soltar cambie el cursor del mouse globalmente, independientemente del estilo del elemento sobre el que se encuentra el cursor del mouse?

me trataron:

document.body.style.cursor = "move" 

y

document.body.style.cursor = "move !important" 

Pero no funciona. Cada vez que arrastro sobre un elemento que define un estilo de cursor, el cursor cambia a ese estilo.

Claro, podría cambiar el estilo del elemento que actualmente estoy arrastrando, pero luego tengo que restablecerlo cuando retire el elemento. Esto parece un poco complicado. Estoy buscando una solución global.

Respuesta

10

Por favor, no mates tu CSS!

para implementar una operación de arrastrar y soltar, usted tiene que utilizar una API muy importante: element.setCapture(). Esto tiene este consecuencias:

  • Todos los eventos de ratón se redirigen al elemento de destino de la captura, independientemente del lugar en que ocurrieron (incluso fuera de la ventana del navegador)
  • El cursor será el cursor del elemento blanco de la captura, independientemente de dónde esté el puntero del mouse.

usted tiene que llamar element.releaseCapture() o document.releaseCapture() para volver al modo normal al final de la operación.

Cuidado con un implemnntation ingenua de arrastrar y soltar: se puede tener un montón de cuestiones dolorosas, como por ejemplo (entre otros): ¿qué ocurre si el ratón se realeased fuera de la ventana del navegador, o más de una elemento que tiene un controlador que detiene la propagación. El uso de setCapture() resuelve todos estos problemas, y el estilo del cursor también.

Puede leer this excellent tutorial que explica esto en detalle si desea implementar el arrastre y soltar usted mismo.

Quizás también puedas usar jQuery UI draggable si es posible en tu contexto.

+4

setCapture funciona en IE y FF/Moz, pero parece que Chrome no es compatible con esta impresionante función :( – eselk

+0

setCapture solo funciona en Firefox hoy (no en IE 11) .Pero se puede usar cuando está allí. – ygoe

4
document.body.style.cursor = "move" 

debería funcionar bien.

Sin embargo, recomiendo hacer el estilo global a través de CSS.

definir lo siguiente:

body{ 
    cursor:move; 
} 

El problema es, que los cursores definidos en los otros elementos anulan el estilo de la carrocería.

Usted podría hacer calle detrás de esta manera:

your-element.style.cursor = "inherit"; // (or "default") 

para restablecerlo al estilo heredado del cuerpo o con CSS: sin embargo

body *{ 
    cursor:inherit; 
} 

Nota, que * normalmente se considera un mal selector -elección.

2

Si lo hace una declaración CSS:

* {cursor:move;}

Se debe trabajar.

3

Desafortunadamente element.setCapture() no funciona para IE

Puedo usar un método de fuerza bruta - abrir un div transparente en la parte superior de la página completa durante la duración de arrastrar y soltar.

.tbFiller { 
    position:absolute; 
    z-index:5000; 
    left:0; 
    top:0; 
    width:100%; 
    height:100%; 
    background-color:transparent; 
    cursor:move; 
} 

... 

function dragStart(event) { 
    // other code... 
    document.tbFiller=document.createElement("div"); 
    document.tbFiller.className="tbFiller" 
} 

function dragStop(event) { 
    // other code... 
    document.tbFiller.parentNode.removeChild(document.tbFiller); 
} 
+1

setCapture funciona en IE, pero no creo que Chrome tenga algo así. – eselk

+0

setCapture no funciona en IE 11. Firefox dice que es una API de Microsoft, pueden haberlo descartado otra vez. Pero no necesitas una div de superposición, una regla de CSS y establecer una clase es suficiente. – ygoe

0

Esto es lo que hago y funciona en Firefox, Chrome, Edge y el IE a partir de 2017.

Añadir esta regla CSS a la página:

html.reset-all-cursors * 
{ 
    cursor: inherit !important; 
} 

Cuando el elemento <html> tiene la clase "restablecer todos los cursores", esto anula todos los cursores que están configurados para los elementos individualmente en su atributo style, sin manipular realmente los elementos. No hay necesidad de limpiar todo el lugar.

Luego, cuando desee anular el cursor en la página completa con la de cualquier element, e. gramo. el elemento arrastrado, hacer esto en JavaScript:

element.setCapture && element.setCapture(); 
$("html").addClass("reset-all-cursors"); 
document.documentElement.style.setProperty("cursor", $(element).css("cursor"), "important"); 

Se utiliza la función setCapture donde está disponible. Esto es actualmente solo Firefox aunque dicen que es una API de Microsoft. Luego, la clase especial se agrega a todo el documento, lo que deshabilita todos los cursores personalizados. Finalmente configure el cursor que desea en el documento para que aparezca en todas partes.

En combinación con la captura de eventos, esto puede incluso extender el cursor de arrastre fuera de la página y la ventana del navegador. setCapture hace esto de manera confiable en Firefox. Pero en otros lugares no funciona todas las veces, dependiendo del navegador, su diseño de interfaz de usuario y la ruta a lo largo de la cual el cursor del mouse sale de la ventana. ;-)

Cuando haya terminado, haz limpieza:

element.releaseCapture && element.releaseCapture(); 
$("html").removeClass("reset-all-cursors"); 
document.documentElement.style.setProperty("cursor", ""); 

Esto incluye jQuery para addClass y removeClass. En escenarios simples, simplemente podría comparar y establecer el atributo class de document.documentElement. Sin embargo, esto romperá otras bibliotecas como Modernizr. Puede deshacerse de la función css si ya conoce el cursor deseado del elemento, o intente algo como element.style.cursor.

Cuestiones relacionadas