I have a window scroll function that I am trying to dial in. Initially, I attempted to do with with waypoints, but couldn't figure it out.
My issue is my function is firing too early and not in the location I am wanting it to. It fires when the bottom of the screen gets to the main container this is all in, #home-info. The issue I have with this is if someone is scrolling slow they never see the animation. Ideally I want the function to fire when it gets to #info-container, the container with the animated objects in it.
What am I doing wrong that is not allowing this to happen or is there a better way to do this?
Fiddle. See it here
function boxes() {
window.addEventListener("scroll", function(event) {
var top, green, yellow, red;
top = this.scrollY;
green = document.querySelector("#green"),
yellow = document.querySelector("#yellow"),
red = document.querySelector("#red");
if(top > 100){
green.classList.add("green", "active");
yellow.classList.add("yellow", "active");
red.classList.add("red", "active");
}
}, false);
}
setTimeout(boxes,1200);
<div id="home-info">
<div id="home-info-container">
<div id="home-info-container">
<div id="home-info-container-description">
<div id="home-info-container-title">THE <span class="yellow-color sansbold">LEADING</span> PROVIDER FOR<br> DEMOLITION & WRECKING</div>
<div id="home-info-description">The Eslich Wrecking Company has been recognized as a leader in the demolition field for over 60 years. Over that time span, we have gained both the experience and reputation for doing quality work in an expedient, safe and cost efficient manner. Our track record proves that Eslich Wrecking has the people, equipment and know-how to tackle even the most complex situations and the most demanding jobs. This includes the capability to bond any project when necessary and to carry general liability, auto, and pollution insurance up to 10 million.</div>
</div>
</div>
<section id="info">
<article id="info-container">
<a href="projects">
<div id="green" class="box">
<div class="info-box-title">PROJECT AFTER PROJECT</div>
<div class="info-box-description">Over 60 years of accumulated projects.</div>
</div>
</a>
<a href="about">
<div id="yellow" class="box">
<div class="info-box-title">YEARS OF DEMOLITION HISTORY</div>
<div class="info-box-description">Find out about - The Eslich Wrecking Company.</div>
</div>
</a>
<a href="contact">
<div id="red" class="box">
<div class="info-box-title">GET IN TOUCH WITH US</div>
<div class="info-box-description">Contact us for more information.</div>
</div>
</a>
</article>
</section>
</div>
You don't want to hardcode your scrollbar position. The position at which your object becomes visible depends on the height of the view port, but more importantly on how much content you have above the target element.
Define a variable target with something like the following:
var target = $('#info-container').offset().top;
if(top >= target) {
// start animation
}
Also note that scroll top tells you nothing of what is in your view port, if you don't also look at the height of your window. In the condition above, use something like
var top = this.scrollY + $(window).height();
This will give you a condition that evaluates to true as soon as #info-container is scrolled into view. Depending on your needs, you may want your target to also include the $('#info-container').height(), if you want the scroll to start once the entire #info-container is in view.
Related
I have an Angular 8 project, which receives list of products from the server. Since the number of products per user might be very large, I'm making request and displaying to user only first 20 items, but when he reaches the bottom of the container, I'm uploading 20 more items. For scroll detection I'm using infinite-scroll library. Everything worked fine until I've added another library, that autoresizes product title to fit container width. After adding it, scroll started automatically jump to the end of the container (to the latest uploaded item) and because of that it triggers uploading of another bunch of additional items. Before adding autoresize, users were staying on the same place (at the end of the first 20 items).
I have already tried next steps:
Removed infinite-scroll and wrote my own method to detect when user
reaches end of container to upload new items. Result: same behavior
with scroll drop.
Removed fittext library and wrote my own directive to resize text
label. Result: same behavior with scroll jump.
Tried to switch overflow on container to hidden to prevent scroll,
tried to change scrollTop value.
Nothing helps. Scroll is still jumping to the end each time new items are loaded. But when I'm removing autoresize feature - everything works fine, except I don't have autoresize..
Maybe someone had similar issue or have any ideas about how to prevent that scroll jump?
Thanks!
This is my html:
<div class="prizes__wrapper" *ngIf="viewModel.prizes.items.length > 0" infinite-scroll [scrollWindow]="false"
(scrolled)="scrollDown(this.viewModel.prizes, 0)">
<div class="content-wrapper">
<div class="outer__wrapper" *ngFor="let prize of viewModel.prizes.items; let i=index; first as isFirst">
<div class="inner__wrapper">
<div class="prize">
<div class="image-wrapper">
<div class="prize__date">
{{'claim_page_won_title' | translate:(prize.created | date:'mediumDate')}}
</div>
<div class="prize__image" [ngStyle]="{ 'background-image': 'url(' + prize.machineImage + ')' }">
</div>
</div>
<div class="prize-controls">
<div class="title-container">
<p class="title" appTextFit>{{prize.prizeShortName}}</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Styles for container with overflow:
.prizes__wrapper
height: 100%
overflow-y: scroll
scrollbar-width: none
-ms-overflow-style: none
Adding trackBy on ngFor element helped to fix that issue.
<div class="machine" *ngFor="let machine of viewModel.machines; let i = index; trackBy: trackByFn">
I have a parallax scrolling website which works via section ID's. I have animations on each of the sections but only want them to activate when the section is in the viewport. I currently have the following, which doesn't seem to be working. I'm fairly new to jquery/javascript so any help would be appreciated!
function paintLine(){
$('#3-Backup-3').lazylinepainter({
"svgData": svgData,
'ease': 'easeInOutQuad',
'strokeCap': 'square'
}).lazylinepainter('paint');
}
var element_position = $('#backup-section-3').offset().top;
$(window).scroll(function() {
var y_scroll_pos = window.pageYOffset;
var scroll_pos_test = element_position;
if(_scroll_pos > scroll_pos_test) {
paintLine();
}
});
<!-- Backup 3 -->
<div data-anchor="backup-section-3" class="section backup-section-3">
<div class="float-left">
<div id="backup-nav">
<p onclick="openSideNavGreen()" class="nav-section-title">Backup</p>
</div>
<div>
<p class="backup-text-title">Methods</p>
<p class="backup-text">No surprises here then: tape as a primary backup method remains at an all-time low of 3%. This is the first year it hasn’t fallen – possibly indicative of how stubborn some legacy systems (often populated with static compliance data) can be. I wouldn’t be surprised to see similar figures next year.<br><br>We did see a drop in the prevalence of combined disk/tape solutions, with a new option, External Hard Drive/USB, seeming the preferred choice instead.</p>
</div>
</div>
<div class="float-right">
<div id="3-Backup-3"></div>
</div>
</div>
$('#backup-section-3').offset().top; refers to an element with an ID of backup-section-3 which you don't seem to have in your HTML markup. Try giving the element that you're referring to an ID of backup-section-3 and see if that resolves your issue.
id needs the start with alpha character. put any alpha char in front of the 3 in your javascript and html and it will work.
I have 3 elements that show/hide their contents when clicked on.
What I am aiming for: Click on element 1, brings the entire div into view. If I then click on element 2, the second div is brought into view.
What happens currently: Click on element 1, brings the entire div into view. Scroll down a bit and click on element 2, it scrolls back up to display the entire first div instead of the second div.
I believe the issue is that I have .content as the parameter in the scrollTop function but I haven't been able to figure out what I should put in there to address the issue.
My jquery/javascript is here:
$(document).ready(function(){
$(".flippy1").click(function(){
$(this).parent().children(".content").slideToggle(); //toggles the content
setTimeout(function(){
$('body').animate({scrollTop:$('.content').offset().top},200)
}, 200); //delay of 200 ms to let the entire slidetoggle animation finish, then scrolls to the top of the div
});
});
HTML:
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="flippy1">
<h2>Experience</h2>
</div>
<div class="content">
content goes here
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="flippy1">
<h2>Dogs</h2>
</div>
<div class="content">
contents goes here
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="flippy1">
<h2>Cats</h2>
</div>
<div class="content">
more content
</div>
</div>
</div>
</div>
The solution for me has been to use $("html,body") when animating scrollTop property. Some browsers do not play nicely with $("body") alone, although I have no proper explanation for this.
Second problem is you're referencing $(".content") in your timeout function. This animates scrollTop to the first occurrence of .content, not necessarily the clicked occurrence. But, we can do one better:
Third, and not a problem but a better way to handle, is to use the callback function of slideToggle: this function is code that gets executed only after slideToggle finishes. Do this rather than set a timeout. Timeout length is arbitrary, for example in a very old, very slow browser, 200ms may not be long enough duration to wait.
See the updates below:
$(document).ready(function(){
$(".flippy1").click(function(){
$(this).parent().children(".content").slideToggle( function(){
$('body,html').animate({scrollTop: $(this).offset().top},200);
});
});
});
If you want to scroll to the top including the headline, simply grab the parent again and use its offset instead.
This line:
$('body,html').animate({scrollTop: $(this).offset().top},200);
becomes:
$('body,html').animate({scrollTop: $(this).parent().offset().top},200);
Example here: https://jsfiddle.net/nb0fvu3u/
Parent example here: https://jsfiddle.net/nb0fvu3u/1/
When the user scrolldown with the mousewheel, I'd like the page go down untill exactly the begining of the next element. Like :
<section class="One">
...
</section>
<section class="Two">
...
</section>
<section class="Three">
...
</section>
When you enter the website, you'll be at the start page, when you scrolldown 1x, I'd like the page scroll untill the begining of section 2 and so on...
Imagine the sections like, home / about / contact
I tried this, but in this example, I have to write the exactly name of the elements and I would have to write one of this for each section... Is there a different way to do so ?
window.onload=function myScroll() {
x = document.getElementById("chat");
h = x.clientHeight;
x.scrollTop = h;
}
<div id="chat" style="width: 100%; height: 70px; overflow: scroll;
border: 1px solid grey">
This can be quite complicated due to the fact that this involves scrolling, catching the mouse wheel events, delay in animations, cross browser usage, swipe and touch events. Fortunately, there are plugins available to make your life easier. One of the most popular ones is Full Page.
Some of the features include:
Usage over old browsers with no CSS3 support.
Add a live menu.
Slide throw the page using the keyboard arrows.
Add horizontal sliders.
Mobile and Tablet detection enabling the scrolling on them.
Usage:
Each section will be defined with a div containing the section class.
<div class="section">
<div class="slide"> Slide 1 </div>
<div class="slide"> Slide 2 </div>
<div class="slide"> Slide 3 </div>
<div class="slide"> Slide 4 </div>
</div>
All you need to do is call the plugin inside a $(document).ready function:
jQuery:
$(document).ready(function() {
$('#fullpage').fullpage();
});
Demo
I have this JS code:
function overlay() {
el = document.getElementById("overlay");
el.style.visibility = (el.style.visibility == "visible") ? "hidden" : "visible";
}
which opens up a new window on click. What I want it to do next from that first click is go to another function. That function entails a scroller that has 5 divs in it. Say I want it to go to the third div or ID, how would I go about writing that type of function? So a HTML example would be:
<div id="this">
<div class="outer">
<div class="innerdiv">
<div class="1" id="1">1</div>
<div class="2" id="2">2</div>
<div class="3" id="3">3</div>
<div class="4" id="4">4</div>
<div class="5" id="5">5</div>
</div>
</div>
</div>
This would represent my scroller. So on that initial first click, the idea is that it would open up a new window and scroll to that 3rd div, or if scrolling to it is to difficult, then go to that first div. http://jsfiddle.net/qYTK4/
<div class="arrowbox">
<div style="display:inline-block; width:155px; height: 50px; float:left;"></div>
<div class="leftbox" id="leftbox"></div>
<div class="backtohome">BACK TO HOME PAGE</div>
<div class="rightbox" id="rightbox"></div>
Using window.scrollTo() and move it to the objects position. Retrieve the position (X,Y) of an HTML element
jQuery.ScrollTo is a great, simple plugin for smooth scrolling animations. It has tons of options for ways to define the scroll behavior and is pretty easy to use. There are a ton of demos and examples on the site linked you should be able to use. In yours you would just tell it to scroll to either the DOM element itself or jQuery object/selector for the 3rd div.
Also, you can't have id attributes start with numbers (like your divs), it's not valid. Classes can but not IDs.
It is also a good idea to rely on click event handlers (i.e. $('.backtohome a').on('click', function() { // your code });) rather than onclick attributes.