是否可以知道函数是由用户事件还是异步事件(如回调)触发而没有原始事件参数?
我正在尝试在更深层的函数调用中确定事件源,该调用不知道谁是原始事件触发器。
我必须知道为了调用弹出或重定向登录系统。但是这个函数是从很多地方调用的,所以我不能在所有调用者中传递event参数。
重要:我无法将参数传递给最终功能。 <{1}}是不允许的。
e.g:
b('timer')
在该示例中,我尝试获取 <a onclick="b()" >call</a>
<script>
function a(){
b();
}
function b(){
final();
}
function final(){
//Is there something like this caller.event.source ?
console.log(this.caller.event.source)
}
setTimeout(a,1000);
或source == 'timer'
或任何其他信息以确定哪个是事件来源。
基于basilikun方法,我实现了这个解决方案:
'onclick'
这是finddle
还有其他办法吗?
答案 0 :(得分:3)
可以在最里面的函数中抛出异常,捕获它,并使用异常来确定调用堆栈。
如何获取调用堆栈的细节是特定于供应商的(FF中为e.stack
,Opera中为e.message
,IE和Safari中的粗略函数体解析),但{ {3}}。
至少,这是我可以从该页面上发布的简短片段中得出的结论。请注意,这已经演变为eriwen.com,因此可能比该页面上的50行代码段更可靠,功能更强大。
在您的示例中,您将使用:
function b(){
final();
}
function final(){
var trace = printStackTrace();
//output trace
}
//This would be attached as the click handler for the anchor
function anchorHandler(){
b();
}
setTimeout(function timerCallback(){
b();
}, 1000);
根据跟踪中是否有timerCallback
或anchorHandler
,您知道哪个事件触发了函数调用。
答案 1 :(得分:2)
假设你至少可以在第一个函数a
中传递“timer”:
<a onclick="a()" >call</a>
<script>
function a(){
b();
}
function b(){
final();
}
function final(){
var callerFunction = arguments.callee.caller;
var evtArg = callerFunction.arguments[0];
while (callerFunction.caller !== null) {
callerFunction = callerFunction.caller;
if (callerFunction.arguments[0]) {
evtArg = callerFunction.arguments[0];
}
}
console.log(evtArg);
}
setTimeout(function(){a("timer")}, 100);
</script>
这将为您提供函数调用链中最后一个可能的第一个参数。因此,如果您使用“普通”事件,它将为您提供事件对象。如果您使用超时,它将为您提供传递给第一个函数的任何内容。
请注意,此解决方案还使用arguments.callee.caller
,它应该很慢并且不支持任何地方。正如robC已经提到的那样,严格模式下不允许这样做。
答案 2 :(得分:1)
您可以使用arguments.callee.caller来访问函数对象并附加一个expando ...不确定这是否适用于您的情况。请注意,这不会在严格模式下工作,因为不推荐使用arguments.callee.caller。
<a onclick="b()" >call</a>
<script>
function a(){
b.calledByA = true;
b();
}
function b(){
final();
}
function final(){
var caller = arguments.callee.caller;
console.log(caller.calledByA);
caller.calledByA = null;
}
setTimeout(a, 1000);
</script>