Создать функции onmouseover/onmouseout динамически с JavaScript?
Итак, вот пример функции, которую мне нужно скопировать:
document.getElementById('img1').onmouseover = function() {
document.getElementById('img1').style.width = expandTo + '%';
expandCompensate(1);
}
document.getElementById('img1').onmouseout = function() {
expandReset();
}
Ситуация такова, что у меня есть for
цикл создания некоторых div
элементы, и их количество является динамическим. На данный момент у меня есть 4 элемента div, поэтому я создал 4 итерации вышеупомянутых функций для img1
, img2
, img3
а также img4
, Но то, что я хотел бы сделать, это иметь onmouseover
а также onmouseout
функции создаются динамически в зависимости от того, сколько div
элементы, которые я решил создать (на основе переменной).
Есть какой-либо способ сделать это? Вот весь код для контекста (это немного), в JS есть комментарии с объяснениями для всего. Часть, которую я пытаюсь автоматизировать, находится внизу:
https://jsfiddle.net/4w0714su/3/
И вот рабочий пример для контекста того, чего я пытаюсь достичь:
http://www.ericsartor.ca/imgwide
К вашему сведению: изображение, которое я выбрал, было случайным, мне просто нужны были изображения в высоком разрешении. Просто делаю это для практики! Спасибо всем, кто может помочь мне понять это!
2 ответа
Я не очень хорошо понимаю ваш код, но я отвечу, в частности, на то, что вы спрашиваете.
Вы можете достичь того, что вы хотите, выполнив цикл:
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 (выражение функции, вызываемое сразу), например:
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
,
Выражение функции, вызываемое немедленно (или IIFE, произносится как "iffy") - это шаблон проектирования JavaScript, который создает лексическую область видимости, используя определение функций JavaScript.
Это может быть достигнуто путем итерации всех тех
DOM
элементы и обязательные события вloop
,Как мы связываем события в
loop
и событиеcallback
выполняется позже, когда цикл будет повторен полностью, нам нужно сохранить значение текущей итерации, используя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 -->