2017-06-25 2 views
1

Nach dem Blättern der Seite zu einem bestimmten Element muss ich eine Klasse zu diesem Element hinzufügen. Problem ist, das falsche Element erhält die Klasse, weil die komplette Funktion vor Beendigung der Scroll-Animation ausgelöst wird. Ich weiß, denn wenn ich die komplette Funktion in eine setTimeout() wrap es funktioniert.jQuery animate() 's komplette Funktion wird vor der Fertigstellung ausgelöst

Warum sollte die komplette Funktion vor der Fertigstellung ausgelöst werden? Ist es ein bekanntes Problem? Was ist der zuverlässigste Weg, um dieses Problem zu lösen?

Mein Code:

$('html, body').animate({ 
    scrollTop: current_element_position + 'px' 
}, 'fast', function(){ 
    current_element.addClass('current_element'); 
}); 
+1

Sie schrieb schnell Argument für belebtes Funktion. Es gibt hier drei Optionen: schnell, mittel und langsam. So hat jeder Zeit, um den Effekt zu vervollständigen. JavaScript ist jedoch asynchron, sodass es nicht darauf wartet, dass eine Aktion abgeschlossen wird, um die nächste zu starten. Wenn eine Aktion länger als die Ausführungszeit dauert, wird der nächste Code ausgeführt. –

+1

Wenn das, was Sie sagen, richtig ist, warum haben sie die vollständige Funktion "complete" auf http://api.jquery.com/animate/ aufgerufen? Wenn es Fälle gibt, in denen die Funktion vor der eigentlichen Fertigstellung ausgelöst wird, scheint der Begriff für mich ziemlich irreführend zu sein. – drake035

+0

Sie haben meinen Freund korrekt. Aber Sie müssen darüber nachdenken, und wie Sie sagten, wäre eine Zeitüberschreitung hilfreich für Sie. –

Antwort

2

Sie den Animationseffekt auf zwei Elemente aufrufen: html und body. Dies bedeutet, dass die Animation tatsächlich zweimal ausgeführt wird und die vollständige Funktion auch zweimal aufgerufen wird.

Der Grund, warum dies normalerweise getan wird, ist, weil einige Browser nur Scrolling html unterstützen und andere nur Scrolling body unterstützen. Dieser Selektor zielt auf beide, was das Problem löst, aber auch diesen doppelten Animationsaufruf verursacht.

Die Animation, die nicht tatsächlich scrollt, wird viel schneller abgeschlossen und löst daher den vollständigen Aufruf aus, bevor die echte Animation auf dem anderen Element ausgeführt wird.

Sie können dies umgehen, indem Sie eine zusätzliche Variable festlegen, damit Ihr Code nur beim letzten Aufruf ausgeführt wird.

var isComplete = false; 
$('html, body').animate({ 
    scrollTop: current_element_position + 'px' 
}, 'fast', function() { 
    if (isComplete) { 
    current_element.addClass('current_element'); 
    isComplete = false; 
    } 
    else { 
    isComplete = true; 
    } 
}); 

Oder noch einfacher, verspricht Verwendung.

$('html, body') 
    .animate({ scrollTop: current_element_position + 'px' }, 'fast') 
    .promise() 
    .then(function() { 
    current_element.addClass('current_element'); 
    }); 
0

Ich weiß nicht, wie Sie Ihre HTML aussieht. Nichtsdestotrotz hoffe ich, dass ich deine Absicht habe und versuche einen anderen Ansatz ohne jQuery und Animationen. Es prüft im Grunde, ob das obere Ende eines Elements innerhalb eines bestimmten Bereichs liegt, während die Seite gescrollt wird. Vielleicht hilft es ...

var divs = document.querySelectorAll('.testdiv'); 
 
window.onscroll = function() { 
 
    divs.forEach(function(item) { 
 
    var top = item.getBoundingClientRect().top; 
 
    item.style.background = 'transparent'; 
 
    if (top >= 70 && top <= 140) { 
 
     item.style.background = 'red'; 
 
    } 
 
    }); 
 
}
.testdiv{ 
 
    width: 200px; 
 
    height: 70px; 
 
    border: 1px solid black; 
 
} 
 
.testdiv:first-of-type{ 
 
    margin-top: 100px; 
 
}
<div class="testdiv"></div> 
 
<div class="testdiv"></div> 
 
<div class="testdiv"></div> 
 
<div class="testdiv"></div> 
 
<div class="testdiv"></div> 
 
<div class="testdiv"></div> 
 
<div class="testdiv"></div> 
 
<div class="testdiv"></div> 
 
<div class="testdiv"></div> 
 
<div class="testdiv"></div> 
 
<div class="testdiv"></div> 
 
<div class="testdiv"></div> 
 
<div class="testdiv"></div> 
 
<div class="testdiv"></div> 
 
<div class="testdiv"></div> 
 
<div class="testdiv"></div> 
 
<div class="testdiv"></div>

0

Wenn Sie eine Klasse zu den Elementen hinzufügen möchten, die angezeigt werden, versuchen Sie es unter Code.

$(function() { 
 
    /** 
 
\t jQuery Custom method to find if element is in View 
 
*/ 
 
    $.fn.isInView = function() { 
 
    if (!this.length) return false; 
 
    var rect = this.get(0).getBoundingClientRect(); 
 
    return (
 
     rect.top >= 0 && 
 
     rect.left >= 0 && 
 
     rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && 
 
     rect.right <= (window.innerWidth || document.documentElement.clientWidth) 
 
    ); 
 

 
    }; 
 
    /** 
 
\t Window Scroll Event: 
 
*/ 
 
    $(window).on('scroll', function(e) { 
 
    var $this = $(this); 
 
    /** 
 
     Trigger Custom Event on timeout if Scroll is stopped else clear the timeout 
 
     */ 
 
    clearTimeout($this.data('scrollTimeout')); 
 
    $this.data('scrollTimeout', setTimeout(function() { 
 
     $(window).trigger('scrollStop') 
 
    }, 50, e)); 
 
    }); 
 

 
    /** 
 
     On ScrollStop Loop Through Each Element and check if it is in view, If yes add Class else remove Class 
 
     */ 
 
    $(window).on('scrollStop', function(ev) { 
 
    $('div').each(function() { 
 
     var $div = $(this) 
 
     if ($div.isInView()) { 
 
     $div.addClass('color'); 
 
     } else { 
 
     $div.removeClass('color'); 
 
     } 
 
    }); 
 
    }).trigger('scrollStop'); 
 
});
div { 
 
    width: 100%; 
 
    height: 170px; 
 
    border: 1px solid black; 
 
} 
 

 
.color { 
 
    background: red; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div> 
 
<div></div>

0

** Sie können Fenster Scroll-Eigenschaft ** versuchen, dies sollte es funktionieren. Wenn Sie zu div blättern, dann fügen Sie die Klasse hinzu und wenn Sie wieder nach oben gehen, entfernen Sie die Klasse. Sie können hier überprüfen https://jsfiddle.net/surendra786/qnhw5ov7/

html -- 
<p class="new"></div> 

script --- 

$('document').ready(function(){ 
    var current_element=$('.new'); 
    var current_element_position = $('.new').position().top; 

    $(window).scroll(function() {  
    var scroll = $(window).scrollTop(); 
    current_element.toggleClass('current_element', 
    scroll >= current_element_position 
); 

    }); 
}); 
Verwandte Themen