[jQuery] kurzes "Flackern" bei Überblendeffekt

JuSchu85

Mitglied
Ich arbeite mich gerade in jQuery ein und programmiere als Übung (und weil ich es selber brauche) ein Plugin für eine Slideshow.
Dabei habe ich 3 img-Elemente in einem div, die sich dank absoluter Positionierung überlagern.
Es gibt jeweils ein img-Element für das aktuelle, das nächste und das vorherige Bild. Die letzten beiden sind standardmäßig ausgeblendet und liegen im Vordergrund.

Wenn man jetz zum nächsten/vorherigen Bild schaltet, wird das img-Element des nächsten/vorherigen Bildes über fadeIn() eingeblendet, es werden die Adressen der Bilder aktualisiert und es wird das img-Element des nächsten/vorherigen Bildes wieder ausgeblendet.
Dabei passiert eigentlich alles in der Callback-Funktion die für fadeIn() registriert wurde.
Ich habe dabei auch darauf geachtet, dass die Reihenfolge beim Ein-/Ausblenden und dem Austauschen der Adressen so ist, dass "eigentlich" niemals das flasche Bild zu sehen ist.
"Eigentlich" weil direkt nach der Überblendung manchmal das gerade ausgeblendete Bild kurz vor das neue Bild aufflackert.
Ich habe auch schon versucht das Problem zu lösen, indem ich das gerade eingeblendete Bild über den z-index vor die anderen setze, aber das hat auch nicht geholfen.

Ich füge hier mal den Code ein. Vielleicht sieht jemand anderes den Fehler oder das Problem.
Das wichtige findet eigentlich nur in der Funktion "next" ganz oben in "slideshow.js" statt.

Die img-Elemente haben folgende IDs:
slideshow_pic_prev
slideshow_pic_now
slideshow_pic_next

Die Bilder liegen als Image-Objekte in einem Array namens "slideshow_pics", das ich über data() an den umschieleßenden div-Tag geknüpft habe.

Ich hab vor kurzem auch JS-Bin entdeckt und hab es da mal eingefügt: http://jsbin.com/egozit/6/edit
Ich hoffe mal ich hab die Speicher-Funktion der Seite richtig verstanden. Dann könnt ihr euch das da was bequemer angucken und direkt rumprobieren.
Und der Zurück-Button funktioniert übrigens noch nicht. Da kümmer ich mich drum, wenn es nicht mehr flackert.

index.html
HTML:
<!DOCTYPE HTML> <!--TODO Version anpassen--> 
<html>
	<head>
		<!--TODO meta--> 
		<!--<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>-->
		<script type="text/javascript" src="scripts/jquery-1.7.1.min.js"></script>
		<script type="text/javascript" src="scripts/slideshow.js"></script> 
		<script type="text/javascript">
			$("#sls").ready(function(){
				$("#sls").slideshow([
					"/more/img/Bild1.jpg",
					"/more/img/Bild2.jpg",
					"/more/img/Bild3.jpg",
					"/more/img/Bild4.jpg",
					"/more/img/Bild5.jpg"
				],{
					"bgr" : true,
				});
				
				$("#prev").click(function(){$("#sls").slideshow("prev")});
				$("#next").click(function(){$("#sls").slideshow("next")});
				$("#get").click(function(){$("#sls").slideshow("get")});
			});
		</script>
		<style type="text/css">
			body{
				padding: 0px;
				margin: 0px;
				overflow: hidden;
			}
			
			.nav_button{
				color: #FFF;
				background-color: #000;
				border: 2px solid #FFF;
				padding: 3px 6px;
			}
		</style>
	</head>
	<body>
		<div id="sls">
			<div style="position:absolute; bottom:8px; right:8px">
				<span class="nav_button" id="prev">&lt;-</span>
				<span class="nav_button" id="next">-&gt;</span>
				<span class="nav_button" id="get">get</span>
			</div>
		</div>
	</body>
</html>

slideshow.js
Code:
(function($){
	$.fn.slideshow = function(){
		///////////////////////
		// control-functions //
		///////////////////////
		var next = function(obj){
			//TODO Flackerproblem loesen
			$("#slideshow_pic_next").stop(true, true);
			$("#slideshow_pic_prev").stop(true, true);
			
			var slideshow_pics = obj.data("slideshow_pics");
			
			//"next" einblenden
			$("#slideshow_pic_next").fadeIn(obj.data("fade_time"), function(){
				
				//lade "next" nach "now"
				$("#slideshow_pic_now").attr("src", $("#slideshow_pic_next").attr("src"));
				
				//"now" in vordergrund setzen
				$("#slideshow_pic_now").css("z-index", "1");
			
				//lade "now" nach "prev"
				$("#slideshow_pic_prev").attr("src", $("#slideshow_pic_now").attr("src"));
				
				//"next" verstecken
				$("#slideshow_pic_next").hide();
				
				//steht "pos" auf maximum
				if (obj.data("pos") < slideshow_pics.length-1){
					obj.data("pos", obj.data("pos")+1);
				}
				else{
					obj.data("pos", 0);
				}
				
				//wird in "next" das nächste oder erste bild geladen
				if (obj.data("pos") < slideshow_pics.length-1){
					$("#slideshow_pic_next").attr("src", slideshow_pics[obj.data("pos")+1].src);
				}
				else{
					$("#slideshow_pic_next").attr("src", slideshow_pics[0].src);
				}
				
				//"now" z-index auf standard setzen
				$("#slideshow_pic_now").css("z-index", "0");
			});
		};
		
		var bgr_on = function(obj){
			var minZ = 0;
			$("#" + obj.attr("id") + " ~ *").each(function(){
				if (minZ > $(this).css("z-index")){
					minZ = $(this).css("z-index");
				}
				if (minZ > parseInt($(this).attr("z-index"))){
					minZ = parseInt($(this).attr("z-index"));
				}
			});
			minZ--;
			
			//TODO leere Eigenschaften ausnehmen 
			obj.data("z-index", obj.css("z-index"));
			obj.css("z-index", minZ);
			
			obj.data("position", obj.css("position"));
			obj.css("position", "absolute");
			
			obj.data("height", obj.css("height"));
			obj.css("height", "100%");
			
			obj.data("width", obj.css("width"));
			obj.css("width", "100%");
		};
		
		var bgr_off = function(obj){
			obj.css("z-index", obj.data("z-index"));
			obj.css("position", obj.data("position"));
			obj.css("height", obj.data("height"));
			obj.css("width", obj.data("width"));
		};
		
		/////////////////////
		// string-commands //
		/////////////////////
		if (typeof arguments[0] == "string"){
			switch (arguments[0]){
				case "next":
					next($(this));
					break;
				case "prev":
					//TODO implementieren
					break;
				case "play":
					//TODO implementieren
					break;
				case "pause":
					//TODO implementieren
					break;
				case "get":
					var al = "Gebe URLs aus:";
					for (var i = 0; i < $(this).data("slideshow_pics").length; i++){
						al += "\n" + $(this).data("slideshow_pics")[i].src
						+ ": " + $(this).data("slideshow_pics")[i].width
						+ " x " + $(this).data("slideshow_pics")[i].height;
					}
					alert(al);
					break;
			}
		}
		
		//////////////
		// add pics //
		//////////////
		else if (typeof arguments[0][0] == "string"){
			if ($(this).data("slideshow_pics")){
				var slideshow_pics = $(this).data("slideshow_pics");
				if ($(this).data("id") == 0){
					$("#slideshow_pic_prev").attr("src", arguments[0][arguments[0].length-1]);
				}
			}
			else{
				var slideshow_pics = new Array();
				$(this).css("overflow", "hidden");
				
				//add <img>-tags
				$(this).prepend("<img id='slideshow_pic_now' style='position:absolute; z-index:0' src='" + arguments[0][0] + "'>" +
								"<img id='slideshow_pic_next' style='position:absolute; z-index:0' src='" + arguments[0][1] + "'>" +
								"<img id='slideshow_pic_prev' style='position:absolute; z-index:0' src='" + arguments[0][arguments[0].length-1] + "'>");
				$("#slideshow_pic_prev").hide();
				$("#slideshow_pic_next").hide();
				
				//initialize default-options
				$(this).data("pos", 0);
				$(this).data("bgr", true);
				$(this).data("autoplay", true);
				$(this).data("show_controls", true);
				$(this).data("time", 10000);
				$(this).data("fade_time", 1500);
				$(this).data("reverse", false);
			}
			
			for (var i = 0; i < arguments[0].length; i++){
				slideshow_pics.push(new Image());
				slideshow_pics[slideshow_pics.length-1].src = arguments[0][i];
			}
			$(this).data("slideshow_pics", slideshow_pics);
		}
		
		/////////////
		// options //
		/////////////
		if (typeof arguments[0] == "object" && typeof arguments[0][0] != "string" || typeof arguments[1] == "object"){
			//determine option-parameter
			if (typeof arguments[1] == "object"){
				var options = arguments[1];
			}
			else{
				var options = arguments[0];
			}
			
			//set options
			if (options["bgr"] != undefined){
				switch (options["bgr"]){
					case true:
						bgr_on($(this));
						$(this).data("bgr", true);
						break;
					case false:
						bgr_off($(this));
						$(this).data("bgr", false);
				}
			}
			
			if (options["autoplay"] != undefined){
				if(typeof options["autoplay"] == "boolean"){
					$(this).data("autoplay", options["autoplay"]);
				}
			}
			
			if (options["show_controls"] != undefined){
				switch (options["show_controls"]){
					case true:
						$(this).data("show_controls", true);
						break;
					case false:
						$(this).data("show_controls", false);
				}
			}
			
			if (options["time"] != undefined){
				if(typeof options["time"] == "number"){
					$(this).data("time", options["time"]);
				}
			}
			
			if (options["fade_time"] != undefined){
				if(typeof options["fade_time"] == "number"){
					$(this).data("fade_time", options["fade_time"]);
				}
			}
			
			if (options["reverse"] != undefined){
				if(typeof options["reverse"] == "boolean"){
					$(this).data("reverse", options["reverse"]);
				}
			}
		}
		
		return $(this);
	};
})(jQuery);
 

Neue Beiträge

Zurück