Stop function after start after start

I have this function

function toDiv() {
$(".wrap"))) 

    $('.barfill').each(function(){
        var width=$(this).data('width');
        $(this).animate({ width: width }, 500);
        var $perctext = $('<div>', {'class': 'perctext', text: width});
        $perctext.appendTo(this);
        $perctext.delay(500).each(function(a) {
            $(this).delay(a * 250).animate({
            'left': width
        }, 1000);
    });
}); 
else {}
}

, which is launched after the appearance of an element in the panel using this.

function toView(elem) {
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();
    var elemTop = $(elem).offset().top;
    var elemBottom = elemTop + $(elem).height();
    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}

I want it to execute ONCE , and when the item is again in the panel, the function will not start again.

I applied .one () to the parent function, so it runs only once, but didn't complete the trick .

You can check the Fiddle Demo to clarify the problem.



Note. I updated this question for clarity, as it seems to have created some misunderstandings.

+4
source share
3

.unbind(), :

$(window).scroll(toDiv);

function toView(elem) {
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();
    var elemTop = $(elem).offset().top;
    var elemBottom = elemTop + $(elem).height();
    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}

function toDiv() {

    if (toView(
    $(".wrap"))) {
        $('.barfill').each(function () {
            var width = $(this).data('width');
            $(this).animate({
                width: width
            }, 500);
            var $perctext = $('<div>', {
                'class': 'perctext',
                text: width
            });
            $perctext.appendTo(this);
            $perctext.delay(500).each(function (a) {
                $(this).delay(a * 250).animate({
                    'left': width
                }, 1000);
            });
        });
      $(window).unbind('scroll');
    }
}

JSFiddle

+5
function highlander(fn) {
  return function() [
    if (fn) {
      fn.apply(this, arguments);
      fn = null;
    }
  }
}

var printHello = highlander(function() {
  console.log('Hello');
});

printHello();
printHello();
printHello();
// will print hello only once!
+1

Your solution should be found simply in the original counter principle.

// define a counter
var counter = 0;
$(window).scroll(toDiv);
function toView(elem) {
    //check the counter value
    if (counter > 0) return false;      
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();
    var elemTop = $(elem).offset().top;
    var elemBottom = elemTop + $(elem).height();    
    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));

}
function toDiv() {
    if (toView(
        $(".wrap"))) 

        $('.barfill').each(function(){
            // increase the counter value
            counter++;
            var width=$(this).data('width');
            $(this).animate({ width: width }, 500);
            var $perctext = $('<div>', {'class': 'perctext', text: width});
            $perctext.appendTo(this);
            $perctext.delay(500).each(function(a) {
                $(this).delay(a * 250).animate({
                    'left': width
                }, 1000);
            });
        });

    else {

         }

}

Checkout DEMO

0
source

Source: https://habr.com/ru/post/1535195/


All Articles