简体   繁体   中英

Run function when element enters to viewport with getBoundingClientRect or intersection observer

i'm trying to run a function called txtAnim when the element.txt-anim enters to the viewport and want to use getBoundingClientRect or intersection observer

Is that possible? I didn't get it working

(I have the animation working but i want it fired when it enters to the viewport)

 function txtAnim(speed){ jQuery('.txt-anim').css("opacity", "1"); var skills = jQuery('.txt-anim p').contents().filter(function() { return this.nodeType === 3; // only immediate text in div, not in span }).map(function() { var txt = "<span class='letter'>" + jQuery(this).text().split("").join("</span><span class='letter'>") + "</span>"; // console.log(txt); jQuery(this).replaceWith(txt); }); var i = 0; var span = jQuery('.txt-anim').find('span'); jQuery(".txt-anim p").empty(); typeWriter(); function typeWriter() { if (i < span.length) { jQuery('.txt-anim p').append(span[i]); i++; setTimeout(typeWriter, speed); }else{ console.log("text animation ended"); jQuery('.home-page-cities-mobile').css("opacity", "1"); jQuery('.flecha-home').css("opacity", "1"); } } } //Intersection Observer const textAnim = document.querySelector('.txt-anim'); let options = { root: textAnim, rootMargin: "0px", threshold: 1.0 }; let observer = new IntersectionObserver(txtAnim(20), options); observer.observe(textAnim);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="logo-message txt-anim"> <p> <span class="letter">L</span> <span class="letter">i</span> <span class="letter">q</span> <span class="letter">u</span> <span class="letter">i</span> <span class="letter">d</span> <span class="letter empty"> </span> <span class="letter">i</span> <span class="letter">d</span> <span class="letter">e</span> <span class="letter">a</span> <span class="letter">s</span> <span class="letter empty"> </span> <span class="letter">t</span> <span class="letter">o</span> <span class="letter empty"> </span> <span class="letter">g</span> <span class="letter">e</span> <span class="letter">t</span> <span class="letter empty"> </span> <span class="letter">a</span> <span class="letter">n</span> <span class="letter">y</span> <span class="letter">w</span> <span class="letter">h</span> <span class="letter">e</span> <span class="letter">r</span> <span class="letter">e</span> </p> </div>

Can anyone help? I've tried with intersection observer beucase i thought it would be easier

OK, so there's a couple problems with the way you're using intersection observer here.

First, your root is wrong. You're using the same element for root as you're trying to observe, which means you're asking the question, When does this element intersect with itself? which is obviously not a very useful question.

If you want it to show when you've scrolled to it in the viewport, you actually don't need to specify a root at all.

Secondly, you're not checking the thing you really need to check: the isIntersecting property. When the intersection observer callback fires, the first argument is an array of entries , and each entry has an isIntersecting property which can be true or false.

I've made this jsfiddle that maybe comes close to doing what you want.

https://jsfiddle.net/xapjz2fe/

As you can see, i've also added in a check to make sure the function txtAnim doesn't run itself more than once -- without that check, if you scrolled to the element, then scrolled away and scrolled back, txtAnim would run a second time and it would mess everything up.

 let txtAnimStarted = false; function txtAnim(speed){ if (txtAnimStarted) return; txtAnimStarted = true; console.log('starting txtAnim'); jQuery('.txt-anim').css("opacity", "1"); var skills = jQuery('.txt-anim p').contents().filter(function() { return this.nodeType === 3; // only immediate text in div, not in span }).map(function() { var txt = "<span class='letter'>" + jQuery(this).text().split("").join("</span><span class='letter'>") + "</span>"; // console.log(txt); jQuery(this).replaceWith(txt); }); var i = 0; var span = jQuery('.txt-anim').find('span'); jQuery(".txt-anim p").empty(); typeWriter(); function typeWriter() { if (i < span.length) { jQuery('.txt-anim p').append(span[i]); i++; setTimeout(typeWriter, speed); }else{ console.log("text animation ended"); jQuery('.home-page-cities-mobile').css("opacity", "1"); jQuery('.flecha-home').css("opacity", "1"); } } } //Intersection Observer const textAnim = document.querySelector('.txt-anim'); let options = { rootMargin: "0px", threshold: 1.0 }; let observer = new IntersectionObserver((entries) => { const entry = entries[0]; if (entry.isIntersecting) txtAnim(20); }, options); observer.observe(textAnim);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div style="margin-bottom:1000px">top div, scroll down</div> <div class="logo-message txt-anim" style="padding-bottom:20px"> <p> <span class="letter">L</span> <span class="letter">i</span> <span class="letter">q</span> <span class="letter">u</span> <span class="letter">i</span> <span class="letter">d</span> <span class="letter empty"> </span> <span class="letter">i</span> <span class="letter">d</span> <span class="letter">e</span> <span class="letter">a</span> <span class="letter">s</span> <span class="letter empty"> </span> <span class="letter">t</span> <span class="letter">o</span> <span class="letter empty"> </span> <span class="letter">g</span> <span class="letter">e</span> <span class="letter">t</span> <span class="letter empty"> </span> <span class="letter">a</span> <span class="letter">n</span> <span class="letter">y</span> <span class="letter">w</span> <span class="letter">h</span> <span class="letter">e</span> <span class="letter">r</span> <span class="letter">e</span> </p> </div>

My indentation of the javascript got ruined copying over from jsfiddle, sorry about that

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM