I got a scrollable page containing a lot of divs. I want to fade out the elements at the top and bottom of the page while the user is scrolling; so only the divs which are currently in the center of the viewport will have an opacity of 100%.
I am currently achieving this by observing the window.scroll event and calculating each divs opacity by their position in relation to the scroll offsets. This works, but has an huge impact on the clients performance (specially when there are a lot of divs) - which leads to a "non fluid" scrolling experience.
Are there other approaches available? Maybe even a solution without going through every single div?
Edit:
I setup a quick preview on jsFiddle, which illustrates my current approach (not optimized)
Thanks for you comments! I really like the idea of using a background gradient to fake the elements opacity - but in my case this won't work, because I got an background image.
Example on jsFiddle
// http://stackoverflow.com/a/488073/340760
function isScrolledIntoView(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));
}
// when you scroll the div
$(".list").scroll(function(e) {
var $list = $(this);
// apply logic only to visible elements
$list.find("div")
.filter(function(i, d) {
return isScrolledIntoView(d);
})
.each(function() {
var eTop = $(this).offset().top;
var center = $list.height() / 2;
// if the element is in the center it is 100%
// otherwise it will fade
var dif = center - eTop;
if (dif < 0) dif *= -1;
var pc = 1 - (dif / center);
// set the opacity for the elements
$(this).css("opacity", pc);
});
});
Related
I was quite happy with my jQuery-solution until I noticed that scrolling is not working properly on chrome, on some cell phones and tablets. That is, scrolling is jumpy and the hashes occur in an ambiguous and irritating way. I am using wordpress + Slider Revolution 6.
So these are my functions:
when an id is in the viewport, its button gets a class (underline).
when an id is in the viewport, the url gets extended with the id's name (#id)
additionally, not shown here and part of the Slider Revolution 6, I use "menu-link+scroll to id"
So, the code below looks comprehensible and simple to me. But I cannot figure out why chrome on some phones and tablets makes the above mentioned problems. I have tried to clear caches everywhere.
function isScrolledIntoView(elem) {
var docViewTop = jQuery(window).scrollTop();
var docViewBottom = docViewTop + jQuery(window).height();
var elemTop = jQuery(elem).offset().top;
var elemBottom = elemTop + jQuery(elem).height();
return (docViewBottom >= elemTop && docViewTop <= elemBottom);
}
jQuery(window).scroll(function() {
element = jQuery('#first');
if (isScrolledIntoView(element) === true) {
jQuery('#first-btn').addClass('underline');
history.replaceState(null,null,'#first');//or pushState?
} else {
jQuery('#first-btn').removeClass('underline');
}
element = jQuery('#second');
if (isScrolledIntoView(element) === true) {
jQuery('#second-btn').addClass('underline');
history.replaceState(null,null,'#second');//or pushState?
} else {
jQuery('#second-btn').removeClass('underline');
}
});
Any help very much appreciated!
Best regards,
Skt
I have 3 blocks about halfway down the page that the client wants to appear in an upward transition when the user scrolls down to it. I've been looking into transition on scroll effects all morning and most of what I've found are parallax pages and headers.
<ul class="testimoniallist">
<li>
stuff
</li>
<li>
more stuff
</li>
<li>
Other stuff
</li>
User goes to the website
User scrolls down to the section with that UL and the three list items
The three list items then appear to transition up
Just for testing purposes, I created a jsfiddle here: http://jsfiddle.net/odyq4rc7/
I gave the ul class a margin top of 1600px so when the user scrolls down to it, how could I bump that up 100px when it comes into viewport view?
On scroll, you could check if the element has come into view, and set its properties accordingly, using something like this to check if its in the viewport:
function isScrolledIntoView( element ) {
var elementTop = element.getBoundingClientRect().top,
elementBottom = element.getBoundingClientRect().bottom;
return elementTop >= 0 && elementBottom <= window.innerHeight;
}
I solved it with the following: (I found this courtesy of this jsfiddle: http://jsfiddle.net/vVaat/76/)
function isScrolledIntoView(elem) {
var $window = $(window),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $(elem).offset().top,
elemBottom = elemTop + $(elem).outerHeight();
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}
$(window).on("scroll", function() {
$('.testimoniallist').each(function() {
if (isScrolledIntoView(this)) {
$(this).addClass('yes');
} else {
$(this).removeClass('yes');
}
});
});
I have some problem.
I write html code where have about 100 div.
<?php
for ($i=0;$i<100;$i++)
{
$post_block = '
<div id="1_%s" class="simple_wall_post" data-foo="bar_%s">
</div>';
$s = sprintf($post_block,$i,$i);
}
?>
windowsHeight = 10000 px
1 div element height = 100 px
For example facebook autoplay video, if video visible then played, if no stopped.
I can't get current div-foo when visible on window.
how can I implement it? thank you.
Did you try to determine the scrolling of the page, as suggested here: Check if element is visible after scrolling
Like this:
function isScrolledIntoView(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 have some divs, I need to trigger an action (float another div or fire an alert for example) when a certain div is viewed or scrolled to.. What is the best approach to do so?
What you mean by "viewed" I have no idea - but here is how you would do it when the user puts their mouse over the div:
function isScrolledIntoView(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));
}
$(window).scroll(function() {
if(isScrolledIntoView(myelement)) {
// in view
} else {
// not in view
}
});
Credit to Is there a way to detect when an HTML element is hidden from view?
You can probably use the Bullseye jQuery plugin which adds adds enterviewport and leaveviewport events to elements.
I'm trying to create a messagebox that is fixed to the bottom of a webpage, so when a user scrolls, it stays put (simple css).
However, I'd like the messagebox to disappear when the user scrolls to a certain point in the webpage.
For example, if you have a signup form on the bottom of your site, I'd like to create a messagebox that reads "scroll down to signup", and when the user scrolled down to the top of the sign up form, the message would disappear, or get covered up by the form.
So when they scrolled up, the message would reappear.
This isn't my implementation, but an accurate illustration of the concept.
I haven't any experience developing with Javascript, but was hoping there was an existing method for this. I'm willing to learn though, this is something I'd like to use.
Any thoughts? Or concepts to start learning?
Thanks guys! (I think this could be a really clever method of highlighting certain content that perhaps users would miss if they didn't scroll through the entire page.)
This should do the trick (tested in IE7, Firefox, Chrome, Safari).
It uses jQuery and shows the element as soon as it is visible. This is the code:
$(document).ready(function() {
function isScrolledIntoView(elem) {
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom >= docViewTop) && (elemTop <= docViewBottom));
}
// the element to look for
var myelement = $('#formcontainer');
// the element to hide when the above is visible
var mymessage = $('#mymessage');
$(window).scroll(function() {
if(isScrolledIntoView(myelement)) {
mymessage.hide();
} else {
mymessage.show();
}
});
});
If you want the whole element to be visible before the message is hidden, replace the isScrolledIntoView above with this:
function isScrolledIntoView(elem) {
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + $(window).height();
var elemTop = $(elem).offset().top;
var elemBottom = elemTop + $(elem).height();
return ((elemBottom >= docViewTop) && (elemTop <= docViewBottom)
&& (elemBottom <= docViewBottom) && (elemTop >= docViewTop) );
}
Credit for both of these functions go to this question.