Search code examples
jquerytimeoutdelay

How to change element text in jQuery, pause, and reset original text


The HTML:

<a href="#" class="change">Old Text</a>
<a href="#" class="change">Old Text</a>

I want to change the "Text" with jQuery, delay two seconds and set it back to the original. I've tried timeout and delay unsuccessfully. The page has multipe items that have the same text "Add to cart", and switch to "Added", then back again.

The jQuery:

$('.change').html('first').delay(2000).html('second')

This fails. It ignores the first, and skips right to the second

_x = $(this);
$(_x).html('New Text');
_t = setTimeout(function(){
    $(_x).html('Old Text');
},2000);

This works, if the user clicks and doesn't trigger another before the 2 second reset. If someone clicks #1 and then clicks #2 before #1 has the text reset, it works on #2 but the text on #1 stays with the New Text.

I thought that since it's inside a function, that the timeout would be instantiated for each object with it's own instance of _t, but apparently not.

I'm not sure if it matters, but the elements are sometimes loaded dynamically, and the click binding is set accordingly

$(element).on('click','.change',function(_e) { ...

How can I handle this? Thank you in advance.


Solution

  • UPDATE [March 04, 2017]

    In response to Wim Mertens comment:

    Unfortunately this doesn't work when you double click ...

    You could tweak the code to handle both click and dblclick events and return the same expected behavior.

    Based on this answer you could do:

    var
      DELAY = 700,
      clicks = 0,
      timer = null,
      restoreText = function(target, oldText, newText) {
        target.html(newText); // set new text
        setTimeout(function() {
          target.html(oldText); // restore old text after n seconds
        }, 2000);
      }
    
    $(".change").on("click", function(e) {
      clicks++; //count clicks
      var that = $(this); // $(".change")
      if (clicks === 1) {
        timer = setTimeout(function() {
          // set new text and restore old one after n seconds
          // parameters : target, oldText, newText 
          restoreText(that, that.html(), "new text")
          clicks = 0; //after action performed, reset counter
        }, DELAY);
        return false
      }
      // double click otherwise
      clearTimeout(timer); //prevent single-click action
      // set new text and restore old one after n seconds
      // parameters : target, oldText, newText 
      restoreText(that, that.html(), "new text")
      clicks = 0; //after action performed, reset counter
    }).on("dblclick", function(e) {
      e.preventDefault(); //cancel system double-click event
    });
    

    See updated JSFIDDLE


    [Original answer]

    Try

    // add a refresh button to image previews
    $(".change").on("click", function () {
        var oldText = $(this).html();
        var that = $(this)
        $(this).html("new text");
        setTimeout(function () {
            that.html(oldText);
        }, 2000);
    });
    

    See JSFIDDLE

    NOTE: if the elements to click are dynamically created, then try .on() in its delegated form like :

    $(".parentSelector").on("click", ".change", function () {
        // handler
    });