Nous connaissons les syntaxes ci-dessous, lors de la définition d'un attribut value
pour onClick
:
<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>
Ce qui m'intéresse, c'est de définir un data-attribute
Personnalisé et d'exécuter la valeur comme suit:
<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>
J'ai collé l'échantillon dans jsBin
Une façon consiste à utiliser eval ()
jQuery(".container").on("click", "button.marker", function (e) {
var callback = jQuery(e.currentTarget).data("callback");
var x = eval(callback)
if (typeof x == 'function') {
x()
}
});
Démo: Fiddle
Remarque: assurez-vous qu'il est sûr dans votre environnement, c'est-à-dire qu'il n'y a aucune possibilité d'injection de script en raison d'une mauvaise entrée des utilisateurs
Je pense qu'une meilleure idée serait de lier dynamiquement les événements et de les déclencher. Si vous souhaitez qu'ils ne soient connus que par un autre code, vous pouvez utiliser des événements personnalisés.
<button type="submit" class="marker marker1"></button>
<button type="submit" class="marker marker2"></button>
<button type="submit" class="marker marker3"></button>
<button type="submit" class="marker marker4"></button>
<script>
var $markers = $('.marker');
$markers.filter('.marker1').bind('customCallback', function(){ alert("hi"); });
$markers.filter('.marker2').bind('customCallback', function(){ doWork(); });
</script>
Vos autres composants pourraient alors les invoquer avec $ (selector) .trigger ('customCallback');
Simplement avec:
$("body").on("click","button.marker", function(e) {
eval($(this).data("callback"));
})
Si vous vouliez vraiment passer des fonctions (avec ou sans paramètres) d'une chose à une autre sans les lier en tant qu'événements, vous pouvez le faire de cette façon (je suis parti de la réponse de @ Taplar)
<button type="submit" class="marker marker1"></button>
<button type="submit" class="marker marker2"></button>
<button type="submit" class="marker marker3"></button>
<button type="submit" class="marker marker4"></button>
<script>
var $markers = $('.marker');
$markers.filter('.marker1').get(0).customCallback = doWork;
$markers.filter('.marker2').get(0).customCallback = function(){
doWork(arg0,arg1);
};
</script>
Ensuite, vous pouvez y accéder dans votre autre composant en tant que:
<script>
$('.marker').each(function(){
var thisFunction = $(this).get(0).customCallback;
//do something useful with thisFunction
});
</script>
Vous pouvez simplement lier une fonction en tant qu'attribut de données
const ele = $('button');
ele.data('onClick', evt => {
alert('bye');
})
ele.click(evt => {
const ele = $(evt.target);
ele.data('onClick')(evt);
})
Une autre façon consiste à utiliser window[func](args)
.
Similaire à eval()
, mais vous devrez stocker le nom de la fonction et l'argument séparément dans l'attribut HTML.
Voici un exemple rapide ... CodePen
<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>