我有一个指向外部网址的链接。我要归档的是,不要重定向到前4次点击的链接,而是第五次点击。
我知道我可以使用
e.preventDefault()
以防止重定向发生,但问题是如何在第5次点击时恢复正常行为? (转到指定的链接)
我创建了一个简单的代码段来演示我想要完成的任务。
https://jsfiddle.net/fuyi/k62oo6uu/
$('a').click(function(e){ console.log('event captured'); });

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#">A link</a>
&#13;
答案 0 :(得分:3)
在一个闭包中你可以有一个变量跟踪它被点击的时间。
例如:
node.addEventListener("click", (function () {
let nbOfClicks = 0;
return function (e) {
if (nbOfClicks < 4) {
nbOfClicks = nbOfClicks + 1;
e.preventDeault();
//do stuff
} else {
// do not prevent click, do stuff
}
};
} ()), false);
var nbOfClicks 只能在IIFE内部访问。 IIFE返回事件的处理程序,并可以访问该变量以读取/更新其值。
请注意,这适用于一个 DOM元素。
如果你想将它用于集合,我认为这更接近你的问题:在每个链接上,防止点击四次的默认行为,否则允许默认行为。
在这种情况下,你有类似的东西:
$("a").each(function () {
this.addEventListener("click", (function () {
let nbOfClicks = 0;
return function (e) {
if (nbOfClicks < 4) {
nbOfClicks = nbOfClicks + 1;
e.preventDeault();
//do stuff
} else {
// do not prevent click, do stuff
}
};
} ()), false);
});
因为循环遍历jQuery集合时,此词法上下文绑定到当前DOM元素。
当然有权衡,因为如果你有大量的链接,那么你只需循环整个集合并为每个集合创建一个闭包,这非常昂贵(选择和闭包)。您可能需要查找事件委派。
如果你想要一个更精确的解决方案,你可以准确地决定做什么,你可能想要考虑这样的通用处理函数:
function handleClick (nbOfTimes, e) {
if (nbOfTimes > 4) { // 4 being a magic number, but anykind of condition could go there,
//also don't forget that you can access the target nodes via e.target
}
// then you should return some kind of data indicating
// what to do afert, like event unbinding, redirection (careful XSS) and so on...
return { unbindEvent: true, redirect: false};
}
最后你有更通用的版本:
$("a").each(function () {
this.addEventListener("click", (function () {
let nbOfClicks = 0;
return function (e) {
nbOfClicks = nbOfClicks + 1;
let {unbindEvent, redirect} = handleClick(nbOfClicks, e);
if (unbindEvent === true) {
// do stuff
}
if (redirect === true) {
// do stuff
}
};
} ()), false);
});
通过阅读评论,看起来你想要的是一个去抖动,在这种情况下,如果我们采取第二个例子我们有
$("a").each(function () {
this.addEventListener("click", (function () {
let lastClickStamp = 0;
return function (e) {
if (lastClickStamp === 0) {
// first click ever
// or since a long period of time
lastClickStamp = e.timeStamp;
// trigger your httprequest
} else {
let diff = e.timeStamp - lastClickStamp;
if (diff > threshold) {
// threshold is your debouncing value,
// which sets the rate at which your events
// wil be processed
// here you exceed the threshold so you can take
// action, but you need to update the last time
// your function was called
lastClickStamp = e.timeStamp;
} else {
// you called the function before enough
//time elapsed
// so you do nothing
}
}
};
} ()), false);
});
作为参考,我建议查看lodash.debounce函数以及更高级的东西到Observables以及像RxJS这样的库中的debounce运算符(或xstream,most.js ......)。
还有你可以看到的油门操作(在lodash和Observables中)。
请询问您是否需要更多详情。
结论是:使用JS闭包的力量!
答案 1 :(得分:0)
您可以计算点击次数,然后取消绑定事件。例如:
var click_count = 0;
$('.myelement').bind('click', function(e) {
e.preventDefault();
++click_count;
if (click_count === 4) {
$(this).unbind('click');
}
});
答案 2 :(得分:0)
$('a').click(function(e){
var times = parseInt($(this).data("times"));
if (isNaN(times)) times=0;
times++;
$(this).data("times",times)
console.log('event captured',times);
if (times<5) e.preventDefault(); // change to !=5 to only allow 5th click
else console.log("HURRAH");
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#">A link</a>
&#13;