I create new Object by function, and i create sortable
method to use, but that have an error on callback function
;"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>
I create new Object by function, and i create sortable
method to use, but that have an error on callback function
;"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>
And this is an Error: Uncaught TypeError: Illegal invocation
That was in goesCallback
function when I drag .sorterItem
and i drop it. It can kill the browser.
So, in sortable
method i have console.log(element.__proto__.ondrop)
to view Error at some line.
How to fix this error?
thank everyone.
Share Improve this question edited Jun 13, 2017 at 4:32 Canh Nguyen asked Jun 5, 2017 at 5:04 Canh NguyenCanh Nguyen 3331 silver badge18 bronze badges 2-
Not sure what you are exactly trying to achieve with the
console.log
. Do you want to see the function? It looks like you cannot log most functions. I ranvar el = document.querySelector('.sorter'); for (let k of Object.keys(el.__proto__.__proto__)) { try { console.log(k, el.__proto__[k]); } catch (e) { } }
and that prints only a handful of functions:onmouseenter
,onmouseleave
,click
,drag
andfocus
. It would be good if you could explain what error you get without theconsole.log
, because I don't get one. – Just a student Commented Jun 9, 2017 at 9:29 - @Justastudent , No, I don't want to see function. It seems that somebody has changed the content of my question, which makes it no longer what I want to ask. I'm handling the drop event but it could kill the browser, and I did the console.log () element to see but get the error. So i got console.log () to know the error at any given line – Canh Nguyen Commented Jun 13, 2017 at 4:14
2 Answers
Reset to default 5You cannot do console.log(element.__proto__.ondrop)
as ondrop is an accessor-property.
Accessor Properties? With reference to this SO Answer
An accessor property is one that is defined in terms of getters and setters, not as a stored value that might be written to. The "pair of accessor functions" denotes the getter and the setter function.
Also see this answer
So basically by calling console.log(element.__proto__.ondrop)
you are invoking the element's ondrop
getter function without proper this context which results in Illegal Invocation error.
Code Example
A javascript code example to illustrate the point
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
So when you call console.log(element.__proto__.ondrop)
you are essentially triggering the ondrop
getter without a valid context.
Update:
I guess what you wanted to do was to inspect why the Drag-events were not firing and you ended up putting a console.log(element.__proto__.ondrop)
which, as it's been already answered, caused the IllegalInvocation
error, resulting in a totally different class of error then the one you were trying to debug!
The reason why your Drag events are not firing is the function call inside the handlers Event.preventDefault(), quoting from MDN
The Event interface's preventDefault() method tells the user agent that if the event goes unhandled, its default action should not be taken as it normally would be.
In your case, the default action means the Drag-related functionality, which, you are (inadvertently) preventing from execution!
I suggest you read more about HTML5 Drag and Drop API on MDN.
The error "Illegal Invocation" means you are trying to call a callable function with the wrong context, the context being the object the method is called on. Let me break down the console.log
:
console.log(element.__proto__.ondrop)
Here, you're trying to log element.__proto__.ondrop
. First, let me explain element.__proto__
. The accessor property on every object, Object.prototype.__proto__
is an accessor property that points to the prototype of that object and is used to resolve methods in the lookup chain. For example:
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
Here, __proto__
of an instance refers to the prototype
of the constructor that constructed the instance. Now, in your case, the __proto__
of an element from the DOM would be something along the lines of the prototype of HTMLDivElement
or something else depending on what type of element it is. For the purpose of this answer, we'll say it's a div
.
Now, when you try to access the property ondrop
of HTMLDivElement
's prototype, you get an illegal invocation because you're trying to access ondrop
statically from the HTMLDivElement
prototype, not an actual div
element! This leads to the "wrong context" because you're trying to call the accessor on HTMLDivElement.prototype
, not a div
from the DOM!
To "fix this", don't access the __proto__
key. If you want to access the element's ondrop
property, just do element.ondrop
.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744164164a4561228.html
评论列表(0条)