使用 javascript 动态创建 onmouseover/onmouseout 函数?
Create onmouseover/onmouseout functions dynamically with javascript?
下面是我需要复制的函数示例:
document.getElementById('img1').onmouseover = function() {
document.getElementById('img1').style.width = expandTo + '%';
expandCompensate(1);
}
document.getElementById('img1').onmouseout = function() {
expandReset();
}
情况是我有一个 for
循环创建一些 div
元素,并且它们的数量是动态的。截至目前,我已经创建了 4 个 div 元素,因此我为 img1
、img2
、img3
和 img4
创建了上述函数的 4 次迭代.但是我想做的是根据我决定创建的 div
个元素(基于变量)动态创建 onmouseover
和 onmouseout
函数。
有什么办法吗?这是上下文的所有代码(不多),JS 中有注释,对所有内容进行了解释。我尝试自动化的部分在底部:
https://jsfiddle.net/4w0714su/3/
这是我正在努力实现的上下文的工作示例:
http://www.ericsartor.ca/imgwide
仅供参考:我选择的图像是随机的,我只需要高分辨率图像。这样做只是为了练习!感谢任何能帮我解决这个问题的人!
我不能很好地理解你的代码,但我会特别回答你的问题。
你可以通过循环实现你想要的:
for (var i = 0; i < 4; i++) {
document.getElementById('img' + i).onmouseover = function() {
this.style.width = expandTo + '%';
expandCompensate(Number(this.id.replace('img', '')));
};
document.getElementById('img' + i).onmouseout = function() {
expandReset();
}
}
注意:您不能在事件处理程序的函数中使用 i
变量,因为它将始终是 4
,因为它将完成循环,并且永远不会再次更改.
另一种方法是使用 IIFE (Immediately-invoked function expression),例如:
for (var i = 0; i < 4; i++) {
(function(n) {
document.getElementById('img' + n).onmouseover = function() {
this.style.width = expandTo + '%';
expandCompensate(n);
};
document.getElementById('img' + n).onmouseout = function() {
expandReset();
}
})(i);
}
这样做,您将当前的 i
值传递给一个函数,因此在该范围内,n
的值对于每次执行都是不同的,例如 0
、1
、2
和 3
.
An immediately-invoked function expression (or IIFE, pronounced
"iffy") is a JavaScript design pattern which produces a lexical scope
using JavaScript's function scoping.
This could be achieved by iterating all those DOM
elements and binding events in a loop
.
As we bind events in loop
, and event callback
is being executed later when loop would be iterated completely, we need to maintaing the value of current iteration using CLOSURE
.
试试这个片段:
var pageHeight = document.getElementById('findBottom').getBoundingClientRect().bottom,
numOfPics = 4; //the number of div elements to create
//creates the div elements within a container div in the HTML document
for (var i = 1; i <= numOfPics; i++) {
document.getElementById('imgContain').innerHTML += '<div id="img' + i + '" class="imgPane"></div>';
}
//used to resize all divs if the window changes size
window.onresize = function() {
pageHeight = document.getElementById('findBottom').getBoundingClientRect().bottom;
for (var i = 1; i <= imgClasses.length; i++) {
document.getElementById('img' + i).style.height = pageHeight + 'px';
}
for (var i = 1; i <= imgClasses.length; i++) {
document.getElementById('img' + i).style.width = 100 / imgClasses.length + '%';
}
};
//sets the height of each div to be the mximum height of the page (without scrolling)
for (var i = 1; i <= numOfPics; i++) {
document.getElementById('img' + i).style.height = pageHeight + 'px';
}
//makes all the divs equal percentage widths
for (var i = 1; i <= numOfPics; i++) {
document.getElementById('img' + i).style.width = 100 / numOfPics + '%';
}
//the percentage of the page the hovered image will expand to
var expandTo = 40;
//function for when an image is hovered over
function expandCompensate(whichImg) {
for (var i = 1; i <= numOfPics; i++) {
if (i != whichImg)
document.getElementById('img' + i).style.width = (100 - expandTo) / (numOfPics - 1) + '%';
}
}
//function for when the hovered image is left to reset the widths
function expandReset() {
for (var i = 1; i <= numOfPics; i++) {
document.getElementById('img' + i).style.width = 100 / numOfPics + '%';
}
}
(function bindEvents() {
for (var i = 1; i <= numOfPics; i++) {
document.getElementById('img' + i).onmouseover = (function(i) {
return function() {
document.getElementById('img' + i).style.width = expandTo + '%';
expandCompensate(i);
}
})(i);
document.getElementById('img' + i).onmouseout = function() {
expandReset();
};
}
})();
body,
p,
div {
margin: 0;
padding: 0;
}
body {} #findBottom {
position: absolute;
bottom: 0;
}
.imgPane {
float: left;
background-position: center;
transition: width 0.25s;
}
#img1 {
background-image: url('http://www.ericsartor.ca/imgwide/img//1.jpg');
}
#img2 {
background-image: url('http://www.ericsartor.ca/imgwide/img//2.jpg');
}
#img3 {
background-image: url('http://www.ericsartor.ca/imgwide/img//3.jpg');
}
#img4 {
background-image: url('http://www.ericsartor.ca/imgwide/img//4.jpg');
}
<div id="imgContain"></div>
<!-- ABSOLUTE ELEMENTS -->
<div id="findBottom"></div>
<!-- ABSOLUTE ELEMENTS -->
下面是我需要复制的函数示例:
document.getElementById('img1').onmouseover = function() {
document.getElementById('img1').style.width = expandTo + '%';
expandCompensate(1);
}
document.getElementById('img1').onmouseout = function() {
expandReset();
}
情况是我有一个 for
循环创建一些 div
元素,并且它们的数量是动态的。截至目前,我已经创建了 4 个 div 元素,因此我为 img1
、img2
、img3
和 img4
创建了上述函数的 4 次迭代.但是我想做的是根据我决定创建的 div
个元素(基于变量)动态创建 onmouseover
和 onmouseout
函数。
有什么办法吗?这是上下文的所有代码(不多),JS 中有注释,对所有内容进行了解释。我尝试自动化的部分在底部:
https://jsfiddle.net/4w0714su/3/
这是我正在努力实现的上下文的工作示例:
http://www.ericsartor.ca/imgwide
仅供参考:我选择的图像是随机的,我只需要高分辨率图像。这样做只是为了练习!感谢任何能帮我解决这个问题的人!
我不能很好地理解你的代码,但我会特别回答你的问题。
你可以通过循环实现你想要的:
for (var i = 0; i < 4; i++) {
document.getElementById('img' + i).onmouseover = function() {
this.style.width = expandTo + '%';
expandCompensate(Number(this.id.replace('img', '')));
};
document.getElementById('img' + i).onmouseout = function() {
expandReset();
}
}
注意:您不能在事件处理程序的函数中使用 i
变量,因为它将始终是 4
,因为它将完成循环,并且永远不会再次更改.
另一种方法是使用 IIFE (Immediately-invoked function expression),例如:
for (var i = 0; i < 4; i++) {
(function(n) {
document.getElementById('img' + n).onmouseover = function() {
this.style.width = expandTo + '%';
expandCompensate(n);
};
document.getElementById('img' + n).onmouseout = function() {
expandReset();
}
})(i);
}
这样做,您将当前的 i
值传递给一个函数,因此在该范围内,n
的值对于每次执行都是不同的,例如 0
、1
、2
和 3
.
An immediately-invoked function expression (or IIFE, pronounced "iffy") is a JavaScript design pattern which produces a lexical scope using JavaScript's function scoping.
This could be achieved by iterating all those
DOM
elements and binding events in aloop
.As we bind events in
loop
, and eventcallback
is being executed later when loop would be iterated completely, we need to maintaing the value of current iteration usingCLOSURE
.
试试这个片段:
var pageHeight = document.getElementById('findBottom').getBoundingClientRect().bottom,
numOfPics = 4; //the number of div elements to create
//creates the div elements within a container div in the HTML document
for (var i = 1; i <= numOfPics; i++) {
document.getElementById('imgContain').innerHTML += '<div id="img' + i + '" class="imgPane"></div>';
}
//used to resize all divs if the window changes size
window.onresize = function() {
pageHeight = document.getElementById('findBottom').getBoundingClientRect().bottom;
for (var i = 1; i <= imgClasses.length; i++) {
document.getElementById('img' + i).style.height = pageHeight + 'px';
}
for (var i = 1; i <= imgClasses.length; i++) {
document.getElementById('img' + i).style.width = 100 / imgClasses.length + '%';
}
};
//sets the height of each div to be the mximum height of the page (without scrolling)
for (var i = 1; i <= numOfPics; i++) {
document.getElementById('img' + i).style.height = pageHeight + 'px';
}
//makes all the divs equal percentage widths
for (var i = 1; i <= numOfPics; i++) {
document.getElementById('img' + i).style.width = 100 / numOfPics + '%';
}
//the percentage of the page the hovered image will expand to
var expandTo = 40;
//function for when an image is hovered over
function expandCompensate(whichImg) {
for (var i = 1; i <= numOfPics; i++) {
if (i != whichImg)
document.getElementById('img' + i).style.width = (100 - expandTo) / (numOfPics - 1) + '%';
}
}
//function for when the hovered image is left to reset the widths
function expandReset() {
for (var i = 1; i <= numOfPics; i++) {
document.getElementById('img' + i).style.width = 100 / numOfPics + '%';
}
}
(function bindEvents() {
for (var i = 1; i <= numOfPics; i++) {
document.getElementById('img' + i).onmouseover = (function(i) {
return function() {
document.getElementById('img' + i).style.width = expandTo + '%';
expandCompensate(i);
}
})(i);
document.getElementById('img' + i).onmouseout = function() {
expandReset();
};
}
})();
body,
p,
div {
margin: 0;
padding: 0;
}
body {} #findBottom {
position: absolute;
bottom: 0;
}
.imgPane {
float: left;
background-position: center;
transition: width 0.25s;
}
#img1 {
background-image: url('http://www.ericsartor.ca/imgwide/img//1.jpg');
}
#img2 {
background-image: url('http://www.ericsartor.ca/imgwide/img//2.jpg');
}
#img3 {
background-image: url('http://www.ericsartor.ca/imgwide/img//3.jpg');
}
#img4 {
background-image: url('http://www.ericsartor.ca/imgwide/img//4.jpg');
}
<div id="imgContain"></div>
<!-- ABSOLUTE ELEMENTS -->
<div id="findBottom"></div>
<!-- ABSOLUTE ELEMENTS -->