Ich suche nach einer Möglichkeit, zwei separate Operationen / Funktionen / "Codeblöcke" auszuführen, wenn auf etwas geklickt wird, und dann einen völlig anderen Block, wenn dasselbe erneut angeklickt wird. Ich habe das zusammengestellt. Ich habe mich gefragt, ob es einen effizienteren / eleganteren Weg gibt. Ich weiß über jQuery .toggle () Bescheid, aber es ist irgendwie beschissen .
Arbeiten hier: http://jsfiddle.net/reggi/FcvaD/1/
var count = 0;
$("#time").click(function() {
count++;
//even odd click detect
var isEven = function(someNumber) {
return (someNumber % 2 === 0) ? true : false;
};
// on odd clicks do this
if (isEven(count) === false) {
$(this).animate({
width: "260px"
}, 1500);
}
// on even clicks do this
else if (isEven(count) === true) {
$(this).animate({
width: "30px"
}, 1500);
}
});
javascript
jquery
ThomasReggi
quelle
quelle
toggle()
saugt nicht, es tut einfach nicht das, was du brauchst;)Antworten:
In jQuery werden zwei Methoden aufgerufen
.toggle()
. Der andere [docs] macht genau das, was Sie für Klickereignisse wollen.Hinweis: Es scheint , dass zumindest seit jQuery 1.7 , ist diese Version von
.toggle
ist veraltet , wahrscheinlich genau aus diesem Grund, nämlich dass zwei Versionen existieren. Die Verwendung.toggle
zum Ändern der Sichtbarkeit von Elementen ist nur eine häufigere Verwendung. Die Methode wurde in jQuery 1.9 entfernt .Im Folgenden finden Sie ein Beispiel dafür, wie Sie die gleiche Funktionalität wie ein Plugin implementieren können (wahrscheinlich jedoch dieselben Probleme wie bei der integrierten Version (siehe den letzten Absatz in der Dokumentation)).
(function($) { $.fn.clickToggle = function(func1, func2) { var funcs = [func1, func2]; this.data('toggleclicked', 0); this.click(function() { var data = $(this).data(); var tc = data.toggleclicked; $.proxy(funcs[tc], this)(); data.toggleclicked = (tc + 1) % 2; }); return this; }; }(jQuery));
DEMO
(Haftungsausschluss: Ich sage nicht, dass dies die beste Implementierung ist! Ich wette, sie kann in Bezug auf die Leistung verbessert werden.)
Und dann nenne es mit:
$('#test').clickToggle(function() { $(this).animate({ width: "260px" }, 1500); }, function() { $(this).animate({ width: "30px" }, 1500); });
Update 2:
In der Zwischenzeit habe ich ein passendes Plugin dafür erstellt. Es akzeptiert eine beliebige Anzahl von Funktionen und kann für jedes Ereignis verwendet werden. Es kann auf GitHub gefunden werden .
quelle
this.each
, zumal dies einfuncs
Array und eine neue Ereignishandlerfunktion für jedes Element erzeugt. Es wurde behoben und Demo hinzugefügt..toggle
Methode entdeckt. Ich wollte diesen Code aber nicht wegwerfen ...data.toggleclicked
das Element einfach auf den Index, auf den Sie zurücksetzen möchten.DEMO
.one () Dokumentation.
Ich bin sehr spät zu antworten, aber ich denke, es ist der kürzeste Code und könnte helfen.
function handler1() { alert('First handler: ' + $(this).text()); $(this).one("click", handler2); } function handler2() { alert('Second handler: ' + $(this).text()); $(this).one("click", handler1); } $("div").one("click", handler1);
DEMO Mit Op's Code
function handler1() { $(this).animate({ width: "260px" }, 1500); $(this).one("click", handler2); } function handler2() { $(this).animate({ width: "30px" }, 1500); $(this).one("click", handler1); } $("#time").one("click", handler1);
quelle
.one()
Methode Bescheid , aber sie ist sehr nützlich. DankeMicro jQuery Plugin
Wenn Sie Ihre eigene verkettbare clickToggle jQuery-Methode möchten , können Sie dies wie folgt tun:
jQuery.fn.clickToggle = function(a, b) { return this.on("click", function(ev) { [b, a][this.$_io ^= 1].call(this, ev) }) }; // TEST: $('button').clickToggle(function(ev) { $(this).text("B"); }, function(ev) { $(this).text("A"); });
<button>A</button> <button>A</button> <button>A</button> <script src="//code.jquery.com/jquery-3.3.1.min.js"></script>
Einfache Funktionen Toggler
LIVE DEMO
function a(){ console.log('a'); } function b(){ console.log('b'); } $("selector").click(function() { return (this.tog = !this.tog) ? a() : b(); });
Wenn Sie es noch kürzer haben möchten ( warum sollte es eines geben, oder?! ), Können Sie den Bitwise XOR * Docs- Operator wie folgt verwenden :
DEMO
return (this.tog^=1) ? a() : b();
Das ist alles.
Der Trick besteht darin, für das
this
Objekt eineboolean
Eigenschafttog
festzulegen, diese mit negation (tog = !tog
) umzuschaltenund die erforderlichen Funktionsaufrufe in einen bedingten Operator einzufügen
?:
Im Beispiel von OP (auch mit mehreren Elementen) könnte es so aussehen:
function a(el){ $(el).animate({width: 260}, 1500); } function b(el){ $(el).animate({width: 30}, 1500); } $("selector").click(function() { var el = this; return (el.t = !el.t) ? a(el) : b(el); });
AUCH : Sie können -toggle auch wie folgt speichern :
DEMO :
$("selector").click(function() { $(this).animate({width: (this.tog ^= 1) ? 260 : 30 }); });
aber es war nicht die genaue Anfrage des OP für ihn
looking for a way to have two separate operations / functions
Verwenden von Array.prototype.reverse :
Hinweis : Dadurch wird nicht der aktuelle Umschaltstatus gespeichert, sondern nur unsere Funktionspositionen im Array umgekehrt (es hat seine Verwendung ...).
Sie speichern einfach Ihre a, b- Funktionen in einem Array. Klicken Sie einfach auf, um die Array-Reihenfolge umzukehren, und führen Sie die folgende
array[1]
Funktion aus:LIVE DEMO
function a(){ console.log("a"); } function b(){ console.log("b"); } var ab = [a,b]; $("selector").click(function(){ ab.reverse()[1](); // Reverse and Execute! // >> "a","b","a","b"... });
EINIGES MASHUP!
jQuery DEMO
JavaScript DEMO
Erstellen Sie eine nette Funktion
toggleAB()
, die Ihre beiden Funktionen enthält, fügen Sie sie in das Array ein und führen Sie am Ende des Arrays einfach die Funktion [0 // 1
] aus, abhängig von dertog
Eigenschaft, die aus derthis
Referenz an die Funktion übergeben wird :function toggleAB(){ var el = this; // `this` is the "button" Element Obj reference` return [ function() { console.log("b"); }, function() { console.log("a"); } ][el.tog^=1](); } $("selector").click( toggleAB );
quelle
.tog
ist nur eine Eigenschaft, die wir demthis
Objekt hinzufügen . Genau wie in "Person.name = "koz"
Person ist ein Objekt" weisen Sie einename
Eigenschaft und dann einen Wert zu. Mehr zum XOR-Operator^
finden Sie hier: stackoverflow.com/a/22061240/383904 (Sie können den gleichen Link in meiner Antwort finden;))one
an jeder Bitposition ein zurück, für die die entsprechenden Bits eines der Operanden, jedoch nicht beider Operanden sindones
. Wie Sie bemerkt haben, gehen wir immer gegen die Einsen (1
) -Operatoren vor:operand^1
Hier ist eine Ergebnistabelle :0^1 =1
und1^1 =0
. So weit so gut - die Ergebnisse wechseln! Aber um unseren Operator tatsächlich zu ändern, müssenel.tog
Sie den Assignment-Operator (=
) verwenden - und los geht's!el.tog^=1
. Wenn Sie nun auf die kleine Tabelle zurückgreifen, werden Sie verstehen, welche Werte derel.tog
Eigenschaft jetzt zugewiesen sind .Ich würde so etwas für den Code tun, den Sie gezeigt haben, wenn Sie nur einen Wert umschalten müssen:
var oddClick = true; $("#time").click(function() { $(this).animate({ width: oddClick ? 260 : 30 },1500); oddClick = !oddClick; });
quelle
width:
-Linie mitwidth: $(this).width() == 30 ? 260 : 30
.Ich habe dies verwendet, um einen Umschalteffekt zwischen zwei Funktionen zu erzeugen.
var x = false; $(element).on('click', function(){ if (!x){ //function x = true; } else { //function x = false; } });
quelle
Ich denke nicht, dass Sie die Umschaltmethode implementieren sollten, da es einen Grund gibt, warum sie aus jQuery 1.9 entfernt wurde.
Verwenden Sie stattdessen toggleClass, das von jQuery vollständig unterstützt wird:
function a(){...} function b(){...}
Nehmen wir zum Beispiel an, Ihr Ereignisauslöser ist onclick, also:
Erste Wahl:
$('#test').on('click', function (event) { $(this).toggleClass('toggled'); if ($(this).hasClass('toggled')) { a(); } else{ b(); } }
Sie können die Handlerfunktionen auch als Parameter senden:
Zweite Option:
$('#test').on('click',{handler1: a, handler2: b}, function (event) { $(this).toggleClass('toggled'); if ($(this).hasClass('toggled')) { event.data.handler1(); } else{ event.data.handler2(); } }
quelle
Wenn Sie nur einen Booleschen Wert beibehalten,
isEven
können Sie prüfen, ob sich eine KlasseisEven
im Element befindet, und diese Klasse dann umschalten.Die Verwendung einer gemeinsam genutzten Variablen wie count ist eine schlechte Praxis. Fragen Sie sich, welchen Umfang diese Variable hat. Denken Sie daran, wenn Sie 10 Elemente hätten, die Sie auf Ihrer Seite umschalten möchten, würden Sie 10 Variablen oder ein Array oder Variablen erstellen, um deren Status zu speichern? Wahrscheinlich nicht.
Bearbeiten:
jQuery verfügt über eine switchClass- Methode, mit der in Kombination mit hasClass zwischen den beiden von Ihnen definierten Breiten animiert werden kann. Dies ist günstig, da Sie diese Größen später in Ihrem Stylesheet ändern oder andere Parameter wie Hintergrundfarbe oder Rand zum Übergang hinzufügen können.
quelle
Verwenden Sie einige Funktionen und einen Booleschen Wert. Hier ist ein Muster, kein vollständiger Code:
var state = false, oddONes = function () {...}, evenOnes = function() {...}; $("#time").click(function(){ if(!state){ evenOnes(); } else { oddOnes(); } state = !state; });
Oder
var cases[] = { function evenOnes(){...}, // these could even be anonymous functions function oddOnes(){...} // function(){...} }; var idx = 0; // should always be 0 or 1 $("#time").click(function(idx){cases[idx = ((idx+1)%2)]()}); // corrected
(Beachten Sie, dass die zweite nicht mehr auf meinem Kopf liegt und ich viele Sprachen mische, sodass die genaue Syntax nicht garantiert ist. Sollte in der Nähe von echtem Javascript liegen.)
quelle
$("#time").click(..)
nur einmal auf, wodurch die aufzurufende Funktion festgelegt wird.Wenn Sie die erste Antwort ändern, können Sie zwischen n Funktionen wechseln:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus.com®"> <!-- <script src="../js/jquery.js"></script> --> <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script> <title>my stupid example</title> </head> <body> <nav> <div>b<sub>1</sub></div> <div>b<sub>2</sub></div> <div>b<sub>3</sub></div> <!-- .......... --> <div>b<sub>n</sub></div> </nav> <script type="text/javascript"> <!-- $(document).ready(function() { (function($) { $.fn.clickToggle = function() { var ta=arguments; this.data('toggleclicked', 0); this.click(function() { id= $(this).index();console.log( id ); var data = $(this).data(); var tc = data.toggleclicked; $.proxy(ta[id], this)(); data.toggleclicked = id }); return this; }; }(jQuery)); $('nav div').clickToggle( function() {alert('First handler');}, function() {alert('Second handler');}, function() {alert('Third handler');} //...........how manny parameters you want..... ,function() {alert('the `n handler');} ); }); //--> </script> </body> </html>
quelle
Einzeilige Lösung: Grundidee:
$('sth').click(function () { let COND = $(this).propery == 'cond1' ? 'cond2' : 'cond1'; doSomeThing(COND); })
Beispiele auf jsfiddle
Beispiel 1: Ändern von innerHTML eines Elements in einem Umschaltmodus:
$('#clickTest1').click(function () { $(this).html($(this).html() == 'click Me' ? 'clicked' : 'click Me'); });
Beispiel 2: Umschalten der Anzeigen zwischen "none" und "inline-block":
$('#clickTest2, #clickTest2 > span').click(function () { $(this).children().css('display', $(this).children().css('display') == 'inline-block' ? 'none' : 'inline-block'); });
quelle