2015-10-03 2 views
1

Так вот пример функции мне нужно повторить:Создавать функции 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. Но я хотел бы сделать так, чтобы функции и onmouseout были созданы динамически в зависимости от количества элементов div, которые я решил создать (на основе переменной).

Есть ли способ сделать это? Вот весь код для контекста (это немного), есть комментарии в JS с объяснениями всего. Часть я пытаюсь автоматизировать на дне:

https://jsfiddle.net/4w0714su/3/

А вот рабочий пример для контекста того, что я пытаюсь достичь:

http://www.ericsartor.ca/imgwide

FYI: Изображение, которое я выбрал, было случайным, мне просто нужны изображения с высоким разрешением. Просто делайте это для практики! Спасибо всем, кто может помочь мне понять это!

+0

Что такое 'imgClasses', что у вас есть в вашем коде? – Buzinas

+0

О, простите, проигнорируйте это. Я использовал это для подсчета количества div, которые я написал в HTML, прежде чем я это сделал с помощью JS. Я использовал селектор длины для подсчета всех классов «imgPane». Извините, я подумал, что избавился от этого: P –

ответ

1

Я не могу понять ваш код очень хорошо, но я отвечу, в частности, то, что вы просите.

Вы можете добиться того, что вы хотите, делая петлю:

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.

немедленно вызываемая функция выражение (или IIFE, выраженный «ненадежный») представляет собой шаблон проектирования JavaScript, который производит лексическую область с помощью функции области видимости в JavaScript.

+0

Существуют ли какие-либо особые преимущества/недостатки для любого метода? –

+0

Итак, первый метод определенно работает (спасибо очень много!), Всего пару вопросов. Я не совсем понимаю, почему вы не можете использовать переменную 'i' внутри обработчика событий ... по моей логике, если это возможно использоваться для идентификации элемента, почему его нельзя использовать внутри функции? Кроме того, я использовал 'parseInt', чтобы делать то, что вы там сделали с помощью' Number() '. Является ли 'Number()' вообще лучшей идеей? –

+0

Обработчик событий выполняется асинхронно, вне логики цикла for и после завершения цикла. В этот момент у меня будет значение, которое было при завершении цикла - т. Е. 4. – caasjj

0

Это может быть достигнуто путем перебора всех тех 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 -->