addeventlistener drop error"Uncaught TypeError:Illegal invocation"

Mr *_*Ken 10 javascript drag-and-drop callback html5sortable

我按功能创建新的Object,我创建了sortable要使用的方法,但是在回调函数上有错误

;"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'
});
Run Code Online (Sandbox Code Playgroud)
<!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>
Run Code Online (Sandbox Code Playgroud)

这是一个错误: Uncaught TypeError: Illegal invocation

那是在goesCallback功能,当我拖累了.sorterItem,我放弃它.它可以杀死浏览器.

所以,在sortable方法中我必须console.log(element.__proto__.ondrop)在某一行查看Error.

如何解决这个错误?

谢谢大家.

riy*_*ali 5

您不能执行console.log(element.__proto__.ondrop)ondrop是访问器属性。

访问器属性? 参考此SO答案

访问器属性是根据获取器和设置器定义的属性,而不是可能要写入的存储值。“一对访问器功能”表示吸气剂和设定器功能。

另请参阅此答案

因此,基本上,通过调用console.log(element.__proto__.ondrop)您会在ondrop没有正确使用此上下文的情况下调用元素的getter函数,将导致非法调用错误。

代码示例
一个JavaScript代码示例来说明要点

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
Run Code Online (Sandbox Code Playgroud)

因此,当您打电话时,console.log(element.__proto__.ondrop)您实际上是在ondrop没有有效上下文的情况下触发吸气剂。

更新:

我猜您想做的是检查一下为什么拖动事件没有触发,而您最终放了一个console.log(element.__proto__.ondrop),因为它已经被回答了,导致了IllegalInvocation错误,错误,导致与您尝试的错误完全不同的错误类别调试!

您的Drag事件未触发的原因是处理程序Event.preventDefault()中的函数调用,引用自MDN

事件接口的preventDefault()方法告诉用户代理,如果事件未处理,则不应像通常那样采取其默认操作。

您的情况是默认操作意味着与Drag相关的功能,您(无意间)阻止了该功能的执行!

建议您阅读有关MDN上HTML5拖放API的更多信息。