我正在尝试将div与对象绑定,以使div具有可以执行的方法。我特别希望用户单击div时,它开始在屏幕上移动,然后如果您单击另一个div,它也开始移动。
由于某种原因,我在moveCarForward方法函数中的this.element未定义。
function Car(element) {
this.element = element;
this.element.addEventListener("click", function() {
this.style.border = "3px solid hotpink";
startDrive();
}, false);
startDrive = function() {
this.carDrivingInterval = setInterval(moveCarForward, 3000);
}
moveCarForward = function() {
this.element.style.x = this.element.offsetLeft + 10 + "px";
}
}
var arrayCarsElements = document.getElementsByClassName("car");
var arrCar = [];
for (var i = 0; i < arrayCarsElements.length; i++) {
arrCar[i] = new Car(arrayCarsElements[i]);
}
<div class="car" id="tesla" style="width: 50px; height: 50px; background: #ccc; margin-bottom: 10px;"></div>
答案 0 :(得分:1)
How does the "this" keyword work?解释了this
的工作方式。我建议您检查一下。
在这种情况下,有必要与您的Object
进行交互,同时保留其引用。在函数中定义this
(new Object()
)并返回到Object
即可解决问题。
var Car = function(element) {
var car = this;
car.element = element;
car.element.addEventListener("click", function() {
car.element.style.border = "3px solid hotpink";
car.startDrive();
}, false);
car.moveCarForward = function() {
car.element.style.marginLeft = car.element.offsetLeft + 10 + "px";
}
car.startDrive = function() {
car.carDrivingInterval = setInterval(car.moveCarForward, 3000);
}
return car;
}
var arrayCarsElements = document.getElementsByClassName("car");
var arrCar = [];
for (var i = 0; i < arrayCarsElements.length; i++) {
arrCar[i] = new Car(arrayCarsElements[i]);
}
<div class="car" id="tesla" style="width: 50px; height: 50px; background: #ccc; margin-bottom: 10px;"></div>
<div class="car" id="fiat" style="width: 50px; height: 50px; background: #ccc; margin-bottom: 10px;"></div>
答案 1 :(得分:0)
这里有很多事情要做。首先,如注释中所述,您需要更好地控制this
。箭头函数(() => {}
)可以提供帮助,因为它们在词法上绑定了this
。您也可以显式bind()
。使用事件侦听器和计时器时,您需要执行此操作,因为侦听器会调用该函数,从而更改this
的含义。以下代码片段显示了两者。
将功能放在Car
原型上也使管理this
变得容易。
此外,我认为您的CSS有点偏离了,我将位置更改为absolute
,并使用left
移动了盒子。
function Car(element) {
this.element = element;
this.element.addEventListener("click", () => { // use arrow function or bind()
this.element.style.border = "3px solid hotpink";
this.startDrive();
}, false);
}
Car.prototype.startDrive = function() {
this.carDrivingInterval = setInterval(this.moveCarForward.bind(this), 1000); // use bind or arrow function
}
Car.prototype.moveCarForward = function() {
this.element.style.left = this.element.offsetLeft + 10 + "px";
}
var arrayCarsElements = document.getElementsByClassName("car");
var arrCar = [];
for (var i = 0; i < arrayCarsElements.length; i++) {
arrCar[i] = new Car(arrayCarsElements[i]);
}
<div class="car" id="tesla" style="position:absolute; left: 10px; width: 50px; height: 50px; background: #ccc; margin-bottom: 10px;"></div>
<div class="car" id="ford" style="position:absolute; top: 75px; left: 10px; width: 50px; height: 50px; background: #ccc; margin-bottom: 10px;"></div>
可能还有更多工作要做(例如单击两次时会发生什么),但是希望这可以帮助您入门。
答案 2 :(得分:0)
这是正确的代码。功能Car(element)-如果在控制台中打印“ element”,它将给出两个div。单击一个div时,必须通过startDrive(element)发送当前的div参数。
function Car(element) {
element.addEventListener("click", function() {
this.style.border = "3px solid hotpink";
startDrive(element);
}, false);
startDrive = function(element) {
carDrivingInterval = setInterval(function() { moveCarForward(element); }, 3000);
}
moveCarForward = function(element) {
element.style.left = element.offsetLeft + 10 + "px";
}
}
var arrayCarsElements = document.getElementsByClassName("car");
var arrCar = [];
for (var i = 0; i < arrayCarsElements.length; i++) {
arrCar[i] = new Car(arrayCarsElements[i]);
}
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>javascript scope with object method</title>
</head>
<body>
<div class="car" id="tesla" style="position:absolute;width: 50px; height: 50px;top:10px; left: 10px; background: #ccc; margin-bottom: 10px;"></div>
<div class="car" id="bmw" style="position:absolute;width: 50px; height: 50px;top:100px; left: 10px; background: #ccc; margin-bottom: 10px;"></div>
</body>
</html>
答案 3 :(得分:-1)
您可以使用一个对象定义您的功能并返回该对象,以便您也可以从外部Car
函数获得该功能(例如,如果要从外部停止汽车,则为示例)。看到我的以下代码,它具有启动/停止功能。只需运行摘要即可查看。
function Car(element) {
var car = {
element: element,
running: false,
start: function() {
this.carDrivingInterval = setInterval(this.moveCarForward.bind(this), 1000);
this.running = true;
},
stop: function(){
clearInterval(this.carDrivingInterval);
this.running = false;
},
moveCarForward: function() {
this.element.style.left = this.element.offsetLeft + 10 + "px";
}
};
element.addEventListener("click", function(event) {
if(!car.running){
this.style.border = "3px solid hotpink";
car.start();
}else{
this.style.border = "3px solid red";
car.stop();
}
});
return car;
}
var arrayCarsElements = document.getElementsByClassName("car");
var arrCar = [];
for (var i = 0; i < arrayCarsElements.length; i++) {
arrCar[i] = new Car(arrayCarsElements[i]);
}
<div class="car" id="tesla1" style="position: absolute; width: 50px; height: 50px; background: #ccc; margin-bottom: 10px;">Car 1</div>
<div class="car" id="tesla2" style="position: absolute; width: 50px; height: 50px; background: #eee; margin-bottom: 10px; left: 50px;">Car 2</div>
当我使用对象定义功能时,现在我可以完美地使用this
了。