Endlosschleife mit divs und jquery
Ich bin weiterhin ein vorherigen post, aber ich dachte, ich würde einen neuen thread aufmachen, da es einen anderen Ansatz und hat mehr den tatsächlichen code. Wie auch immer, ich versuche zu bekommen eine Endlosschleife gehen mit divs scrollen durch ein Fenster (den anderen post hat ein Bild, und der code unten funktioniert).
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Bleh...</title>
<style type="text/css" media="screen">
body {
padding: 0;
text-align: center;
}
#container {
width: 1000px;
padding: 10px;
border: 1px solid #bfbfbf;
margin: 0 auto;
position: relative;
}
#window {
width: 400px;
height: 100px;
padding: 10px;
border: 3px solid #666;
margin: 0 auto;
}
.box {
height: 100px;
width: 100px;
border: 1px solid #666666;
position: absolute;
z-index: -1;
}
.red { background-color: #ff6868;}
.green { background-color: 7cd980;}
.blue { background-color: #5793ea;}
.yellow { background-color: #f9f69e;}
.purple { background-color: #ffbffc;}
.cyan { background-color: #bff3ff;}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript" charset="utf-8">
$(window).load(function() {
arrangeBoxes();
setInterval('shiftLeft()', 3000);
});
//arrange the boxes to be aligned in a row
function arrangeBoxes() {
$('.box').each( function(i, item) {
var position = $('#window').position().left + 3 + i * ( $(item).width() + 10 );
$(item).css('left', position+'px')
});
}
//shifts all the boxes to the left, then checks if any left the window
function shiftLeft() {
$('.box').animate({'left' : "-=100px"}, 3000, 'linear');
checkEdge();
}
//returns the new location for the box that exited the window
function getNewPosition() {
return $('.box:last').position().left + $('.box:last').outerWidth() + 10;
}
//if the box is outside the window, move it to the end
function checkEdge() {
var windowsLeftEdge = $('#window').position().left;
$('.box').each( function(i, box) {
//right edge of the sliding box
var boxRightEdge = $(box).position().left + $(box).width();
//position of last box + width + 10px
var newPosition = getNewPosition();
if ( $(box).attr('class').indexOf('red') >=0 ) {
console.log('box edge: ' + boxRightEdge + ' window edge: ' + windowsLeftEdge + ' new pos: ' +newPosition);
}
if ( parseFloat(boxRightEdge) < parseFloat(windowsLeftEdge) ) {
$(box).css('left', newPosition);
$(box).remove().appendTo('#window');
first = $('.box:first').attr('class');
console.log('first is ' + first);
}
});
}
</script>
</head>
<body id="index">
<div id="container">
<div id="window">
<div class="box red"></div>
<div class="box green"></div>
<div class="box blue"></div>
<div class="box yellow"></div>
<div class="box purple"></div>
<div class="box cyan"></div>
</div>
</div>
</body>
</html>
Sowieso, das problem ist, dass ich die Boxen nach Links verschieben, aber ich kann nicht Holen Sie sich das führende Feld, um pop zurück auf das Ende der Zeile, wenn ich bei der ganzen Sache. Wenn ich jede Funktion separat (mit firebug) -
>> $('.box').animate({'left' : "-=100px"}, 3000, 'linear');
>> checkEdge()
Es funktioniert Super. Wenn ich Sie zusammen, ich bekomme nur die kontinuierliche Bewegung von rechts nach Links, bis die Boxen den Bildschirm zu verlassen, so muss es sein, wie Sie interagieren. Ich hoffe, das macht Sinn (wenn nicht, speichern Sie den obigen code-block als html-Datei und führen Sie es in einem browser). Ich Hänge schon länger auf diese für eine Weile, so dass jede Hilfe wird Super werden. Danke.
InformationsquelleAutor sa125 | 2009-11-18
Du musst angemeldet sein, um einen Kommentar abzugeben.
Müssen Sie legen Sie die callback-wie dies
checkEdge()
nichtcheckEdge
Überprüfen Sie hier für eine funktionierende Lösung http://jsbin.com/uceqi (nur Kopie eingefügten code)
Hier macht es wirklich einen Unterschied, wenn man die Klammern entfernt. Die version mit den geschweiften Klammern ausgeführt
checkEdge()
einmal pro animation (um ehrlich zu sein, in Wirklichkeit führt ercheckEdge
, BEVOR die animation beginnt. DiecheckEdge()
Funktion wird aufgerufen, wenn der$...animte(..)
- Anweisung erreicht, noch bevoranimate()
selbst führt.checkEdge
würde dazu führen, die Funktion übergeben werden, als parameter, in der Regel den richtigen Weg zu gehen).Die version ohne Klammern führt
checkEdge
einmal für die Anzahl der Elemente ist abgestimmt mit dem selector. In diesem Fall 6 mal.Also technisch gesehen ist dein Ansatz richtig wäre, wie es wäre, das Feuer der Rückruf einmal pro animierte element und NACH die animation.
Aber die Ausführung
checkEdge
sobald dies offensichtlich nicht, was der Autor beabsichtigt (check-Schleife über divs incheckEdge
). Und verursacht auch ernsthafte hinterher, als Sie die Schleife mehrmals über alle divs6divs animierte
->
6x callback ausgelöst->
callback-Schleifen über alle divs==>
36x Ausführung der anonymen Funktion incheckEdge()
!!Also das eigentliche problem ist, dass der callback gefeuert wird 6x und alle zur gleichen Zeit. Somit haben wir eine race-Bedingung und die animation versaut. Als mehrere
checkEdge()
Arbeit ruft gleichzeitig auf die Positionierung des divs.Aber Sie bemerken nur, weil die
animation-speed
und das Intervall, insetInterval
(shiftLeft) identisch sind. Würde Sie anders ((Intervall +~1000ms) > animation-Geschwindigkeit) dann wäre es korrekt zu. Aber natürlich ist die animation wäre nicht flüssig. AlsshitfLeft()
würde Feuer 1s, nachdem die animation beendet.Können Sie überprüfen, dieses Beispiel http://jsbin.com/iwapi3, die zeigt, was passiert, wenn Sie die version ohne Klammern. Warten und irgendwann wird der Zähler für
checkEdge()
Anrufe steigt von 7 alle 3s. Sie werden auch feststellen, dass in einigen Fällen die animation teilweise funktioniert und einige divs wieder verschoben werden, um an das Ende der Liste (manchmal).Nach einmal klicken Sie auf die Schaltfläche und beobachten Sie, wie die version mit Klammern sortiert das Chaos aus, nachdem ein paar ausgeführt wird (aber das jetzt die richtige Reihenfolge der Farbe ist natürlich auch Durcheinander). Und nur Anrufe
checkEdge()
einmal pro animation. (Kurz nach dem drücken der Schaltfläche erhalten Sie und andere +7, wie einige Rückrufe sind immer noch in der Leitung)es ist tatsächlich nicht in diesem Fall. Begründung in meiner Antwort. technisch Ihre Lösung richtig wäre und meine Lösung falsch. Antwort überprüfen für details
danke für deine Erklärung
InformationsquelleAutor jitter
Ausführung von JavaScript nicht warten, bis die 3000msec Ihrer animate-Funktion ausgegeben werden. Es beginnt mit der animate-Funktion, wird dann aber (nach 0-1 MS) bewegen sich auf Ihrem checkEdge () - Funktion. Sie prüfen nicht für den Zustand, in checkEdge (), die Sie wollen.
Um dies zu verhindern, sollten Sie Ihre checkEdge () - Funktion als callback zu der animate-Funktion, die ausgeführt wird, es genau nach diesen 3000ms.
Versuchen Sie dies:
InformationsquelleAutor Karsten