我有一个按钮,其中包含:
onclick
实施例
<input id='b1' type='button' value='go' onclick='alert("0")';'/>
$("#b1").on('click',function (){alert('1');});
$("#b1").on('click',function (){alert('2');});
$("#b1").on('click',function (){alert('3');});
警告0,1,2,3。
但是如何在“自定义索引”中插入新的onclick
?
例如,让我们说我想在1,2的警报之间插入一个函数。
我该怎么做?
p.s:
控制内联onclick
不是问题,我只需要使用attr
并稍后执行。
对我来说问题是.on
寄存器。我想过$.data("events")
但它已被弃用,应该只用于调试建议。 (也 - 它的语法已经改变了。)
答案 0 :(得分:6)
我写了small jQuery plugin声称这样做。
使用on
jQuery函数(实际上是我的插件重写的),如下所示:
<script src="path/to/jQuery.js"></script>
<script src="path/to/jQuery-priorityze.js"></script>
<button id="go">Test 1</button>
<script>
var $go = $("#go");
$go.on('click', 5, function () { console.log('nice'); });
$go.on('click', {priority: 4}, function () { console.log('a'); });
$go.on('click', 6, function () { console.log('plugin?'); });
$go.on('click', 1, function () { console.log('Is'); });
$go.on('click', 3, function () { console.log('this'); });
$go.on('click', 2, function () { console.log('not'); });
<script>
如果未提供优先级,插件将选择将1
递增到最新提供的优先级的事件的优先级。
我希望在不改变现有结构的情况下获得解决方案
在页面中加入我的插件并使用:
$("#b1").on('click', function (){alert('1');}); // 1
$("#b1").on('click', function (){alert('2');}); // 2
$("#b1").on('click', function (){alert('3');}); // 3
$("#b1").on('click', 1.5, function (){alert('4');}); // 1.5
// 0 -> 1 -> 4 -> 2 -> 3
// seems that onclick attribute is stronger that .on
function topPriority() {
alert('top priority');
}
设置1.5
优先级将最后一个处理程序放在第一个(1
)和第二个(2
)之间。
就像我评论onclick
属性强于on
jQuery函数。
在Github上查看源代码here并检查测试。
别忘了给它上演明星:https://github.com/IonicaBizau/jQuery-prioritize :-)
该插件与jQuery >= 1.8.x
兼容,并使用$._data($el[0]).events
,如here所述。
你想为这个项目做贡献吗?大!请按照以下步骤操作:
我会尝试尽快合并拉取请求。
答案 1 :(得分:2)
如果你需要一个dinamic的东西,你可以在你的代码中的任何一点添加一些事件,而不改变你已经在做的结构,我建议一个简单的解决方法:
在您创建的代码的开头:
$("#b1").on('click')
分配给遍历调用每个回调的数组的函数$("#b1").on('click',function (){alert('1');});
现在您必须在所有其他事件之后调用$("#b1").onclick(function (){alert('1');});
//或$("#b1").onclick(function (){alert('1');}, INDEX);
//如果您需要你想要一个特定的订单(INDEX是一个整数)完整的代码是:
$("#b1").on('click',function(){
for (var i = 0; i < callbacks.length; i++)
callbacks[i]();
});
callbacks= new Array();
jQuery.fn.extend({
onclick: function(callback, index) {
if (index) {
callbacks.splice(index, 0,callback);
}
else callbacks.push(callback);
}
});
你只需将它放在一开始,然后,无论你在什么地方注册一个事件,你都会像过去那样做,例如:
$("#b1").onclick(function (){alert('1');});
$("#b1").onclick(function (){alert('2');});
$("#b1").onclick(function (){alert('3');});
$("#b1").onclick(function (){alert('new 2');},2); //index 2
您可以在此jsfiddle
中试用答案 2 :(得分:1)
实际上,JQuery(而不是vanilla js)保证了多个回调的顺序,但它保留了一些内部JQuery机制。您可以创建回调数组并迭代它:
var callbacks = [
function (){alert('1');},
function (){alert('2');},
function (){alert('3');}
];
$("#b1").click(function() {
for (var i = 0; i < callbacks.length; i++) callbacks[i]();
});
现在,您可以通过随机播放来维护订单,或像常规数组一样扩展callbacks
数组
答案 3 :(得分:1)
好的,这不是不可能的。首先,我只确定这适用于使用jQuery添加的事件,但我认为它可能适用于其他情况。有一些事情需要考虑:
onclick
属性。onclick
属性首先出现,但如果在文档加载后更改该属性,则会在附加到该元素的任何其他处理程序之后执行该属性。因此,目标是添加一个新的事件处理程序,它将以您选择的任何顺序执行,而无需修改任何现有代码,并使用jQuery。所以我创建了一个脚本,它的工作方式如下:它抓取所有类型的所有点击事件,从目标事件到文档,并保留与目标匹配的事件。它从目标元素中删除当前的onclick
函数,并将其添加到事件中。然后,它会添加自定义onclick
函数,并断开绑定到目标的所有单击事件。在自定义onclick
函数stopPropagation()
中,事件不会冒泡DOM,将新函数插入所需的索引,然后按顺序运行事件。它不应该混淆由其他元素触发的任何点击事件
这是一个有效的jsfiddle:http://jsfiddle.net/mMG99/8/
这是代码,它可能会被清理很多:
<input id='b1' type='button' value='go' onclick='alert("0");'/>
<br>
<input id='index' type='number' min='0' />
<input id='b2' type='button' value='add listener at this index'/>
// Uses different ways to add the event handlers to test if this works with each
$("#b1").on('click',function (){alert('1');});
$("#b1").bind('click',function (){alert('2');});
$(document).on('click', '#b1', function (){alert('3');});
var selector = '#b1';
var insertedFunction = function(){alert('heyooo!');};
var $target = $(selector);
var oldOnClickFunction = new Function($target.attr('onclick'));
var targetEvents = [oldOnClickFunction];
var boundEvents = $._data($target.get(0), "events");
boundEvents && boundEvents.click && $.each(boundEvents.click, function(i, val){
targetEvents.push(val.handler);
});
var $targets = $(document).add($target.parents());
$targets.each(function(){
var eventObj = $._data(this, "events");
eventObj && eventObj.click && $.each(eventObj.click, function(i, val){
if($target.filter(val.selector).length) {
targetEvents.push(val.handler);
}
});
});
newOnClick = function(event){
event.stopPropagation();
$.each(targetEvents, function(i, handler){
handler(event);
});
};
$("#b2").on('click', function(){
$target.attr('onclick', 'newOnClick(event)');
var removeAt = targetEvents.indexOf(insertedFunction);
if (removeAt != -1) {
targetEvents.splice(removeAt,1);
}
targetEvents.splice(parseInt($('#index').val()), 0, insertedFunction);
$target.off('click');
});
答案 4 :(得分:0)
最简单的方法是更改代码的最少量,将新函数调用放在您想要的事件处理程序中。但最好的方法是只有一个事件处理程序调用你想调用的所有函数,而不是有一些事件监听器:
<input id='b1' type='button' value='go' onclick='alert("0")';'/>
$("#b1").on('click',function (){
alert('1');
newFunctionCall();
alert('2');
alert('3');
});
答案 5 :(得分:0)
我不确定你能找到适合自己的工作方式,至少你想做的事情。
无论如何,你需要某种切换器,只要你无法阅读有关当前事件的任何信息,就无法解开 - &gt;这个切换器应该在你用“alert”替换的功能中实现。
相当有趣的解决方案(仅在Chrome中检查):http://jsbin.com/UsuRanAR/3/edit
function alert(a) {
setTimeout(function(){
console.log(a);
},((a == 1 || a == 'top priority')?0:200));
}
我担心这是你从这种情况中获得的最大值。
答案 6 :(得分:0)
我打算建议:
添加占位符html节点,隐藏原始节点,单击占位符时,执行“优先级”操作然后触发单击原始节点:
var $clone = $('#b1').clone().attr('id', null).attr('onclick', null);
$clone.insertBefore('#b1');
$('#b1').hide();
$clone.on('click', function(e){
alert('Kilroy was here');
$('#b1').trigger('click');
// do not duplicate the bubbling/default action
return false;
});
但出于某种原因,在这种情况下,onclick
回调最后被调用...