2016-12-23 1 views
0

Was ich will, ist auf #bt-1 und ändern Sie die Farbe von #target-1, klicken Sie auf #bt-2 und ändern Sie die Farbe von #target-2 klicken ... Ich begann für jeden #bt-n einen bestimmten Click-Ereignishandler schreiben/#target-n Aber als die Seite größer wurde, dachte ich über eine Schleife nach. Mein Ansatz verwendete eine for-Schleife mit Variablen in jQuery-Selektoren. Hier ist mein Code:Ereignisbehandlungsroutine für Schleife mit dynamischen jQuery Selektoren

$(document).ready(function() { 
 
    
 
    var total = $('.target').length; 
 
    for(n=1; n<=total; n++) { 
 
    var num = String(n); 
 
    $('#bt-'+num).on('click', function() { 
 
     $('#target-'+num).toggleClass('yellow'); 
 
    }); 
 
    } 
 
    
 
});
.wrapper { 
 
    display: flex; 
 
    text-align: center; 
 
} 
 
.button, .target { 
 
    padding: 20px; 
 
    margin: 10px; 
 
} 
 
.button { 
 
    background: gray; 
 
} 
 
#target-1 { 
 
    background: red; 
 
} 
 
#target-2 { 
 
    background: green; 
 
} 
 
#target-3 { 
 
    background: blue; 
 
} 
 
.yellow { 
 
    background: yellow !important; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div class="wrapper"> 
 
    <div id="bt-1" class="button"> 
 
    <h1>Button 1</h1> 
 
    </div> 
 
    <div id="target-1" class="target"> 
 
    <h1>Target 1</h1> 
 
    </div> 
 
</div> 
 
<div class="wrapper"> 
 
    <div id="bt-2" class="button"> 
 
    <h1>Button 2</h1> 
 
    </div> 
 
    <div id="target-2" class="target"> 
 
    <h1>Target 2</h1> 
 
    </div> 
 
</div> 
 
<div class="wrapper"> 
 
    <div id="bt-3" class="button"> 
 
    <h1>Button 3</h1> 
 
    </div> 
 
    <div id="target-3" class="target"> 
 
    <h1>Target 3</h1> 
 
    </div> 
 
</div>

Ich verstehe nicht, warum es richtet sich nur die letzte #target-n als die Schleife auf #bt-n scheint zu funktionieren. Ich habe auch darüber nachgedacht, ein Array zu verwenden, kann aber nicht herausfinden, wie man es implementiert.

Ich konnte es $(this).siblings('.target')... mit funktioniert das for-Schleife nicht und ids das erfordert aber ein übergeordnetes Element für jeden .button/.target, in diesem Fall .wrapperCode Here. Obwohl dies eine gute Lösung war, würde ich gerne verstehen, was ich falsch gemacht habe und wie man eine Schleife richtig implementiert, ohne die Eltern .wrapper zu verwenden. Vielen Dank.

+0

anstelle von ''bt -' + num' ich denke, Sie können '' bt - '+ n' –

+0

Mögliche Duplikate von [Zuweisen von Click-Handlern in for-Schleife] (http://stackoverflow.com/questions/4091765/assign-click-handlers-in-for-loop) –

+1

benutze '$ (this) .next(). toggleClass ('yellow')' –

Antwort

2

Der Grund dafür, dass nur der letzte Eintrag betroffen ist, liegt daran, dass die Schleife abgeschlossen wurde, bevor ein Ereignis ausgelöst wird. Daher enthält n den letzten Wert in der Schleife. Um dies zu beheben müssen Sie einen Verschluss verwenden:

for (n = 1; n <= total; n++) { 
    (function(n) { 
    $('#bt-' + n).on('click', function() { 
     $('#target-' + n).toggleClass('yellow'); 
    }); 
    })(n); 
} 

Das heißt, ein viel besserer Ansatz wäre, die Schleife zu vermeiden und DOM-Traversal zu verwenden, um die .target zu finden im Zusammenhang mit dem angeklickt .button, wie folgt aus:

$('.button').click(function() { 
 
    $(this).next('.target').toggleClass('yellow'); 
 
});
.wrapper { 
 
    display: flex; 
 
    text-align: center; 
 
} 
 
.button, 
 
.target { 
 
    padding: 20px; 
 
    margin: 10px; 
 
} 
 
.button { 
 
    background: gray; 
 
} 
 
#target-1 { 
 
    background: red; 
 
} 
 
#target-2 { 
 
    background: green; 
 
} 
 
#target-3 { 
 
    background: blue; 
 
} 
 
.yellow { 
 
    background: yellow !important; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div class="wrapper"> 
 
    <div id="bt-1" class="button"> 
 
    <h1>Button 1</h1> 
 
    </div> 
 
    <div id="target-1" class="target"> 
 
    <h1>Target 1</h1> 
 
    </div> 
 
</div> 
 
<div class="wrapper"> 
 
    <div id="bt-2" class="button"> 
 
    <h1>Button 2</h1> 
 
    </div> 
 
    <div id="target-2" class="target"> 
 
    <h1>Target 2</h1> 
 
    </div> 
 
</div> 
 
<div class="wrapper"> 
 
    <div id="bt-3" class="button"> 
 
    <h1>Button 3</h1> 
 
    </div> 
 
    <div id="target-3" class="target"> 
 
    <h1>Target 3</h1> 
 
    </div> 
 
</div>

+0

Ich dachte, dass "num" nur den letzten Wert enthält, aber es ist seltsam, weil das Klick-Ereignis ausgelöst wird, wenn ich '# bt-1',' # bt-2' oder '# bt-3' drücke. Irgendwie wird nicht nur der letzte Valye an dieser Zeile übergeben, was in der nächsten Zeile für das "# target" + num' passiert. – guizo

+0

Mit 'next()' ist sicher eine bessere Lösung, die 'Geschwister()' wie ich tat. Vielen Dank. – guizo

+1

@guizo Das Ereignis wird an die richtigen Elemente angehängt, weil 'num' den richtigen Wert beim Finden dieser Elemente enthält. Der Event-Handler selbst, der den Elementen zugeordnet ist, wird erst später verwendet, nachdem die Schleife ausgeführt wurde. Daher hat "num" immer den endgültigen Wert. –

0

Es ist unklug, eine Menge von Event-Handler zu registrieren. Sie können einen Ereignishandler binden und für den konkreten Fall idx Lesen von Element-ID Aktion durchführen, zum Beispiel:

$('body').on('click', function (event) { 
    if (!event.target.id.match(/^bt-\d+/)) { 
     return; //id of clicked element does not match bt-{number} 
    } 

    var idx = event.target.id.replace('bt-', ''); //remove prefix "bt-" and leave only numeric postfix 

    $('#target-' + idx).toggleClass('yellow'); 
}); 

Erläuterung:

Wenn Sie click auf body Element binden Sie erhalten Zugang zu allen click Ereignisse von Kind Elemente, die nicht abgebrochen wurden und dieses Ereignis weiterreichen. Element, auf das geklickt wurde, wurde in event.target gespeichert und hat die Eigenschaft id in event.target.id.

Auf dieser Eigenschaft id I Match-Funktion mit regulären Ausdruck nennen - es wird Zeichenfolge übereinstimmen, die \d eine beliebige Anzahl von ^bt- und haben beginnt mindestens eine eine +.

if (!event.target.id.match(/^bt-\d+/)) { 
    return; //id of clicked element does not match bt-{number} 
} 

Es ist Negation dieser Aussage, so Wird diese id Format nicht in ist bt-someNumber wird es nicht weiter gehen.

var idx = event.target.id.replace('bt-', ''); 

als nimmt id und ersetzt bt- Teil darin mit leeren String ''

$('#target-' + idx).toggleClass('yellow'); 

Schließlich Du Makeln Klasse auf das Element mit der gleichen Anzahl wie Taste, aber mit unterschiedlichen Präfix target- statt bt-.

Happy hacken!

+0

Es funktioniert, aber ich habe nicht verstanden, was in der if-Anweisung passiert. – guizo

+0

Ich habe Erklärung dieses Prozesses in der Post hinzugefügt;) – Hakier