w3schools setdata para formatos espaƱol data attribute javascript jquery html5 drag-and-drop

javascript - para - Los datos de HTML5 DnDTransfer setData o getData no funcionan en todos los navegadores, excepto en Firefox



get data attribute javascript (6)

Considera este JSFiddle . Funciona bien en Firefox (14.0.1), pero falla en Chrome (21.0.1180.75), Safari (?) Y Opera (12.01?) En Windows (7) y OS X (10.8). Por lo que puedo decir, el problema es con los setData() o getData() en el objeto dataTransfer . Aquí está el código relevante de JSFiddle.

var dragStartHandler = function (e) { e.originalEvent.dataTransfer.effectAllowed = "move"; e.originalEvent.dataTransfer.setData("text/plain", this.id); }; var dragEnterHandler = function (e) { // dataTransferValue is a global variable declared higher up. // No, I don''t want to hear about why global variables are evil, // that''s not my issue. dataTransferValue = e.originalEvent.dataTransfer.getData("text/plain"); console.log(dataTransferValue); };

Por lo que puedo decir, esto debería funcionar perfectamente bien, y si miras la consola mientras arrastras un elemento, verás el ID escrito, lo que significa que está encontrando el elemento bien y tomando su atributo de identificación. La pregunta es, ¿no se trata de establecer los datos o no obtenerlos?

Agradecería sugerencias porque después de una semana de trabajar en esto con tres intentos y más de 200 versiones, estoy empezando a perder la cabeza. Todo lo que sé es que solía funcionar en la versión 60 más o menos y que el código específico no ha cambiado en absoluto ...

En realidad, una de las principales diferencias entre 6X y 124 es que cambié el enlace del evento de live() a on() . No creo que ese sea el problema, pero he llegado a ver un par de fallas de Chrome cuando se trata de DnD mientras trabajaba en esto. Esto ha sido desacreditado. El método de vinculación de eventos no tiene ningún efecto sobre el problema.

ACTUALIZAR

JSFiddle un nuevo JSFiddle que elimina absolutamente todo y deja el enlace y los manipuladores del evento. Lo probé con jQuery 1.7.2 y 1.8 con on() y live() . El problema persistió, así que bajé un nivel y eliminé todos los marcos y usé JavaScript puro. El problema persiste, por lo que según mis pruebas, no es mi código el que está fallando. En cambio, parece que Chrome, Safari y Opera están implementando setData() o getData() fuera de especificaciones o simplemente fallando por alguna razón u otra. Por favor corrígeme si estoy equivocado.

De todos modos, si echas un vistazo al nuevo JSFiddle, deberías ser capaz de replicar el problema, solo mira la consola cuando estás arrastrando sobre un elemento designado para aceptar un drop. He seguido adelante y he abierto una entrada con Chromium . Al final, todavía puedo estar haciendo algo mal, pero simplemente no sé cómo más hacer DnD en este momento. El nuevo JSFiddle es tan simple como puede ...


Algo que también vale la pena señalar es que si abandona la cadena de ejecución utilizando un tiempo de espera, el objeto dataTransfer ya no tendrá sus datos. p.ej

function dropEventHandler(event){ var dt = event.dataTransfer.getData("text/plain"); // works var myEvent = event; setTimeout(function(){ var dt = myEvent.dataTranfer.getData("text/plain"); // null }, 1); }


Bien, entonces, después de investigar un poco más, descubrí que el problema en realidad no está en Chrome, Safari y Opera. Lo que lo disfrutó fue que Firefox lo estaba apoyando y simplemente no podía decir que los otros navegadores fallaban, ya que eso es algo que normalmente aceptaría para IE.

La verdadera causa del problema es la especificación DnD en sí misma . De acuerdo con las especificaciones para los dragenter drag , dragenter , dragleave , dragover y dragend , el modo de almacenamiento de datos de arrastre está protegido . ¿Qué es el modo protegido que preguntas? Es:

Para todos los demás eventos. Los formatos y tipos en la lista de elementos de almacenamiento de datos de arrastre que representan datos arrastrados se pueden enumerar, pero los datos en sí no están disponibles y no se pueden agregar datos nuevos.

Eso se traduce en, "no tienes acceso a los datos que configuras, ¡ni siquiera en modo de solo lectura! Ve f @ & # tú mismo". . De Verdad? ¿Quién es el genio que se le ocurrió esto?

Ahora, para evitar esa limitación, tienes pocas opciones, y solo voy a delinear dos que se me han ocurrido. El primero es usar una variable global malvada y contaminar el espacio de nombres global. Su segunda opción es utilizar la API localStorage de HTML5 para realizar la misma funcionalidad EXACTA que la API DnD debería haber proporcionado para empezar.

Si sigues esta ruta, que tengo, ahora estás implementando dos API HTML5 no porque quieras , sino porque es necesario. Ahora estoy comenzando a apreciar las diatribas de PPK sobre el desastre que es la API HTML5 DnD.

La conclusión es esto, la especificación debe ser modificada para permitir el acceso a los datos almacenados, incluso si solo está en modo de solo lectura. En mi caso, con este JSFiddle , en realidad estoy usando el dragenter como una forma de mirar hacia adelante en la zona de lanzamiento y verificar que debería permitir que ocurra una caída o no.

En este caso, Mozilla aparentemente optó por no cumplir totalmente con la especificación y es por eso que mi JSFiddle funcionaba bien. Da la casualidad de que esta es la única vez que apoyo totalmente no admitir la especificación completa.


Estaba obteniendo el mismo error para el siguiente código:

event.originalEvent.dataTransfer.setData ("text / plain", event.target.getAttribute (''id''));

Cambié el código a:

event.originalEvent.dataTransfer.effectAllowed = "mover"; event.originalEvent.dataTransfer.setData ("text", event.target.getAttribute (''id''));

Y funcionó para mí.


Hay una razón para el bit "protegido" ... arrastrar / soltar puede abarcar ventanas completamente diferentes, y no querían que alguien pudiera implementar un DIV "oyente" que espiaría el contenido de todo lo que era arrastrado sobre él (y tal vez enviar esos contenidos por AJAX a algún servidor espía en Elbonia). Solo el área DROP (que está más claramente bajo el control del usuario) obtiene la primicia completa.

Molesto, pero puedo ver por qué podría considerarse necesario.


Sé que ya respondió esto, pero este es un hilo útil. Solo quería agregar un apéndice. Si está configurando los datos usted mismo, siempre puede agregar los datos en el campo mismo (feo, lo sé), pero evita tener que volver a crear la funcionalidad:

Por ejemplo, si configura sus propios datos personalizados:

dataTransfer.setData(''mycustom/whatever'', ''data'');

anexar los datos como una nueva entrada de datos e iterar:

dataTransfer.setData(''mycustom/whatever/data/{a json encoded string even}'');

consultando:

// naive webkit only look at the datatransfer.types if (dataTransfer.types.indexOf(''mycustom/whatever'') >= 0) { var dataTest = ''mycustom/whatever/data/''; // loop through types and create a map for (var i in types) { if (types[i].substr(0, dataTest.length) == dataTest) { // shows: // {a json encoded string even} console.log(''data:'', types[i].substr(dataTest.length)); return; // your custom handler } } }

probado solo en cromo


var dragStartHandler = function (e) { e.originalEvent.dataTransfer.effectAllowed = "move"; e.originalEvent.dataTransfer.setData("text/plain", this.id); };

El problema es con el "texto / plano". La especificación estándar en la documentación de MSDN para setData es solo "texto" (sin el / plain). Chrome acepta el / plain, pero IE no, en cualquier versión que probé.

Luché con el mismo problema durante varias semanas, tratando de descubrir por qué mis eventos de "caída" no se activaban correctamente en IE mientras lo hacían en CHrome. Fue porque los datos de transferencia de datos no se habían cargado correctamente.