Übergeben Sie die Javascript-Funktion als data-*-Attribut und führen Sie sie aus
Lesezeit: 6 Minuten
Wir kennen solche Syntaxen wie unten, wenn wir a definieren value zum onClick Attribut:
<button type="submit" onclick="alert('hi');"></button>
<button type="submit" onclick="doWork"></button> <!-- This one doesn't work -->
<button type="submit" onclick="doWork()"></button>
<button type="submit" onclick="doWork('Mike', 2)"></button>
Was mich interessiert, ist, einen Brauch zu definieren data-attribute und führen Sie den Wert wie folgt aus:
<button type="submit" data-callback="alert('hi');" class="marker"></button>
<button type="submit" data-callback="doWork" class="marker"></button>
<button type="submit" data-callback="doWork()" class="marker"></button>
<button type="submit" data-callback="doWork('Mike', 2)" class="marker"></button>
<script type="text/javascript">
jQuery("body").on("click","button.marker", function(e) {
var callback = jQuery(e.currentTarget).data("callback");
// Now I need to execute the callback no matter of the format
// 1. Execute as function's body
// 2. Or by function 'name'
// 3. Or by function 'name' with 0 parameters
// 4. Or by function 'name' with n parameters
})
function doWork(name, nr){
var personName = name || "Unnamed";
var personNr = nr || 0;
alert("Name is: " + personName + " Nr: " + personNr);
}
</script>
Gibt es einen Grund, warum Sie die dynamische Bindung vermeiden? Würde das Thema vereinfachen.
– Taplar
4. Mai 2015 um 11:01 Uhr
Wenn Sie keinen wirklich guten Grund haben / nur experimentieren, scheint das Schreiben von Code in ein Datenattribut nur eine schlechte Idee zu sein! Sie können den Rückruf einfach auf die Schaltflächen setzen $(.marker).myCallback = doWork; Fühlen Sie sich frei, meine Meinung zu erweitern, wenn Sie nicht einverstanden sind 🙂
– Michiel Cornille
4. Mai 2015 um 11:05 Uhr
@ Taplar Ja. Das Beispiel ist vereinfacht. Im Produktionscode soll der Callback von anderen Komponenten und zu einem späteren Zeitpunkt aufgerufen werden.
– Christian E.
4. Mai 2015 um 11:05 Uhr
@Mvision: AngularJS hält das Schreiben von Code in Attributen nicht für eine schlechte Idee 🙂 Es ist sein Kern und meiner Meinung nach sogar das, was es ausmacht Weg besser zu verwenden als jQuery.
jQuery(".container").on("click", "button.marker", function (e) {
var callback = jQuery(e.currentTarget).data("callback");
var x = eval(callback)
if (typeof x == 'function') {
x()
}
});
Hinweis: Stellen Sie sicher, dass es in Ihrer Umgebung sicher ist, dh es besteht keine Möglichkeit der Skriptinjektion aufgrund schlechter Eingaben von Benutzern
Warum ist die Verwendung der JavaScript-Bewertungsfunktion eine schlechte Idee?
Ich glaube eval("doWork('Mike', 2)") startet die Funktion selbst. Sie müssen es nicht neu starten, indem Sie weitere hinzufügen ().
– Jeremy Thille
4. Mai 2015 um 11:03 Uhr
@JeremyThille das ist der data-callback="doWork" Fall, in dem eine Funktionsreferenz übergeben wird
– Arun P. Johny
4. Mai 2015 um 11:03 Uhr
Ich stimme zu, aber ich denke, OP sucht nach der einen oder anderen Lösung, und sie werden sich für eine der beiden entscheiden "dowork" oder "dowork()" Syntax, machen die if (typeof x == 'function') Test nutzlos.
– Jeremy Thille
4. Mai 2015 um 11:05 Uhr
@JeremyThille Ich habe das deswegen gemacht Or by function 'name' – Ich bin davon ausgegangen, dass OP gemeint ist, dass eine Funktionsreferenz (Name) übergeben wird, die ausgeführt werden muss
– Arun P. Johny
4. Mai 2015 um 11:07 Uhr
@ArunPJohny Auch wenn JeremyThille mit der Antwort schneller war. Ich werde Ihre als akzeptiert markieren, daher ist sie für zukünftige SO-Benutzer “vollständiger”. Vielen Dank
– Christian E.
4. Mai 2015 um 11:55 Uhr
Taplar
Ich denke, eine bessere Idee wäre, die Ereignisse dynamisch zu binden und sie auszulösen. Wenn Sie möchten, dass sie nur durch anderen Code bekannt sind, können Sie benutzerdefinierte Ereignisse verwenden.
Die Parameter sind in der Funktion, aber alles ist fest codiert: data-callback="doWork('Mike', 2)"
– Jeremy Thille
8. März 2017 um 9:39 Uhr
ja, deshalb war meine frage, wie man durchkommt. Natürlich weiß ich, dass wir hart codieren können. eval("function")(args) wird nicht funktionieren
– Tim Kretschmer
9. März 2017 um 4:09 Uhr
Nun, ich denke, wenn die doWork Funktion ist global, Sie können so etwas tun window[ $(this).data("callback") ](arg1, arg2) aber das alles ist sooooo schmutzig :/ Übergeben globaler Funktionen über HTML-Attribute … yurgh … Warum nicht den sauberen Weg gehen und einfach JS-Funktionen in einem isolierten Bereich schreiben?
– Jeremy Thille
9. März 2017 um 8:08 Uhr
Michiel Cornille
Wenn Sie wirklich Funktionen (mit oder ohne Parameter) von einer Sache zur anderen übergeben wollten, ohne sie als Ereignisse zu binden, könnten Sie dies auf diese Weise tun (ich begann mit der Antwort von @Taplar).
Dann könnten Sie in Ihrer anderen Komponente wie folgt darauf zugreifen:
<script>
$('.marker').each(function(){
var thisFunction = $(this).get(0).customCallback;
//do something useful with thisFunction
});
</script>
Sie können eine Funktion einfach als Datenattribut binden
const ele = $('button');
ele.data('onClick', evt => {
alert('bye');
})
ele.click(evt => {
const ele = $(evt.target);
ele.data('onClick')(evt);
})
Es ist erwähnenswert, dass dies nicht als Datenattribut im DOM gespeichert wird. JQuery abstrahiert das und verwaltet diese Daten in sich selbst. In Attributen können nur Zeichenfolgen gespeichert werden. Das heißt, es kann nicht in nativem JS gelesen werden. Immer noch eine viel bessere Lösung als die Verwendung von eval, vorausgesetzt, jQuery ist verfügbar.
– ste2425
17. September 2018 um 10:57 Uhr
Asuka165
Ein anderer Weg ist die Verwendung window[func](args).
Ähnlich wie eval()aber Sie müssen den Funktionsnamen und das Argument separat im HTML-Attribut speichern.
<button type="submit" data-func="Angel" data-args="use me instead of evil()" class="marker">TEST</button>
<script type="text/javascript">
//=== The Listener =====
$(".marker").on("click",function(){
// Get the function name and arguments
let func = $(this).attr("data-func");
let args = $(this).attr("data-args");
// Call the function
window[func](args);
})
//=== The Function =====
function Angel(msg){
alert(arguments.callee.name + " said : " + msg);
}
</script>
Es ist erwähnenswert, dass dies nicht als Datenattribut im DOM gespeichert wird. JQuery abstrahiert das und verwaltet diese Daten in sich selbst. In Attributen können nur Zeichenfolgen gespeichert werden. Das heißt, es kann nicht in nativem JS gelesen werden. Immer noch eine viel bessere Lösung als die Verwendung von eval, vorausgesetzt, jQuery ist verfügbar.
– ste2425
17. September 2018 um 10:57 Uhr
12065200cookie-checkÜbergeben Sie die Javascript-Funktion als data-*-Attribut und führen Sie sie ausyes
Sie können sich den Teufel ansehen bewerten()
– Arun P. Johny
4. Mai 2015 um 10:55 Uhr
Gibt es einen Grund, warum Sie die dynamische Bindung vermeiden? Würde das Thema vereinfachen.
– Taplar
4. Mai 2015 um 11:01 Uhr
Wenn Sie keinen wirklich guten Grund haben / nur experimentieren, scheint das Schreiben von Code in ein Datenattribut nur eine schlechte Idee zu sein! Sie können den Rückruf einfach auf die Schaltflächen setzen $(.marker).myCallback = doWork; Fühlen Sie sich frei, meine Meinung zu erweitern, wenn Sie nicht einverstanden sind 🙂
– Michiel Cornille
4. Mai 2015 um 11:05 Uhr
@ Taplar Ja. Das Beispiel ist vereinfacht. Im Produktionscode soll der Callback von anderen Komponenten und zu einem späteren Zeitpunkt aufgerufen werden.
– Christian E.
4. Mai 2015 um 11:05 Uhr
@Mvision: AngularJS hält das Schreiben von Code in Attributen nicht für eine schlechte Idee 🙂 Es ist sein Kern und meiner Meinung nach sogar das, was es ausmacht Weg besser zu verwenden als jQuery.
– Jeremy Thille
4. Mai 2015 um 11:08 Uhr