vuejs sortable sort ejemplos drop divs and javascript callback drag-and-drop html5sortable

javascript - sortable - addeventlistener drop error "TypeError no capturado: invocación ilegal"



sortable js (2)

El error "Invocación ilegal" significa que intenta llamar a una función invocable con el contexto incorrecto, siendo el contexto el objeto al que se llama el método. Déjame desglosar la console.log :

console.log(element.__proto__.ondrop)

Aquí está intentando registrar el element.__proto__.ondrop . Primero, déjame explicar el element.__proto__ . La propiedad de acceso en cada objeto, Object.prototype.__proto__ es una propiedad de acceso que apunta al prototipo de ese objeto y se usa para resolver los métodos en la cadena de búsqueda. Por ejemplo:

function Person(name) { //This is a constructor function this.name = name; //Set the name to be part of the instance } Person.prototype.sayName = function() { //A function on the prototype console.log(this.name); //and is part of the instance } const bob = new Person("Bob"); console.log(bob.__proto__); //The __proto__ property refers to `Person.prototype` //and will log the `Person.prototype` object

Aquí, __proto__ de una instancia se refiere al prototype del constructor que construyó la instancia. Ahora, en su caso, el __proto__ de un elemento del DOM sería algo HTMLDivElement al prototipo de HTMLDivElement o algo más, dependiendo del tipo de elemento que sea. A los efectos de esta respuesta, diremos que es un div .

Ahora, cuando intenta acceder al ondrop de propiedad del prototipo HTMLDivElement , recibe una invocación ilegal porque está intentando acceder de ondrop estática desde el prototipo HTMLDivElement , ¡no es un elemento div real ! Esto lleva al "contexto incorrecto" porque está intentando llamar al HTMLDivElement.prototype de HTMLDivElement.prototype en HTMLDivElement.prototype , ¡no a un div del DOM!

Para "arreglar esto", no acceda a la tecla __proto__ . Si desea acceder a la propiedad ondrop del elemento, simplemente haga element.ondrop .

Creo un nuevo objeto por función y creo un método sortable para usar, pero que tiene un error en la función de devolución de llamada

;"use strict"; (function(){ function libJS(){}; libJS.prototype = { loopElement : function(element, options, callback){ var libObj = this; var goesCallback = function(element, options, callback){ if (!!callback && libObj.isFunction(callback)) callback(element, options); }; if (libObj.isElement(element)) goesCallback(element, options, callback); else if (libObj.isString(element) && /^(/.|/#)[/w/d/-_]+$/g.test(element)){ if (/^/./g.test(element)){ element = document.getElementsByClassName(element.replace(''.'', '''')); var length = element.length || 0, i; for(i = 0; i < length; i++) goesCallback(element[i], options, callback); }else{ element = document.getElementById(element.replace(''#'', '''')); if (!!element) goesCallback(element, options, callback); } } }, isElement : function(element){ // code check var f=(typeof HTMLElement === ''object'' || false); f=(f && element instanceof HTMLElement); f=(f||(typeof element === ''object'' && element.nodeType===1 && typeof element.nodeName === ''string'')); return f; }, isString : function(str){ // code check return true; }, isObject : function(obj){ // code check return true; }, isFunction : function(func){ // code check return true; }, token : function(length){ // create token return ''random_string''; }, sortable : function(options){ if (''draggable'' in document.createElement(''span'')){ var libObj = this; if (libObj.isObject(options)){ libObj.loopElement(options.element, options, function(element, options){ element.style.position = ''relative''; var childNodes = element.childNodes, length = childNodes.length || 0, x; for (x = 0; x < length; x++){ var item = childNodes[x]; if (item.nodeName !== ''#text''){ item.id = ''libJS-'' + libObj.token(12); item.draggable = true; item.style.cursor = ''pointer''; item.style.transition = ''all 0.5s ease''; item.addEventListener(''dragstart'', function(event){ event.preventDefault(); // some code }); } } element.addEventListener(''dragover'', function(event){ event.preventDefault(); }); element.addEventListener(''drop'', function(event){ event.preventDefault(); }); console.log(element.__proto__.ondrop); // View Error }); } }else throw ''ERROR: libJS.sortable(): this browser not support drag and drop event!''; } }; window.libJs = new libJS(); })(); libJs.sortable({ element : ''.sorter'' });

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Test</title> <style type="text/css"> *{ box-sizing: border-box; } .sorter{ border: 1px solid green; padding: 10px; } .sorter:after{ display: block; content: ''''; clear: both; } .sorterItem{ display: inline-block; float: left; width: 70px; height: 70px; margin-right: 10px; margin-bottom: 10px; } .sorterItem img{ display: block; max-width: 100%; max-height: 100%; min-width:100px; min-height:100px; } </style> </head> <body> <div class="sorter"> <div class="sorterItem"> <img src="/data/upload/noimage.jpg" /> </div> <div class="sorterItem"> <img src="/data/upload/noimage.jpg" /> </div> <div class="sorterItem"> <img src="/data/upload/noimage.jpg" /> </div> <div class="sorterItem"> <img src="/data/upload/noimage.jpg" /> </div> <div class="sorterItem"> <img src="/data/upload/noimage.jpg" /> </div> <div class="sorterItem"> <img src="/data/upload/noimage.jpg" /> </div> </div> </body> </html>

Y esto es un error: Uncaught TypeError: Illegal invocation

Eso estaba en la función goesCallback cuando arrastro .sorterItem y lo .sorterItem caer. Puede matar el navegador.

Entonces, en el método console.log(element.__proto__.ondrop) tengo console.log(element.__proto__.ondrop) para ver Error en alguna línea.

¿Cómo arreglar este error?

gracias a todos.


No puede hacer console.log(element.__proto__.ondrop) ya que ondrop es una propiedad de acceso.

¿Propiedades del Accesorio? Con referencia a esta SO Respuesta

Una propiedad de acceso es aquella que se define en términos de getters y setters, no como un valor almacenado en el que se podría escribir. El "par de funciones de acceso" denota el getter y la función setter.

Ver también esta respuesta

Así que, básicamente, al llamar a console.log(element.__proto__.ondrop) está invocando la función ondrop del elemento ondrop sin este contexto apropiado, lo que da como resultado un error de Invocación Ilegal .

Ejemplo de código
Un ejemplo de código de JavaScript para ilustrar el punto

var Person = { firstname: "John", lastname: "Doe", get fullname() { return this.firstname + " " + this.lastname }, set fullname(name) { this.firstname = name.split('' '')[0] this.lastname = name.split('' '')[1] } } console.log(Person.fullname) // will trigger the getter function ''fullname'' Person.fullname = "Jane Doe" // will trigger the setter function ''fullname'' console.log(Person.fullname) // logs Jane Doe

Así que cuando llamas a console.log(element.__proto__.ondrop) esencialmente estás activando el getter ondrop sin un contexto válido .

Actualizar:

Supongo que lo que quería hacer era inspeccionar por qué los Drag-events no se activaban y terminaba colocando console.log(element.__proto__.ondrop) que, como ya se ha respondido, provocó el error de IllegalInvocation , lo que dio como resultado un clase de error totalmente diferente a la que estabas tratando de depurar

El motivo por el que los eventos de arrastre no se activan es la llamada de función dentro de los manejadores Event.preventDefault () , que cita de MDN

El método preventDefault () de la interfaz de eventos le dice al agente de usuario que si el evento no se controla, su acción predeterminada no debería tomarse como lo haría normalmente.

En su caso, la acción predeterminada significa la funcionalidad relacionada con Arrastrar, que (¡por descuido!) Impide la ejecución.

Le sugiero que lea más acerca de HTML5 arrastrar y soltar API en MDN.