我有一个简单的文本按钮,旁边有一个箭头图像。我希望当有人将鼠标悬停在按钮上时箭头图像会移动。
我目前正在使用JS'document.getElementById ...'在一个实例中进行此操作,但是我的网站上有多个按钮希望具有相同的行为。我首先想到的是使用类而不是id,并使用相同的功能。
无论出于何种原因,document.getElementsByClassName
都不起作用-即使在一个实例中也是如此。
这是一个更简单的版本来演示-在Codepen上查看:https://codepen.io/sdorr/pen/JxYNpg
HTML
<HTML>
<a href="#" class="button" onmouseover="move()" onmouseout="moveBack()">hover over me</a>
<div id="block"></div>
<a href="#" class="button" onmouseover="moveAlt()" onmouseout="moveBackAlt()">hover over me</a>
<div class="block"></div>
CSS
* {
margin: 0;
padding: 0;
}
.button {
color: #000000;
text-decoration: none;
background-color: cyan;
margin: 0;
display: block;
width: 300px;
padding: 20px;
text-align: center;
}
#block {
width: 30px;
height: 30px;
background-color: red;
}
.block {
width: 30px;
height: 30px;
background-color: green;
}
JS
function move() {
document.getElementById("block").style.marginLeft = "35px";
}
function moveBack() {
document.getElementById("block").style.marginLeft = "0px";
}
function moveAlt() {
document.getElementsByClassName("block").style.marginLeft =
"35px";
}
function moveBackAlt() {
document.getElementsByClassName("block").style.marginLeft =
"0px";
}
首先,为什么类的行为不起作用,但id可以正常工作?
第二,一个类是否可以解决此问题,并且可以在具有相同两个功能(onmouseover / onmouseout)的所有按钮上进行扩展?
如果没有,关于解决方案有什么想法吗?我目前有一个使用jQuery的解决方案,该解决方案确实有效,但是将鼠标悬停在一个按钮上时,所有箭头图像都会在网站上移动。我不必介意这种行为,因为一次只能看到一个按钮-但是我正在尝试学习JS并用自己的解决方案解决问题!
答案 0 :(得分:0)
非常感谢您渴望自己学习而不依赖预制解决方案的愿望。保持这种精神,你会去的地方!
对于getElementsById
,我们知道这应该适用于一个元素,因为该函数返回单个元素。
但是,getElementsByClassName
返回什么?
(请参阅:https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName)
它返回一个HTMLCollection
,您可以循环访问它来更改单个元素的style
。
因此,要使其与JavaScript一起使用,您需要编写一个函数,该函数将能够识别要移动的特定div.block
。但是,这使您回到起点,需要一些特定的标识符,例如id
或dataset
值才能传递给函数。
或者,根据您提供的HTML结构,您可以在被点击的nextElementSibling
上寻找a
。但是我会设置一个eventListener
而不是将JS函数作为值添加到onmouseenter
属性中。
const btns = document.getElementsByTagName('a');
/*** UPDATE forEach is a NodeList method, and will fail on HTMLCollection ***/
/* this fails -> Sorry! ~~btns.forEach(button=>{~~
/* the following will work
/**********/
for (let i = 0; i < btns.length; i++){
btns[i].addEventListener('mouseenter', function(e) {
//we pass e to the function to get the event and to be able to access this
const block = this.nextElementSibling;
block.style.marginLeft = "35px";
})
btns[i].addEventListener('mouseleave', function(e) {
const block = this.nextElementSibling;
block.style.marginLeft = "0";
})
}
但是有兄弟姐妹,只有CSS解决方案。
如果我们只是来回移动,我们可以将Adjacent Sibling Selector
与:hover
状态选择器结合使用,并且不需要JavaScript。
.button:hover+.block {
margin-left: 35px;
}
查看下方的片段
* {
margin: 0;
padding: 0;
}
.button {
color: #000000;
text-decoration: none;
background-color: cyan;
margin: 0;
display: block;
width: 300px;
padding: 20px;
text-align: center;
}
.block {
width: 30px;
height: 30px;
background-color: green;
}
.button:hover+.block {
margin-left: 35px;
}
<a href="#" class="button">hover over me</a>
<div class="block"></div>
<a href="#" class="button">hover over me</a>
<div class="block"></div>
答案 1 :(得分:0)
如Vecta所述,getElementsByClassName
返回类似数组的形式。您需要执行以下操作才能获取第一个元素:
function moveAlt() {
document.getElementsByClassName("block")[0].style.marginLeft = "35px";
}
function moveBackAlt() {
document.getElementsByClassName("block")[0].style.marginLeft = "0px";
}
但是,更好的解决方案可能是使用document.querySelector
,其操作类似于jQuery的$()
语法:
function moveAlt() {
document.querySelector(".block").style.marginLeft = "35px";
}
function moveBackAlt() {
document.querySelector(".block").style.marginLeft = "0px";
}