有没有办法控制绑定到元素点击的JS脚本的执行顺序?例如,我们有两个单独的脚本,它们在同一个动作和同一个元素上触发。
第一个脚本(由网站上的脚本触发 - 我无权更改):
$('body').on('click', '#button', function1);
第二个脚本(由浏览器插件触发,我可以更改,并在其他所有内容被触发后运行):
$('body').on('click', '#button', function2);
这两个脚本是分开的(在两个不同的文件中),不能合并成这样的一个,因为我只能改变第二个:
$('body').on('click', '#button', function() {
function1();
function2();
});
我可以设定执行顺序吗?我可以强制最后执行一个脚本吗?
答案 0 :(得分:0)
在第二个脚本中,您可以通过第一个脚本读取哪个函数与click事件绑定。然后您可以分离该处理程序并添加您自己的处理程序,如果您愿意,可以在最后一步添加原始函数的执行:
// script 1 ///////////////////////////////////////////////////////////
function f1() {
console.log('f1: function bound by script 1');
}
$('body').on('click', '#button', f1);
// script 2 ///////////////////////////////////////////////////////////
function f2() {
console.log('f2: my own function that should run first');
}
var original_f = $._data(document.body, 'events').click[0].handler;
$('body').off('click', '#button').on('click', '#button', function () {
f2();
original_f();
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Trigger handlers</button>
&#13;
这使用$._data
,它不是jQuery的公共API的一部分。请参阅this answer。
以上解决方案假设
网站的脚本(第一个脚本)在元素body
的{{1}}元素上使用jQuery事件委托;如下:
#button
请注意,还有其他方法可以附加事件处理程序,但是这个答案假设第一个脚本是这样做的(就像您在问题中提供的那样)。当然,$('body').on('click', '#button', function1);
可以是任何函数,甚至是匿名的内联函数。
您可以完全控制第二个脚本,并可以重新定义您在其中定义的点击处理程序。
您在评论中写道,您无法访问第一个脚本(function1
)的功能。但请注意,如果JavaScript能够执行它,则没有理由无法通过JavaScript访问它。
此外,由于您通知第一个脚本使用jQuery附加其处理程序,jQuery也知道它是哪个函数并且可以访问它(当发生单击事件时它还能如何执行它?)。
我上面提供的解决方案实际上要求jQuery为您提供该函数的引用。然后你可以像jQuery在发生点击事件时那样执行它。
为了验证第一个脚本确实以这种方式设置了处理程序:
function1
...而且仍然存在,您可以使用以下脚本进行调试:
$('body').on('click', '#button', function1);
&#13;
// script 1 -- you don't need to enter this, it is for this snippet to work with.
function f1() {
console.log('f1: function bound by script 1');
}
$('body').on('click', '#button', f1);
// script 2 -- your code ///////////////////////////////////////////////////////////
var click_handlers = $._data(document.body, 'events').click;
console.log('Info on BODY click handlers that have been set via jQuery:\n',
JSON.stringify(click_handlers, null, 2));
console.log('First click handler is this function:\n', click_handlers[0].handler);
&#13;