2010-12-08 14 views
0

J'ai une boucle de 50 divs, dans laquelle j'affecte l'événement en fonction de l'élément en cours. Cependant, je veux attribuer un événement en fonction d'une condition. Par exemple, les Divs sont disposées les unes derrière les autres, tout comme une pile photo. Je veux que l'utilisateur frappe d'abord le premier div, alors seulement ils devraient pouvoir frapper le deuxième div puis le troisième div et ainsi de suite jusqu'à ce qu'ils atteignent la fin des divs.sous boucle, comment affecter un événement en fonction de la condition en fonction de la valeur d'index

En raison du code ci-dessous, l'utilisateur peut frapper n'importe quel div et effectuer une action. Mais l'action doit être effectuée un par un. Un div après l'autre. S'il vous plaît suggérer la solution.

var flag=0; 
var flipImage=document.querySelectorAll('.shadow'); 
    for(j=0; j<flipImage.length; j++){ 
    var currentFlipImage=flipImage[j]; 
     if(j==flag){ 
     flag++; 
     currentFlipImage.addEventListener('click',flipDown,false); 
    } 
    } 

Répondre

0

Peut-être quelque chose comme:

var _handler = null; 
var images = document.querySelectorAll('.shadow'); 
var length = images.length; 

function attachHandler(index) { 
    if(_handler) { 
     // remove the click handler from the previous image 
     images[index-1].removeEventListener('click', _handler, false); 
     _handler = null; 
    } 
    if(index < length) { 
     var handler = function(event) { 
      flipDown(event); 
      attachHandler(index+1); // add the click handler to next image 
     } 
     images[index].addEventListener('click', handler, false); 
     _handler = handler; // capture reference for removal 
    } 
} 

attachHandler(0); 

Cela ne génère et ajoute des écouteurs d'événement en cas de besoin.

Note importante: La valeur de retour de querySelectorAll() est NodeList qui est en direct. Cela signifie que chaque fois que vous appelez length sur cet objet, la liste est réévaluée (les éléments sont à nouveau recherchés) ce qui ajoute une surcharge de performance. Par conséquent, n'utilisez jamais list.length dans la boucle for. Capturez le length à l'avance.

Working DEMO

Si vous voulez faire passer dans une boucle, il suffit de retirer la déclaration if (garder le corps bien sûr) et faire

index = index % length; 
+0

Cette solution a l'air parfaite. Cependant, sur chaque div actuel, je dois joindre une classe appelée flip down, qui permet à la div de flipdown. Quand j'essaye je deviens l'animation très étrange. ci-dessous le code que j'ai dans la fonction de bascule. var obj = event.target; obj.className = 'flipDown'; Je pense que la classe est affectée à mousevent, au lieu de div réel. Quelle est la solution pour cela? – user504023

+0

@ user504023: Pourriez-vous créer un jsFiddle avec votre code? Il est difficile d'aider avec cette information seulement, mais il semble que vous attachez la classe correctement. –

+0

Merci beaucoup. En fait, j'ai une solution pour gérer cela. J'utilise event.currentTarget, au lieu de event.target. Cela fonctionne bien maintenant. Votre code ci-dessus m'aide vraiment beaucoup. Merci encore. – user504023

0

Essayez de donner à chaque div un ID séquentiel puis en ajoutant l'événement click à l'autre dans l'ordre

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
<head> 
<title>Test</title> 
<script type="text/javascript"> 
function div_click(event) 
{ 
    var div_clicked = event.currentTarget, 
     next_sequence = parseInt(div_clicked.id.split("_")[1]) + 1, 
     next_div = document.getElementById("mydiv_" + next_sequence); 
    //alerts are just for testing here 
    alert(div_clicked.id); 
    alert(next_div.id); 

    div_clicked.removeEventListener('click',div_click,false); 
    next_div.addEventListener('click',div_click,false); 
} 

window.onload = function() 
{ 
    var first_div = document.getElementById("mydiv_0"); 
    first_div.addEventListener('click',div_click,false); 
}; 
</script> 
</head> 
<body> 
<div id="mydiv_0">Click 0</div> 
<div id="mydiv_1">Click 1</div> 
<div id="mydiv_2">Click 2</div> 
<div id="mydiv_3">Click 3</div> 
<div id="mydiv_4">Click 4</div> 
<div id="mydiv_5">Click 5</div> 
</body> 
</html> 

vaut le coup?

0

Essayez ceci:

var flipImage = document.querySelectorAll('.shadow'), current = 0; 
function flipDown(){ 
    current++; 
    current = (current > flipImage.length)? 0 : current; 
    for(j = 0; j < flipImage.length; j++){ 
     flipImage[j].style.zIndex = (j == current)? 2 : 1; 
    } 
} 
window.onload = function(){ 
    for(j = 0; j < flipImage.length; j++){ 
    flipImage[j].onmouseclick=flipDown; 
    } 
} 
+0

Je ne pense pas que ce soit ce que veut l'OP. Oui, les effets seront exécutés dans l'ordre des divs, mais peu importe sur quel div un clique. –

+0

Vous avez raison, mais cela * devrait * fonctionner si les divs sont placés les uns sur les autres. Je suis tout à fait d'accord que votre réponse correspond mieux à la question de l'OP – JCOC611

+0

Ah, désolé JCOC611, j'ai oublié la position. Vous avez raison, alors ce n'est pas grave;) Nevermind! –

0

Lorsque vous avez un nombre arbitraire d'éléments partage le même gestionnaire d'événements, la gestion de tous les événements d'un parent commun est généralement préférable à l'affectation de gestionnaires à chaque élément.

Ceci ne fonctionne pas pour les événements 'focus' ou non-bouillonnants, mais il est utile pour les événements tactiles, de souris et de clavier.

Il est généralement plus facile de coordonner des actions basées sur les conditions d'un gestionnaire de 'standard' constant que d'éléments arbitraires.