2014-04-05 3 views
4

나는 요소가이를 사용하여 창에 표시 한 후 실행이 기능정지 기능은 한 번

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 {} 
} 

있습니다.

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

나는 실행 ONCE에 원하는 요소가 창에있을 때 다시 함수는 다시 실행되지 않습니다. 이 한 번만 실행되도록

나는 부모 함수에 사실 말이다()을 적용하지만 트릭을하지 않았다.

Fiddle Demo에서 문제를 더 명확하게 확인할 수 있습니다.



주 : 몇 가지 오해를 만들 것 같았다 이후 나는 명확하게이 질문을 업데이트했습니다. 이 사용 된 후에는

+2

가 충분히 수용 할 질문에 대한을 downvoted되었다하는 체크 아웃. 상향 조정되었다. – SomeKittens

+0

@ HélioC 반대 원리는 더 간단해야한다고 생각합니다. – SaidbakR

답변

5

사용 .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

+0

수락 및 upvoted. 빠른 질문 : 실행 취소되었는지 확인하기 위해 플래그를 생성하는 것보다 바인딩 해제가 더 나은 방법입니까? 아니면 그것을 달성하기위한 간단하고 청결한 방법일까요? –

+2

@ HélioC 바인딩 해제는 더 나은 습관입니다. 방금 방귀가났습니다. 미안합니다. – SomeKittens

1
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

이것은 OP가 이미 원하지 않는다고 말한'.one()'보다 더 이상 유용하지 않습니다. – jfriend00

+0

@ jfriend00 감사합니다. 원래의 질문은 이것에 대해 아주 분명하지 않았습니다. 업데이트가 실제로 더 명확하게 나타났습니다. –

0

귀하의 솔루션은 단순히 발견해야한다, 원래 카운터 원칙적으로.

// 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 { 

     } 

} 

당신은 보이는 DEMO