How to run code just in the first click?

Asked

Viewed 1,678 times

4

I have a list of buttons (<li>):

<li id="1">link 1</li>
<li id="2">link 2</li>
<li id="3">link 3</li>
<li id="4">link 4</li>
<li id="5">link 5</li>

When the user clicks on a link he executes a Ajax and make a request in one PHP file, when you click on another, it makes the same request and so on.

I would like to know how to do when the user clicks on link and only on the first click make the request and if it click again do not make the request anymore.

PS.: When he clicks on any of the links, it executes the event html() that keeps the results in a div that is right next to the <li>

  • How are you currently doing? There are many ways, the question is to choose one that fits well in the rest of your code...

3 answers

6


One way to do this is through $.one. It places an event handler in the set of selected elements, so that the handler will only be called once for each element of the set. Example:

$("li").one("click", function() { 
    alert("click"); 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li id="1">link 1</li>
<li id="2">link 2</li>
<li id="3">link 3</li>
<li id="4">link 4</li>
<li id="5">link 5</li>

Note that if you do this there is no simple way to "reconnect" the event handler if you need to do so for some reason (for example, if the ajax call fails, and you want an individual element of the list to be clicked again). The most you can do is relocate the handler in the future (for what the one does is remove the handler after he is called).

6

Beyond the way that mgibsonbr has already indicated, that allows to make click only once, you may need another variant if you need to store the information in the DOM if it has already been clicked (in addition to not allowing more than 1 time).

You can do it like this, keeping one data-clicado in the element:

$('li').on('click', function (e) {

    var clicado = $(this).data('clicado');

    // se "clicado" tiver valor o click não é mais seguido
    if (clicado) return e.preventDefault();

    // aqui juntas um timestamp ao elemento para saberes que foi clicado e quando
    $(this).data('clicado', new Date().getTime()); 

    $.ajax... // o teu código de ajax aqui...
});

6

Leaving a solution in Vanilla Javascript to attach an event of click in each <li/> present in <ul/> specified where it only fires once.

Example

var ul = document.getElementById("minhaLista");

var items = ul.getElementsByTagName("li");

for (var i = 0; i < items.length; ++i) {
  items[i].addEventListener("click", handler);
}


function handler(e) {

  e.target.removeEventListener(e.type, arguments.callee);

  alert("Teste, uma vez por clique em cada LI!");
}
<ul id="minhaLista">
  <li id="1">link 1</li>
  <li id="2">link 2</li>
  <li id="3">link 3</li>
  <li id="4">link 4</li>
  <li id="5">link 5</li>
</ul>

Explanation

  • Identify the <ul/>:

    var ul = document.getElementById("minhaLista");
    
  • Catch the <li/> within the <ul/>:

    var items = ul.getElementsByTagName("li");
    
  • For every <li/>, attach event click:

    for (var i = 0; i < items.length; ++i) {
        items[i].addEventListener("click", handler);
    }
    
  • Call function in attached event that removes event itself after first use:

    function handler(e) {
    
        // remover evento para não voltar a executar
        e.target.removeEventListener(e.type, arguments.callee);
    
        // código a executar aqui...
        alert("Teste, uma vez por clique em cada LI!");
    }
    
  • 3

    +1 this is basically what the jQuery.one makes, but without jQuery - good for cases where jQuery (and all its KB) is not really necessary.

  • 2

    @mgibsonbr Quite true! And it seems relevant to leave solutions without recourse to jQuery whenever the opportunity arises, [tag:javascript], since Vanilla JS is falling into oblivion...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.