JavaScript(ES6)类没有';不要让元素拖拉
我正在尝试使用类将函数转换为ES6。以下代码作为一个函数,定义元素以使其可拖动:JavaScript(ES6)类没有';不要让元素拖拉,javascript,ecmascript-6,es6-class,Javascript,Ecmascript 6,Es6 Class,我正在尝试使用类将函数转换为ES6。以下代码作为一个函数,定义元素以使其可拖动: 'use strict'; var Drag = function(el) { var elem = document.querySelector(el); this.move =(e)=> { elem.style = 'position:absolute;'+ 'top:'+e.clientY+'px;'+
'use strict';
var Drag = function(el) {
var elem = document.querySelector(el);
this.move =(e)=> {
elem.style =
'position:absolute;'+
'top:'+e.clientY+'px;'+
'left:'+e.clientX+'px;'+
'margin-left:-25px;'+
'margin-top:-10px';
}
this.up =()=> { window.removeEventListener('mousemove', this.move, true); }
this.down =()=> { window.addEventListener('mousemove', this.move, true); }
this.events =()=> {
elem.addEventListener('mousedown', this.down, false);
window.addEventListener('mouseup', this.up, false);
}
return this.events();
};
window.onLoad = (()=> {
var drag = new Drag('#dragme');
})();
上面的代码正在运行。但是,下面的代码甚至没有在控制台中显示错误。这就像它不会执行,但它部分执行。我觉得方法up()
和down()
可能会导致问题。因为某种原因它不会开火
'use strict';
class Drag {
constructor(el) {
this.el = document.querySelector(el);
this.events();
}
move(e) {
this.el.style =
'position:absolute;'+
'top:'+e.clientY+'px;'+
'left:'+e.clientX+'px;'+
'margin-left:-25px;'+
'margin-top:-10px';
}
up() { window.removeEventListener('mousemove', this.move, true); }
down() { window.addEventListener('mousemove', this.move, true); }
events() {
this.el.addEventListener('mousedown', this.down, false);
window.addEventListener('mouseup', this.up, false);
}
}
window.onLoad = (()=> {
const drag = new Drag('#dragme');
})();
我做错了什么?提前感谢。在第一个示例中,构造函数将每个方法的一个新实例分配给
this
。您还使用了箭头函数,它捕获此
上下文
在第二种情况下,类的所有实例共享相同的方法
这有两个问题:
this
上下文是不固定的,因此当window
调用this.move
作为mousemove处理程序时,move
方法中的this
不再引用Drag
的实例。它指的是窗口
this.move
,而不仅仅是当前的Drag
的move
方法
解决方案:
就像您在第一个示例中所做的那样,将方法附加到构造函数中。另一方面,这几乎违背了使用类的目的:
class Drag {
constructor(el) {
this.el = document.querySelector(el);
this.move = (e) => ....;
this.up = () => .....;
// etc...
this.events();
}
events() {
this.el.addEventListener('mousedown', this.down, false);
window.addEventListener('mouseup', this.up, false);
}
}
旁注:我倾向于通过根本不使用这个
来消除所有的这个
混乱。毕竟,代码中的new Drag()
实际上并没有创建任何可以与之高效交互的内容:
function drag(el) {
var elem = document.querySelector(el);
function move(e) {
elem.style =
'position:absolute;'+
'top:'+e.clientY+'px;'+
'left:'+e.clientX+'px;'+
'margin-left:-25px;'+
'margin-top:-10px';
}
function up() { window.removeEventListener('mousemove', move, true); }
function down() { window.addEventListener('mousemove', move, true); }
function events() {
elem.addEventListener('mousedown', down, false);
window.addEventListener('mouseup', up, false);
}
};
window.onLoad = (()=> {
drag('#dragme');
})();
在第一个示例中,构造函数将每个方法的新实例分配给this
。您还使用了箭头函数,它捕获此
上下文
在第二种情况下,类的所有实例共享相同的方法
这有两个问题:
它们的this
上下文是不固定的,因此当window
调用this.move
作为mousemove处理程序时,move
方法中的this
不再引用Drag
的实例。它指的是窗口
如果这真的执行过(尽管不会,因为原因1)
window.removeEventListener('mousemove',this.move,true)
它将删除类的所有实例共享的this.move
,而不仅仅是当前的Drag
的move
方法
解决方案:
就像您在第一个示例中所做的那样,将方法附加到构造函数中。另一方面,这几乎违背了使用类的目的:
class Drag {
constructor(el) {
this.el = document.querySelector(el);
this.move = (e) => ....;
this.up = () => .....;
// etc...
this.events();
}
events() {
this.el.addEventListener('mousedown', this.down, false);
window.addEventListener('mouseup', this.up, false);
}
}
旁注:我倾向于通过根本不使用这个
来消除所有的这个
混乱。毕竟,代码中的new Drag()
实际上并没有创建任何可以与之高效交互的内容:
function drag(el) {
var elem = document.querySelector(el);
function move(e) {
elem.style =
'position:absolute;'+
'top:'+e.clientY+'px;'+
'left:'+e.clientX+'px;'+
'margin-left:-25px;'+
'margin-top:-10px';
}
function up() { window.removeEventListener('mousemove', move, true); }
function down() { window.addEventListener('mousemove', move, true); }
function events() {
elem.addEventListener('mousedown', down, false);
window.addEventListener('mouseup', up, false);
}
};
window.onLoad = (()=> {
drag('#dragme');
})();
绑定属于事件的方法并使用此
,否则将无法定义上下文
move = (e) => {
this.el.style = ...;
}
绑定属于事件的方法并使用此
,否则将无法定义上下文
move = (e) => {
this.el.style = ...;
}
另一个解决方案(请注意,我更喜欢JLRishe中的解决方案!)是显式地提供这个
变量是什么
'use strict';
class Drag {
constructor(el) {
this.el = document.querySelector(el);
this.events();
}
move(e) {
this.el.style =
'position:absolute;'+
'top:'+e.clientY+'px;'+
'left:'+e.clientX+'px;'+
'margin-left:-25px;'+
'margin-top:-10px';
}
up() { window.removeEventListener('mousemove', this.eventHandler, true); }
down() {
this.eventHandler = this.move.bind(this)
window.addEventListener('mousemove', this.eventHandler , true);
}
events() {
this.el.addEventListener('mousedown', this.down.bind(this), false);
window.addEventListener('mouseup', this.up.bind(this), false);
}
}
window.onLoad = (()=> {
const drag = new Drag('#dragme');
})();`
另一个解决方案(请注意,我更喜欢JLRishe中的解决方案!)是显式地提供这个
变量是什么
'use strict';
class Drag {
constructor(el) {
this.el = document.querySelector(el);
this.events();
}
move(e) {
this.el.style =
'position:absolute;'+
'top:'+e.clientY+'px;'+
'left:'+e.clientX+'px;'+
'margin-left:-25px;'+
'margin-top:-10px';
}
up() { window.removeEventListener('mousemove', this.eventHandler, true); }
down() {
this.eventHandler = this.move.bind(this)
window.addEventListener('mousemove', this.eventHandler , true);
}
events() {
this.el.addEventListener('mousedown', this.down.bind(this), false);
window.addEventListener('mouseup', this.up.bind(this), false);
}
}
window.onLoad = (()=> {
const drag = new Drag('#dragme');
})();`
window.addEventListener('mousedown',this.down.bind(this),false);等否则
this`对象将是触发事件的元素。如果要使用箭头函数,您仍然必须将它们放入构造函数中
,就像原始函数中一样。window.addEventListener('mousedown',this.down.bind(this),false);等否则
this`对象将是触发事件的元素。如果要使用箭头函数,您仍然必须将它们放入构造函数
中,就像原始函数
中一样。非常感谢,这样做了。我知道这门课有点多余。我只是想了解函数/类的区别,因为我来自PHP,并试图找到相似之处,以便更好地与之相处,哈哈。再次感谢你的解释。非常感谢,就这样。我知道这门课有点多余。我只是想了解函数/类的区别,因为我来自PHP,并试图找到相似之处,以便更好地与之相处,哈哈。再次感谢你的解释。这很好地解决了问题。不过我只能接受一个答案,我会投票支持你的工作,谢谢你。这就很好了。不过我只能接受一个答案,我会投票支持你的工作,谢谢。