Передайте функцию javascript как атрибут data-* и выполните
мы знаем такие синтаксисы, как ниже, при определении value
на :
<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>
что меня интересует, это определить пользовательский data-attribute
и выполните значение следующим образом:
<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>
я вставил образец jsBin
как сделать такое же поведение, используя пользовательские атрибуты данных?
5 ответов
один из способов-это использовать 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()
}
});
демо: Скрипка
Примечание: убедитесь, что это безопасно в вашей среде, т. е. нет возможности инъекции скрипта из-за плохого ввода от пользователей
Я думаю, что лучшей идеей было бы динамически связывать события и запускать их. Если вы хотите, чтобы они были известны только другим кодом, вы можете использовать пользовательские события.
<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>
тогда ваши другие компоненты могут вызывать их с помощью $(selector).триггер('customCallback');
Если вы действительно хотели передать функции (с параметрами или без них) от одной вещи к другой, не связывая их как события, вы могли бы сделать это таким образом (я начал с ответа @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>
тогда вы можете получить к ним доступ в другом компоненте как:
<script>
$('.marker').each(function(){
var thisFunction = $(this).get(0).customCallback;
//do something useful with thisFunction
});
</script>
вы можете просто связать функцию как атрибут данных
const ele = $('button');
ele.data('onClick', evt => {
alert('bye');
})
ele.click(evt => {
const ele = $(evt.target);
ele.data('onClick')(evt);
})