JQuery/Javascript Slider Problem

rtf

PC-Selbstbauer(in)
Hallo Leute,

Ich habe zurzeit ein Problem mit meinem Slider.
Die eigentliche Funktion, dass sliden beherrscht er, dass ist keine Problem. Jedoch wollte ich eine weitere Funktion einbauen, die mir das Überspringen von einigen Elementen erlaubt, so dass der User direkt auf seine gewünschte Info trifft. Leider versage ich hier gerade dauerhaft und werd schon ganz Matsche in Kopf :schief:. Ich habe 2 Funktionen für den Slider slider_out und slide_in. Zuerst wird slider_out gestartet um die erste Information auszublenden.
Danach wird im Callback die slide_in aufgerufen, die mir das nächste Element anzeigen soll. Ist das Einblenden beendet, ruf ich ebenfalls per Callback slider_out auf und übergebe ihm die zurzeit eingeblendete Seite. Das ganze Spiel fängt dann von vorne an.

Damit der User weiß wieviele Sliderelemente es gibt, ich nenn sie jetzt mal Folien, habe ich für jede "Folie" Kreise eingebaut. Dies passiert ind der set_slider_points() Funktion. Damit der User weiß, was zurzeit die aktuelle Folie ist, setze ich per Funktion slider_point einen weißen Punkt in den Kreis. Zusätzlich und jetzt kommt der Fehler, will ich, dass wenn man auf einen dieser Kreise klickt, die alte Funktion beendet wird und er direkt zu dieser angeklickten Folie springt. Danach soll er seine Zeit warten und den gewohnten gang wieder weitergeht. Eine Pause Funktion soll später auch eingebaut werden, aber das ist erstmal nicht so wichtig.

Ich sollte dazu sagen, dass dies mein erstes Größeres Projekt mit Javascript/Jquery ist und ich noch nicht sehr geübt darin bin.

und hier folgt mein kopfzereißender Code:schief:
Code:
/*
Mein erstes kleines JQuery 
*/

var timer = 3000; 
$(document).ready(function() {

    set_slider_points();
    $( "#sliderpoint span" ).eq(0).addClass("currendot");
    slider_out(timer,0);
       slider_click();   
    
});

function slider_click(){
    $("#sliderpoint span").click(function(){
        elementclicked = $(this).index();
    });
}

//Funktion sliderout nimmt sich das aktuelle Element jeweils von headline, infotext und pic1 und lässt es nach einem verzögerten Start auslaufen.
function slider_out(delayout,elslideout){
        sliderelement = elslideout;
        //geht erst 10 Punkte nach links um dann in der JQuery callback Funktion eine weitere Animation aufzurufen, die das Element noch 350 Punkte nach rechts verschiebt und dabei ausbleichen lässt. 
        $( "#slider > .headline" ).eq(sliderelement).delay(delayout).animate({
                left: "-=10",
                }, 500, function() {
                    $( "#slider > .headline" ).eq(sliderelement).animate({
                            opacity: 0,
                            left: "+=350",
                            }, 1000);
                    });


        $( "#slider > .infotext" ).eq(sliderelement).delay(delayout + 200).animate({
                left: "-=10",
                }, 500, function() {
                    $( "#slider > .infotext" ).eq(sliderelement).animate({
                            opacity: 0,
                            left: "+=350",
                            }, 1000);
                });



        $( "#slider > .pic1" ).eq(sliderelement).delay(delayout + 400).animate({
                left: "-=10",
                }, 500, function() {
                    $( "#slider > .pic1" ).eq(sliderelement).animate({
                            opacity: 0,
                            left: "+=350",
                            }, 1000, function() {
                                                        elslidein = elslideout + 1;
                                                        slide_in(0,elslidein);
                                                    });
        });
                   
};
        
//Function slidein nimmt sich das nächste Element und lässt es von der Linken seite einlaufen. 
function slide_in(delayin,elslidein){
        sliderelement = elslidein;
        // Überprüft ob das aktuelle Element das letzte ist. Falls ja wird es wieder auf 0 zurückgesetzt. 
        if(sliderelement > $(".headline").length - 1){sliderelement = 0;}
                            //Funktionsaufruf mit der Übergabe des aktuellen Elements
                            slider_point(sliderelement);
        $( "#slider > .headline" ).eq(sliderelement).css("left","2%").delay(delayin).animate({
                            opacity:"1",
                            left: "10%",
                }, 1000);
        
            $( "#slider > .infotext" ).eq(sliderelement).css("left","2%").delay(delayin).animate({
                            opacity:"1",
                            left: "5%",
                }, 1000);
                        
            $( "#slider > .pic1" ).eq(sliderelement).css("left","2%").delay(delayin).animate({
                            opacity:"1",
                            left: "50%",
                }, 1000,function(){
                                console.log("sliderin: " + sliderelement);
                            });                
                        
                        
};

//Set die Anzahl der Punkte im Slider. Dabei zählt es die Anzahl der headline Klasse.
function set_slider_points(){
    
     $(".headline").each(function(){
        $("<span></span").appendTo("#sliderpoint");
     });
     
}

//Setz den Punkt in der zurzeit aktiven Folie.
function slider_point(currsliderelement){
        $( "#sliderpoint span" ).removeClass("currendot");
        $( "#sliderpoint span" ).eq(currsliderelement).addClass("currendot");
}
ich hoffe mir kann einer helfen.
 
Zuletzt bearbeitet:
Yo,

ich würd dir erstmal raten, ein Minimalbeispiel bei jsfiddle.net zu erstellen und den Link zu posten.
Das macht es deutlich einfacher eine Vorstellung davon zu bekommen, was du haben willst.
 
wieso muss man da imer irgendwelches google-gelumbe zulassen? denk das is javascript? ich hasse sowas ><

aber zumindest weis ich jetzt, wie du dir das so vorstellst. aber mit js bin ich selber jetz auch ned so bewandert ^^ mal drüber lunzen, vllt hab ich ja doch ne idee. btw: wieso nennst du eine funktion slider_out und die andere slide_in? finde sowas immer verwirrend. also entweder beide slider oder beide slide *duck* hat für die funktionsweise natürliche keine auswirkung, aber ich find sowas halt irgendwie immer unschön ^^
 
wieso muss man da imer irgendwelches google-gelumbe zulassen? denk das is javascript? ich hasse sowas ><

aber zumindest weis ich jetzt, wie du dir das so vorstellst. aber mit js bin ich selber jetz auch ned so bewandert ^^ mal drüber lunzen, vllt hab ich ja doch ne idee. btw: wieso nennst du eine funktion slider_out und die andere slide_in? finde sowas immer verwirrend. also entweder beide slider oder beide slide *duck* hat für die funktionsweise natürliche keine auswirkung, aber ich find sowas halt irgendwie immer unschön ^^

Wäre nicht schlecht wenn dir was einfallen würde ^^. Naja zu den Funktionen. Ich mag es selber auch nicht und mir es halt später auch aufgefallen, das da noch ein r fehlt aber hab es bisher noch nicht geändert, weil ich mich aufs technische konzentrieren wollte. Funtionen kann man ja noch schnell mit suchen und ersetzen ändern :)
 
habs mir mal kurz angeschaut, aber werd aus dem code ned schlau ^^ also die grundlegende arbeit kann ich erahnen, aber wie das was genau funzt und zusammenpasst... allein sowas hier "$(document).ready(function() {..." sieht für mich seltsam aus. ne funktionsdeklaration als parameter? ^^ aber wie gesagt, hab mich bisher nur sehr sehr rudimentär mit js beschäftigt.

aber grundlegend kann ich ja bissl was faseln *denk*
wie funzt das atm? er beginnt mit der ersten seite, äh folie, und slidet zur nächsten. irgendwo wie müssen die ja angegeben sein, am besten noch nen index haben (oder in ner liste stehen oder so). macht ers atm so, dass er selber einfach den nächsten index ansteuert? weil ich würde die slide-methoden dann so ändern, dass man den "zielindex" mit übergeben muss. also aus pff slide(element) wird ein slide(element, nexElement) oder so. bei der ersten funktion stell ichs mir grob so vor, dass er in der funktion selber dann nextElement nach einem festen schema erstellt. ach ich "skizziere" es mal fix:
Code:
function slide(element) {
  nextElement = element + 1;
  slide_to(nextElement); // shortcut für die funktionalität des slidens an sich
}

function slide(element, nextElement) {
  slide_to(nextElement); // shortcut für die funktionalität des slidens an sich
}
bei der automatischen umswitcherei würde man dann halt slide(element, element + 1) übergeben, bei nem klick dann eben den index des geklickten elements -> slide(element, clickedElement). wie gesagt, ist nur algorythmisch und nicht mit explizitem code, aber vllt hilfts dir ja weiter ^^
 
Code:
$(document).ready(function(){});
Bedeutet das er warten soll bis das Dokument/die Seite fertig geladen ist. Er würde sonst vorher schon beginnen dies bringt leider nicht wenn es die Elemente noch nicht gibt. Ähnlich wie ein Frühstart ^^

Code:
function slider_out(delayout,elslideout){}
Das ist meine erste Funktion. delayout ist für den Timer, damit er das Layout nicht direkt wieder rausslidet. elslideout ist das element was er raussliden soll.


Code:
slider_out(timer,0);
Das ist mein erster Funktionsaufruf. Er übergibt die Zeit 3000 ms und den Index 0 für das 1 Layout.

Wenn er soweit mit dem raussliden der Elemente fertig ist soll er mit dem einsliden bzw der Funktion slide_in() beginnen. Damit er aber erst die Animation abwartet,
er würde sonst direkt alles durchführen und die Animation nicht beachten, gebe ich in der letzten Animation von dem pic1 in der Callbackfunktion an das er die Funktion slide_in() ausführen soll.

Das was dick geschrieben ist, ist die Callback Funktion
Code:
$( "#slider > .pic1" ).eq(sliderelement).delay(delayout + 400).animate({ 
                left: "-=10", 
                }, 500, function() { 
                    $( "#slider > .pic1" ).eq(sliderelement).animate({ 
                            opacity: 0,                            
                            left: "+=350",  }, 1000, [B]function() {
                                                         elslidein = elslideout + 1;
                                                         slide_in(0,elslidein);       [/B]                                              
});         
});
und hier nehme ich elslideout also 0, addiere es mit 1 und übergebe es elslidein.
Code:
elslidein = elslideout + 1; slide_in(0,elslidein);
Somit slidet er mit den nächsten Element weiter.

in slide_in() überprüft er auch ob er schon das letzte Element geslidet hat wenn ha spring er wieder zum ersten

Code:
 if(sliderelement > $(".headline").length - 1){sliderelement = 0;}
So ich hab mir schon genau das gleiche gedacht, einfach die Variaben ändern und Funktion wieder aufrufen, aber irgendwie scheitere ich daran. Ich hab auch schon mit globalen Variablen gearbeitet.
Das Ergebnis war meist immer das er ein Layout stehen gelassen hat und die anderen mehr oder weniger wild durcheinander geslidet hat...


Ich hoffe dir ist der Code jetzt ein bisschen geläufiger. Der Rest ist eigentlich eher uninteressant da sich dieser eher auf die Animation bzw. das Aussehen kümmert.:daumen:
 
Zuletzt bearbeitet:
und hier nehme ich elslideout also 0, addiere es mit 1 und übergebe es elslidein.
Code:
elslidein = elslideout + 1; slide_in(0,elslidein);
wäre das nich genau der ansatzpunkt? wenn man irgendwas klickt, dann müsste hier elslideout eben auf den index des geklickten gesetzt werden. ist halt die frage, wie er da reagiert. wenn man mitten in einer animation klickt, was passiert dann? man müsste eventuell NACH einer slide-animation nen "eventhandler" bauen. also irgendwas, das prüft, welches element angeklickt wurde. ist auch irgendwie die frage, KANN man überhaupt bei der animation was klicken? also thema multithreading. während der animation wird ja der code der slide-bla funktion ausgeführt in irgendeiner schleife? keinen plan ^^ wenn man dann klickt und bei onclick ne funktion save_clickedIndex(elIndex) oder so ausführen lassen will - ginge das überhaupt "nebenher"? ^^

hoffe, du weist, was ich meine ><

wenn man so den clickedIndex irgendwie sicher kann, dann könnte man aus deinem zitierten code vllt sowas hier machen:
Code:
clickedIndex = -1;
...
function saveClickedIndex(elIndex) {
  clickedIndex = elIndex;
}
...

// schauen, ob was angeklicked wurde
if(clickedIndex > -1) {
  elslidein = clickedIndex;
  clickedIndex = -1;
} else
  elslidein++;

// elIndex auf anfang setzen, wenn das letzte element überschritten wurde
if(elslidein > maxIndex)
  elslidein = 0;

// rumsliden ^^
slide_in(0, elslidein);
 
Hab dir jetzt mal eben schnell ein Eventhandler auf alle Punkte gesetzt. Er zeigt dir jetzt den Index in einem alert an.

Code:
function slider_click(){
    $("#sliderpoint span").click(function(){
        elementclicked = $(this).index();
        alert (elementclicked);
    });

clickedIndex wäre dann bei dir eine globale Variable oder?

Ich glaube ich verstehe was du meinst und werde es morgen mal gegenprüfen.

Da sind leider noch so viele Sachen wo ich drauf aupassen muss. Am besten wäre, die Funktion zu stoppen wenn was geklickt wurde, könnte sonst sein das er mein geklicktes Layout erst nach dem 2.ten mal anzeigt weil die Funktion vorher schon "aktiviert" worden ist.Eine Art sperre wenn der User wie ein bekloppter auf die Punkte klickt sollte auch sein, denn sonst slidet er wie wild ein und aus. Sind echt schon tolle Ergebnisse bei rausgekommen die ich versucht habe. :schief:
 
Tja es kann so einfach sein und manchmal macht man sich weit aus mehr verrückt als man überhaupt muss.

es klappt:daumen:

Code:
function slider_click(){
    $("#sliderpoint span").click(function(){
        clickindex = $(this).index();
    });

Hier ist meine klickfunktion, die in die globale Variable clickindex das angeklickte Element übergibt.


Code:
$( "#slider > .pic1" ).eq(sliderelement).delay(delayout + 400).animate({
                left: "-=10",
                }, 500, function() {
                    $( "#slider > .pic1" ).eq(sliderelement).animate({
                            opacity: 0,
                            left: "+=350",
                            }, 1000, function() {    
                                                    // Überprüft, ob ein anderes Element angeklickt worden ist. 
                                                    //Wenn ja setzt er den nächsten Slidepunkt auf das clickelement und setzt clickindex wieder auf seine 
                                                    //ausgangswert zurück. 
                                                    //wurde nichts gegklickt, geht er seinen alten Weg und erhöht den Wert um 1.
                                                        i[B]f (clickindex > -1){
                                                            elslidein = clickindex;
                                                            clickindex = -1;
                                                        }else{elslidein = elslideout + 1;}[/B]
                                                        
                                                        
                                                        slide_in(0,elslidein);
                                                    });
        });

Hier frage ich in der Callbackfunktion ob der clickindex höher ist. Wenn ja, setzt er elslidein mit diesem gleich und setzt clickindex zurück. Wenn nicht geht er seinen gewohnten weg und nimmt das nächst höhere Element.
Jetzt fehlt nur noch die Pause/weiter Funktion.

Danke soweit DarkMo:daumen:
 
Jetzt scheint alles zu funktionieren. Übersichtshalber poste ich hier, statt mein vorherigen zu editieren.
Pause Funktion ist jetzt auch eingerichtet.
Code:
/*
Mein erstes kleines JQuery 
*/

var timer = 3000; 
var clickindex = -1;
[B]var pause = false;[/B]
var currentelement = 0;

$(document).ready(function() {

    set_slider_points();
    $( "#sliderpoint span" ).eq(0).addClass("currendot");
   [B] setTimeout(function(){slider_out(0,0);},timer);[/B]
       slider_click();   
       
       [B]$("p.pause").click(function(){
       if(pause == true){pause = false;}else{
       pause = true;}
       
       if(currentelement > 4)
       {currentelement = 0;}
       setTimeout(function() {slider_out(0, currentelement);}, timer);
       });[/B]
    
});



function slider_click(){
    $("#sliderpoint span").click(function(){
        clickindex = $(this).index();
    });
}

//Funktion sliderout nimmt sich das aktuelle Element jeweils von headline, infotext und pic1 und lässt es nach einem verzögerten Start auslaufen.
function slider_out(delayout,elslideout){
   [B] if(pause == true){return false;}[/B]
        sliderelement = elslideout;
        //geht erst 10 Punkte nach links um dann in der JQuery callback Funktion eine weitere Animation aufzurufen, die das Element noch 350 Punkte nach rechts verschiebt und dabei ausbleichen lässt. 
        $( "#slider > .headline" ).eq(sliderelement).delay(delayout).animate({
                left: "-=10",
                }, 500, function() {
                    $( "#slider > .headline" ).eq(sliderelement).animate({
                            opacity: 0,
                            left: "+=350",
                            }, 1000);
                    });


        $( "#slider > .infotext" ).eq(sliderelement).delay(delayout + 200).animate({
                left: "-=10",
                }, 500, function() {
                    $( "#slider > .infotext" ).eq(sliderelement).animate({
                            opacity: 0,
                            left: "+=350",
                            }, 1000);
                });



        $( "#slider > .pic1" ).eq(sliderelement).delay(delayout + 400).animate({
                left: "-=10",
                }, 500, function() {
                    $( "#slider > .pic1" ).eq(sliderelement).animate({
                            opacity: 0,
                            left: "+=350",
                            }, 1000, function() {    
                                                    // Überprüft, ob ein anderes Element angeklickt worden ist. 
                                                    //Wenn ja setzt er den nächsten Slidepunkt auf das clickelement und setzt clickindex wieder auf seine 
                                                    //ausgangswert zurück. 
                                                    //wurde nichts gegklickt, geht er seinen alten Weg und erhöht den Wert um 1.
                                                        if (clickindex > -1){
                                                            elslidein = clickindex;
                                                            clickindex = -1;
                                                        }else{elslidein = elslideout + 1;}
                                                        
                                                        currentelement = elslidein;
                                                        slider_in(0,elslidein);
                                                    });
        });
                   
};
        
//Function slidein nimmt sich das nächste Element und lässt es von der Linken seite einlaufen. 
function slider_in(delayin,elslidein){
        sliderelement = elslidein;
        // Überprüft ob das aktuelle Element das letzte ist. Falls ja wird es wieder auf 0 zurückgesetzt. 
        if(sliderelement > $(".headline").length - 1){sliderelement = 0;}
                            //Funktionsaufruf mit der Übergabe des aktuellen Elements
                            slider_point(sliderelement);
        $( "#slider > .headline" ).eq(sliderelement).css("left","2%").delay(delayin).animate({
                            opacity:"1",
                            left: "10%",
                }, 1000);
        
            $( "#slider > .infotext" ).eq(sliderelement).css("left","2%").delay(delayin).animate({
                            opacity:"1",
                            left: "5%",
                }, 1000);
                        
            $( "#slider > .pic1" ).eq(sliderelement).css("left","2%").delay(delayin).animate({
                            opacity:"1",
                            left: "50%",
                }, 1000,function(){
                                console.log("sliderin: " + sliderelement);
                               [B] setTimeout(function(){slider_out(0,sliderelement);}, timer);[/B]
                            });                                 
                        
};

//Set die Anzahl der Punkte im Slider. Dabei zählt es die Anzahl der headline Klasse.
function set_slider_points(){
    var i = 0;
     $(".headline").each(function(){
     
        var titel = $(".headline").eq(i).html();
        var addvalues = "<span title=" + titel + "></span>";
        $(addvalues).appendTo("#sliderpoint");
        i++;
     });
     
}

//Setz den Punkt in der zurzeit aktiven Folie.
function slider_point(currsliderelement){
        $( "#sliderpoint span" ).removeClass("currendot");
        $( "#sliderpoint span" ).eq(currsliderelement).addClass("currendot");
}
Den Funktionsaufruf mach ich jetzt mit einem setTimeout. Diese sorgt jetzt dafür, dass bei der Pause Funktion auch das aktuelle Element pausiert wird und nicht erst das darauffolgende. Das Problem hierbei war, dass er immer schon in der Funktion bzw. dem JQuery Objekt drin war, jedoch wegen des delays nicht ausgeführt hatte und einfach wartete. Habe ich auf pause geklickt, wurde erst bei der nächsten Folie pausiert.

Die Pausefunktion setzt die var pause, die dafür verwendet wird, das die Funktion slider_out mit einem return direkt beendet wird. Aus der Klickfunktion wird ebenfalls wieder die Funktion slider_out aufgerufen.

nochmal recht herzlichen dank an dir DarkMo für den kleinen aber wichtigen Denkanstoß.:daumen:

Jetzt gehts ans Design und den Fallbacks
 
Zurück