事件监听器不触发?

时间:2018-08-16 21:20:46

标签: javascript html mouseevent addeventlistener

我尝试将两个事件侦听器添加到我的外部脚本中,两个侦听器都可以作为附加到HTML元素的事件属性正常工作。

事件侦听器是:

parent.addEventListener("mousemove", where(event));
parent.addEventListener("mouseleave", reset(event));

其余的代码可以在这里看到: https://codepen.io/rowancavanagh/pen/NBmPGv 或在摘要中:

window.onload = function() {
	var parent = document.querySelectorAll(".shadowed");
	var shadow = document.createElement("div");
	for (var i = 0; i < parent.length; i++) {
	  parent[i].appendChild(shadow);
	}
	parent.addEventListener("mousemove", where(event));
	parent.addEventListener("mouseleave", reset(event));
}

function where(e) {
	var x = e.offsetX / e.target.offsetWidth * 10 - 5;
	var y = e.offsetY / e.target.offsetHeight * 10 - 5;
	e.target.querySelector('.shadowed div').style.transform = 'translateX(' + x + 'px) translateY(' + y + 'px)';
}

function reset(e) {
	e.target.querySelector('.shadowed div').style.transform = 'translateX(0px) translateY(0px)';
}
* {
	margin: 0;
	padding: 0;
	box-sizing: border-box;
}

html, body {
	height: 100%;
}

body {
	background-color: #eee;
	display: flex;
	justify-content: center;
	align-items: center;
}

.shadowed {
	position: relative;
	width: 400px;
	height: 240px;
	margin: 10px;
	background-color: #fff;
	border-radius: 5px;
}

.shadowed div {
	position: absolute;
	bottom: 0;
	right: 0;
	margin: 0 -10px -10px 0;
	width: calc(100% - 40px);
	height: calc(100% - 40px);
	background-color: #ddd;
	border-radius: 5px;
	z-index: -1;
	transform: translateY(0px) translateX(0px);
	transition: transform .1s ease-out;
}
<div class="shadowed"></div>

如您所见,它们应该在mousemove和mouseleave上触发几个功能,但不是。

有什么想法我在做什么错吗?

4 个答案:

答案 0 :(得分:2)

绑定事件后,将立即调用该函数。事件处理程序需要一个函数引用。

parent.addEventListener("mousemove", where(event));

应该是

parent.addEventListener("mousemove", where);

parent变量还包含该特定类的所有元素的活动节点列表。 addEventListener是可用于需要单独绑定的特定元素的方法。

window.onload = function() {
    var parent = document.querySelectorAll(".shadowed");
    var shadow = document.createElement("div");
    for (var i = 0; i < parent.length; i++) {
      parent[i].appendChild(shadow);
    }

    parent.forEach(function(elem) {
       elem.addEventListener("mousemove", where);
       elem.addEventListener("mouseleave", reset);
    });
}

答案 1 :(得分:2)

parent是您使用的document.querySelectorAll的NodeList。您将需要使用Array.prototype.forEachfor循环将事件侦听器添加到查询选择器选择的每个元素中。如果只想匹配第一个元素,则可以使用document.querySelector并以已经完成的方式添加事件侦听器,因为它将返回匹配选择器的第一个Element。

更改

window.onload = function() {
    var parent = document.querySelectorAll(".shadowed");
    var shadow = document.createElement("div");
    for (var i = 0; i < parent.length; i++) {
      parent[i].appendChild(shadow);
    }
    parent.addEventListener("mousemove", where(event));
    parent.addEventListener("mouseleave", reset(event));
}

收件人

window.onload = function() {
    var parent = document.querySelectorAll(".shadowed");
    var shadow = document.createElement("div");
    for (var i = 0; i < parent.length; i++) {
      parent[i].appendChild(shadow);
    }
    parent.forEach(function(item){
      item.addEventListener("mousemove", where);
      item.addEventListener("mouseleave", reset);
    });
}

此外,您只需要将函数的名称提供给事件侦听器即可;您无需调用该函数(传递事件Object)。

更改

parent.addEventListener("mousemove", where(event));
parent.addEventListener("mouseleave", reset(event));

收件人

parent.addEventListener("mousemove", where);
parent.addEventListener("mouseleave", reset);

window.onload = function() {
	var parent = document.querySelectorAll(".shadowed");
	var shadow = document.createElement("div");
	for (var i = 0; i < parent.length; i++) {
	  parent[i].appendChild(shadow);
	}
  parent.forEach(function(item){
   	item.addEventListener("mousemove", where);
	  item.addEventListener("mouseleave", reset);
  });
}

function where(e) {
	var x = e.offsetX / e.target.offsetWidth * 10 - 5;
	var y = e.offsetY / e.target.offsetHeight * 10 - 5;
	e.target.querySelector('.shadowed div').style.transform = 'translateX(' + x + 'px) translateY(' + y + 'px)';
}

function reset(e) {
	e.target.querySelector('.shadowed div').style.transform = 'translateX(0px) translateY(0px)';
}
* {
	margin: 0;
	padding: 0;
	box-sizing: border-box;
}

html, body {
	height: 100%;
}

body {
	background-color: #eee;
	display: flex;
	justify-content: center;
	align-items: center;
}

.shadowed {
	position: relative;
	width: 400px;
	height: 240px;
	margin: 10px;
	background-color: #fff;
	border-radius: 5px;
}

.shadowed div {
	position: absolute;
	bottom: 0;
	right: 0;
	margin: 0 -10px -10px 0;
	width: calc(100% - 40px);
	height: calc(100% - 40px);
	background-color: #ddd;
	border-radius: 5px;
	z-index: -1;
	transform: translateY(0px) translateX(0px);
	transition: transform .1s ease-out;
}
<div class="shadowed"></div>

答案 2 :(得分:1)

parent是运行querySelectorAll的结果,因此它将是一个元素数组。您可以将事件侦听器移入循环,以便.shadowed的所有实例都将侦听事件。

另一件事是将函数传递给事件侦听器的方式。 parent.addEventListener("mousemove", where(event));会将函数调用的结果设置为侦听器,您只想传递函数的实际名称。 onload可能看起来像这样:

window.onload = function() {
    var parent = document.querySelectorAll(".shadowed");
    var shadow = document.createElement("div");
    for (var i = 0; i < parent.length; i++) {
      parent[i].appendChild(shadow);
      parent[i].addEventListener("mousemove", where);
      parent[i].addEventListener("mouseleave", reset);
    }
}

这些更改之后

答案 3 :(得分:1)

parent是一个数组,您无法将EventListener添加到数组中,因此需要在for循环内将EventListener添加到数组的每个元素中

例如:

for (var i = 0; i < parent.length; i++) {
  parent[i].appendChild(shadow);
  parent[i].addEventListener("mousemove", where(event));
  parent[i].addEventListener("mouseleave", reset(event));
}