2017-01-25 3 views
0

У меня есть ссылка на внешний URL. Я хочу архивировать, чтобы не перенаправить ссылку на первые 4 клика, но на пятый щелчок.Как предотвратить поведение по умолчанию для ссылки на клик для первых 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>

+0

число кэша щелчки вне обработчика обратного вызова и вызывать только '' preventDefault' если length' ниже вашего предел –

ответ

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); 

Значение переменной 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); 

}); 

Поскольку это лексического контекста, связанного с текущим DOM Element, когда вы цикл по коллекции JQuery.

Конечно, есть компромиссы, потому что, если у вас огромное количество ссылок, вы просто зацикливаете всю вашу коллекцию и создали для каждого из них закрытие, что довольно дорого (как выбор, так и закрытие). Возможно, вам придется искать событие делегирование.

Если вы хотите получить более утонченное решение, когда вы можете решить, что именно делать вы можете думать о родовой функции обработчика, который хотел бы это:

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 и оператора debounce в библиотеке, например, RxJS (или xstream, most.Js ...).

Существует также работа дроссельной заслонки, на которую вы могли бы обратить внимание (в lodash и Observables).

Запрашивайте, пожалуйста, более подробную информацию.

Вывод: используйте силу запирания JS!

+0

Спасибо за краткое и полное объяснение с кодом Например, это определенно ответ на вопрос! – fuyi

+0

Я заглянул в функцию debounce lodash, я не могу понять, как «возобновить» поведение по умолчанию, в этом случае перейдите к ссылке в хвосте времени debounced – fuyi

+0

Или в вашем последнем фрагменте кода, когда diff> threshold, как я могу заставить поведение события по умолчанию перейти к ссылке? – fuyi

0

Вы можете считать клики, а затем отменить событие. Например:

var click_count = 0; 
$('.myelement').bind('click', function(e) { 
    e.preventDefault(); 
    ++click_count; 

    if (click_count === 4) { 
     $(this).unbind('click'); 
    } 
}); 
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"); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<a href="#">A link</a>

+0

Спасибо, это должно сделать это. Один последующий вопрос тогда, что, если ссылка кликается несколько раз, но я только хочу перейти к ссылке один раз? – fuyi

+0

изменить <5 to! = 5 – mplungjan

+0

Позвольте мне пояснить, что я не хочу перейти к ссылке с пятого щелчка, я хочу определить, если пользователь несколько раз щелкнул ссылку, если это так, перейдите по ссылке один раз после прекращения использования нажмите – fuyi

Смежные вопросы