2016-12-17 3 views
1

Also habe ich dieses Javascript erstellt, das einen bestimmten Ort mit seiner ID animiert. Das Problem ist, dass es viele von denen auf der Website gibt und dies bedeutet, dass ich diese Funktion viele Male duplizieren müsste, nur um das x in getElementById ("x") zu ersetzen.Erstellen eines klassenbasierten JS anstelle der ID

So, hier ist der Code, den ich von mir voll gemacht:

var popcount = 0; 
var opanumber = 1; 
var poptimeout; 
function pop() { 
    if (popcount < 10) { 
     popcount++; 
     if (opanumber == 1) { 
     document.getElementById("nav1").style.opacity = 0; 
     opanumber = 0; 
     poptimeout = setTimeout("pop()", 50); 
     } 
     else { 
     document.getElementById("nav1").style.opacity = 1; 
     opanumber = 1; 
     poptimeout = setTimeout("pop()", 50); 
     } 
    } 
    else { 
    popcount = 0; 
    document.getElementById("nav1").style.opacity = 1; 
    } 
} 

function stoppop() { 
    clearTimeout(poptimeout); 
    popcount = 0; 
    document.getElementById("nav1").style.opacity = 1; 
} 

Ich würde gerne alle Informationen zu schätzen weiß, wie ich diese Situation lösen könnte und auch keine Anleitungen Klassen und „this“.

+0

gut für einen, erkannte man bereits das Problem, die Tatsache, dass Sie "nav1" Parameter fest codierten. Nun gehe ich davon aus, dass Sie auch wissen, wie Sie Ihren Funktionen Parameter hinzufügen können, die Sie dann in Ihren Funktionen wiederverwenden können. Eine andere Sache, über die Sie nachdenken sollten, setTimeout mit einem String-Ansatz ist eine sehr veraltete Vorgehensweise, definieren Sie einfach eine anonyme Funktion und rufen Sie Ihre Pop-Funktion aus dieser anonymen Funktion heraus. Ein weiterer kleiner Punkt, wie dies Code funktioniert, [codereview] (http://codereview.stackexchange.com) könnte ein besserer Ort für Ihre Frage sein – Icepickle

+0

Hinzufügen eines Parameters zu meiner Funktion würde es funktionieren (ich habe es versucht), aber Ich kann anscheinend nicht in der Lage sein, ElementById des Parameters zu erhalten. Versucht '"' + p1 + '"'. Wie für die setTimeout könnte funktionieren, aber ich würde die Funktions-ID für onmouseover, nein? – MrMeDo

Antwort

2

So etwas wie das; Anstatt einen Wert in eine Funktion zu schreiben, ist es besser, den Wert zu übergeben, damit Sie die Funktion für mehr als eine Sache wiederverwenden können. In diesem Fall können Sie nun startPop und stopPop mit dem Namen einer CSS-Klasse aufrufen.

var popTimeout; 

function setOpacity(className, value) { 
    Array.prototype.forEach.call(
     document.getElementsByClassName(className), 
     function(el) { 
      el.style.opacity = value; 
     } 
    ); 
} 

function pop(className, popCount, opaNumber) { 
    if (popCount < 10) { //Must be even number so you end on opacity = 1 
     setOpacity(className, opaNumber); 
     popTimeout = setTimeout(function() { 
      pop(className, popCount++, 1-opaNumber); 
     }, 50); 
    } 
} 

function startPop(className) { 
    pop(className, 0, 0); 
} 

function stopPop(className) { 
    clearTimeout(popTimeout); 
    setOpacity(className, 1); 
} 

Falls Sie die 1 - opaNumber; fragen sich, darüber ist ein einfacher Weg, um einen Wert zwischen 1 und 0. Wie 1-1 = 0 und 1-0 = 1 Schalt.

+0

Danke, aber ich bekomme "Uncaught TypeError: document.getElementsByClassName (...). ForEach ist keine Funktion" nach dem Einrichten der Klasse und der Anpassung des Codes in.;/ – MrMeDo

+0

Sie benötigen etwas wie folgt: https: // jsfiddle.net/2b9304ur/ https://toddmotto.com/ditch-the-array-foreach-call-nodelist-hack/ – sinisake

+0

Damm-Knotenlisten unterstützen forEach nicht. Probieren Sie es jetzt. –

1

Nun begann man heraus mit Erkennen, wo Sie das Problem haben, und das ist schon eine gute Sache :)

Um Ihren Code ein wenig kompakter zu machen, und so viele Dinge wie möglich aus dem lokalen Bereich zu bekommen, Sie könnte die folgende Implementierung überprüfen.

Es ist in gewisser Weise eine kleine Demo, wo ich versucht habe, so viele Kommentare wie möglich hinzuzufügen.

Ich habe ein bisschen mehr bearbeitet, nachdem Sie realisiert haben, dass Sie eher Klassennamen anstelle von IDs verwenden möchten :) Daher verwende ich jetzt eher die document.querySelectorAll, die Ihnen ein bisschen mehr Freiheit gibt.

Jetzt können Sie die startPop-Funktion mit jedem gültigen Selektor aufrufen. Wenn Sie rein ID Pop möchten, können Sie verwenden:

startPop('#elementId'); 

oder wenn Sie für die Klassen

startPop('.className'); 

Das Beispiel gehen wollen selbst auch eine andere Funktion, nl Trigger hinzufügen ist, das zeigt, wie Sie kann die Funktionen starten/stoppen.

Ich entschied mich auch lieber die setInterval Methode anstelle der setTimeout Methode zu verwenden. Beide rufen eine Funktion nach einer bestimmten Anzahl von Millisekunden auf, jedoch müssen Sie setInterval nur einmal aufrufen.

Als zusätzliche Änderung, StopPop verwendet auch jetzt die document.querySelectorAll, so dass Sie die gleiche Freiheit haben sie als startPop Funktion aufrufen.

Ich habe 2 weitere optionale Parameter in der startPop-Funktion hinzugefügt, nämlich total und callback.

Insgesamt gibt die maximalen Zeiten, die Sie wünschen, das Element zu „blinken“ (s), und der Rückruf bietet Ihnen eine Möglichkeit, informiert werden, wenn das Knallen vorbei ist (zB potentielle Elemente zu aktualisieren, die das Knallen gestartet)

ich es geändert etwas mehr, damit Sie es mithilfe der this Syntax für die Inline-Javascript

'use strict'; 
 

 
function getElements(className) { 
 
    // if it is a string, assume it's a selector like #id or .className 
 
    // if not, assume it's an element 
 
    return typeof className === "string" ? document.querySelectorAll(className) : [className]; 
 
} 
 

 
function startPop(className, total, callback) { 
 
    // get the element once, and asign a value 
 
    var elements = getElements(className), 
 
    current = 0; 
 
    var interval = setInterval(function() { 
 
    var opacity = ++current % 2; 
 
    // (increase current and set style to the left over part after dividing by 2) 
 
    elements.forEach(function(elem) { elem.style.opacity = opacity }); 
 
    // check if the current value is larger than the total or 10 as a fallback 
 
    if (current > (total || 10)) { 
 
     // stops the current interval 
 
     stopPop(interval, className); 
 
     // notifies that the popping is finished (if you add a callback function) 
 
     callback && callback(); 
 
    } 
 
    }, 50); 
 
    // return the interval so it can be saved and removed at a later time 
 
    return interval; 
 
} 
 

 
function stopPop(interval, className) { 
 
    // clear the interval 
 
    clearInterval(interval); 
 
    // set the opacity to 1 just to be sure ;) 
 
    getElements(className).forEach(function(elem) { 
 
    elem.style.opacity = 1; 
 
    }); 
 
} 
 

 
function trigger(eventSource, className, maximum) { 
 
    // get the source of the click event (the clicked button) 
 
    var source = eventSource.target; 
 
    // in case the attribute is there 
 
    if (!source.getAttribute('current-interval')) { 
 
    // start it & save the current interval 
 
    source.setAttribute('current-interval', startPop(className, maximum, function() { 
 
     // completed popping (set the text correct and remove the interval) 
 
     source.removeAttribute('current-interval'); 
 
     source.innerText = 'Start ' + source.innerText.split(' ')[1]; 
 
    })); 
 
    // change the text of the button 
 
    source.innerText = 'Stop ' + source.innerText.split(' ')[1]; 
 
    } else { 
 
    // stop it 
 
    stopPop(source.getAttribute('current-interval'), className); 
 
    // remove the current interval 
 
    source.removeAttribute('current-interval'); 
 
    // reset the text of the button 
 
    source.innerText = 'Start ' + source.innerText.split(' ')[1]; 
 
    } 
 
}
<div class="nav1"> 
 
    test navigation 
 
</div> 
 
<div class="nav2"> 
 
    Second nav 
 
</div> 
 
<div class="nav1"> 
 
    second test navigation 
 
</div> 
 
<div class="nav2"> 
 
    Second second nav 
 
</div> 
 
<a id="navigation-element-1" 
 
    onmouseover="this.interval = startPop(this)" 
 
    onmouseout="stopPop(this.interval, this)">Hover me to blink</a> 
 

 
<button type="button" onclick="trigger(event, '.nav1', 100)"> 
 
    Start nav1 
 
</button> 
 
<button type="button" onclick="trigger(event, '.nav2', 100)"> 
 
    Start nav2 
 
</button>

+0

Ich bin immer noch neugierig auf den Downvote (obwohl ich zugeben, ich habe die Frage zunächst falsch verstanden, ich denke, ich habe genug hinzugefügt/korrigiert) – Icepickle

+0

Also im Grunde will ich nicht viele sagen wir div zu "Pop" wenn onmouseover (in meine Situation), nur der eine. Also könnten die Ids auch funktionieren. Ich habe mir den ganzen Weg durchgelesen, nachdem ich erfahren habe, dass man tatsächlich eine Variable für die ID bekommen kann, zum Beispiel onmouseover = "pop ('nav1')". Alles, was ich tun musste, war, diese "da" zu benutzen. Die Sache ist jetzt, dass beim Funktions-Timeout dieser Wert sich zu "undefiniert" ändert, was bedeutet, dass die Funktion das zweite Mal nutzlos ist. Also ich denke, ich muss einen anderen Weg mit der Auszeit machen, oder? – MrMeDo

+0

@MrMeDo Ja, Sie sollten überprüfen, um eine anonyme Funktion zu verwenden, in gewisser Weise wie ich in der SetInterval verwendet, wie Sie bereits den Parameter in Ihrer Pop-Funktion definiert haben, können Sie diesen Wert beim Aufrufen der setTimeout-Methode jedoch meine verwenden Version würde auch für Ihren Plan funktionieren (und beide mit IDs als Klassen;)) – Icepickle

0

für die Maus über ein Element verwenden, Wenn Sie die Verwendung von IDs wiederherstellen möchten, müssen Sie über popTimeout nachdenken, wenn Sie dies für mehr als ein Element gleichzeitig ausführen.

function setOpacity(id, value) { 
    document.getElementById(id).style.opacity = value; 
} 

function runPop(id) { 
    function pop(id, popCount, opaNumber) { 
     if (popCount < 10) { //Must be even number so you end on opacity = 1 
      setOpacity(id, opaNumber); 
      popTimeout = setTimeout(function() { 
       pop(id, popCount++, 1-opaNumber); 
      }, 50); 
     } 
    } 

    var popTimeout; 

    pop(id, 0, 0); 

    return function() { 
     clearTimeout(popTimeout); 
     setOpacity(id, 1); 
    } 
} 

var killPop = []; 

function startPop(id) { 
    killPop[id] = runPop(id); 
} 

function stopPop(id) { 
    killPop[id](); 
} 
Verwandte Themen