我按功能创建新的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'
});
&#13;
<!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>
&#13;
这是一个错误:Uncaught TypeError: Illegal invocation
当我拖动goesCallback
并放弃它时,这是.sorterItem
函数。它可以杀死浏览器。
因此,在sortable
方法中我console.log(element.__proto__.ondrop)
可以在某行查看错误。
如何解决此错误?
谢谢大家。答案 0 :(得分:5)
你不能console.log(element.__proto__.ondrop)
,因为ondrop是一个访问者属性。
访问者属性?参考此SO Answer
访问者属性是根据getter和setter定义的属性,而不是可能写入的存储值。 “配对函数对”表示getter和setter函数。
所以基本上通过调用console.log(element.__proto__.ondrop)
来调用元素的ondrop
getter函数而没有正确的this context会导致Illegal Invocation错误。
代码示例
一个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
因此,当您致电console.log(element.__proto__.ondrop)
时,您实际上是在没有有效上下文的情况下触发ondrop
获取者。
我想你想要做的是检查为什么Drag-events没有被触发你最后放了一个console.log(element.__proto__.ondrop)
,因为它已经被回答,导致IllegalInvocation
错误,结果在一个完全不同的错误类别,然后是你试图调试的那个!
您的Drag事件未触发的原因是处理程序Event.preventDefault()内的函数调用,引自MDN
Event接口的preventDefault()方法告诉用户代理,如果事件未处理,则不应采取其默认操作。
在您的情况下,默认操作表示与拖动相关的功能,您(无意中)阻止执行!
我建议您在MDN上阅读有关HTML5 Drag and Drop API的更多信息。
答案 1 :(得分:3)
错误&#34;非法调用&#34;表示您尝试使用错误的上下文调用可调用函数,上下文是调用该方法的对象。让我分解console.log
:
console.log(element.__proto__.ondrop)
在这里,您尝试记录element.__proto__.ondrop
。首先,让我解释element.__proto__
。每个对象Object.prototype.__proto__
上的访问器属性是一个访问器属性,指向该对象的原型,用于解析查找链中的方法。例如:
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
&#13;
这里,实例的__proto__
引用构造实例的构造函数的prototype
。现在,在您的情况下,来自DOM的元素的__proto__
将是HTMLDivElement
或其他原型的行,具体取决于它是什么类型的元素。出于这个答案的目的,我们会说它是div
。
现在,当您尝试访问ondrop
原型的HTMLDivElement
属性时,您会收到非法调用,因为您正在尝试访问{{1来自ondrop
原型的静态,而非实际的HTMLDivElement
元素!这导致了错误的背景&#34;因为您试图在div
上调用访问者,而不是来自DOM的HTMLDivElement.prototype
!
要解决此问题&#34;,请勿访问div
密钥。如果您想访问元素的__proto__
属性,只需执行ondrop
。