if target element is visible on screen quasion - javascript

I am using wordpress, and we have there dynamic sidebar. in the sidebar we have many widgets. what am I trying to do is to show the divis (widgets) that visible on the screen (onload - after the page is load). the others widgets will be hidden(opacity 0 or something like that) but when I will scroll I want that widget(that was not visible on screen) will appear in fade effect.
I using this code that hide all my sidebar block is on opacity=0 on load.
I need help to show always all widgets that is visible on screen and then make the fade effect on scroll to others.
$(document).ready(function(){
tiles = $("#sidebar1 div").fadeTo(0, 0);
});
$(window).scroll(function(d,h) {
tiles.each(function(i) {
a = $(this).offset().top + $(this).height();
b = $(window).scrollTop() + $(window).height();
if (a < b) $(this).fadeTo(500,1);
});
});
the function for scrolling is working. the problem is that when the page is full load my sidebar class that hold all widgets is on opacity 0 (like display:none). what I need is when the page load it will give opacity=1 to all widgets that visible on screen (for example 2 of 10 widgets). then when user will scroll it will show others widgets each by other with fade effect.

Extract the block of code that makes these widgets visible and put it in a function. Then add a handler to both scroll and "DOM ready" pointing to this function.
// Determine show or hide
function showOrHide(){$(document).ready(function(){
$("#sidebar1 div").each(function(i) {
var a = $(this).offset().top + $(this).height();
var b = $(window).scrollTop() + $(window).height();
if (a < b) $(this).fadeTo(500,1);
});
}
// Assign to both
$(document).ready(showOrHide);
$(window).scroll(showOrHide);
Now there's a performance penalty here. On scroll fire several times per second. You wouldn't want to query the DOM for these elements and run each on them multiple times a second. For that' I'll leave it to you to search (It's asked frequently on both SO and CodeReview)

Related

Hide a div until scrolled to the bottom of the page

I am making a web page (kind of like those music release pages, here is an example), and I would like certain div's at the bottom not to be shown until the user has scrolled to the bottom of the page, delay a second or two, then pop up. Kind of like a hidden feature thing.
You can also think of it like an infinite scroll, like when you drag down your Instagram feed at the top it refreshes it, and new posts show up. That's the user experience I'm looking for, only in my case it is a "finite scroll", just with some div's hidden by default.
I currently have two implementations of it, neither fully achieves the desired experience. Both used jQuery Slim.
In both implementations, #hidden is the id of my hidden-by-default div, it has style="display: none;" inline, on the div tag.
The first one looks like this:
$(window).scroll(function() {
var x = $(document).height() - $(window).height() - 20;
if( $(window).scrollTop() > x ) {
$("#hidden").delay(1000).show(0);
}
else {
$("#hidden").hide(0);
}
});
The problem with this one is that when the div shows up it changes the document height, so when you get to the bottom of the page it kind of flickers (due to recomputing the document height), and sometimes goes back to being hidden. Really bad user experience.
The second one looks like this:
$(window).scroll(function() {
if( $(window).scrollTop() > 75 ) {
$("#hidden").delay(1000).show(0);
}
else {
$("#hidden").hide(0);
}
});
This one got rid of the flickering problem by keeping the threshold static altogether, slightly better user experience, but not really flexible, in the case that my page gets longer I'll have to set a new threshold for the div to show up.
In neither of the above solutions did the delay(1000) work. The div showed up as soon as the page gets scrolled to the bottom.
Is it possible to make this design work out?
You can try this code:
$(window).on("scroll", function() {
var scrollHeight = $(document).height();
var scrollPosition = $(window).height() + $(window).scrollTop();
if ((scrollHeight - scrollPosition) / scrollHeight === 0) {
$("#hidden").delay(1000).show(0);
}
});

How to show data only when in viewport

I'm planning to use a jQuery plugin called charts.js
for graphs and charts. However, on a larger page, the animations of those graphs get completed even before the user sees them.
My question is, how do we fade in the content of a particular div/section only when it is visible inside the viewport as exactly depicted on charts.js website. The content fades in sequentially as we scroll down and hence even the animations of the graphs aren't missed. How can I achieve this with the help of jQuery?
Take a look at this jsFiddle. The author fades in boxes as they become visible. You porbably need to call chart.js to create the graphs as they become visible, rather than just fade them in (that is if you want the fancy graph animations, rather than just a fade-in :-)) I have tweaked the fiddle and included it below:
$(document).ready(function() {
/* Every time the window is scrolled ... */
$(window).scroll( function(){
/* Check the location of each desired element */
$('.graph').each( function(i){
var bottom_of_object = $(this).position().top + $(this).outerHeight();
var bottom_of_window = $(window).scrollTop() + $(window).height();
/* If the object is completely visible in the window, fade it it */
if( bottom_of_window > bottom_of_object ){
//Code to initialize the graph here.
//This initialization should probably
//be deferred, to ensure performance,
//and the graphs should be marked as
//initialized so we dont't init them
//multiple times (possibly by changing
//their class so .each ignores them).
}
});
});
});
Mika's Viewport Selectors plugin works for the browser window viewport and not html elements. In other words if you got some css like #container{width:350px;height:150px;overflow:auto;} it will not work when scrolling.
I recommend trying his other plugin, Lazy Load
Here's an example: http://jsbin.com/efazos/1/edit
The following code will enable you to determine whether an element is within the window on the scroll of the document. From there you can enable your chart and do whatever animations you like :
<script type="text/javascript">
$(document).ready(function() {
$(document).on('scroll', function() {
//Get Div 1's Top and Left offsets from the Document.
var divTop = $('#div1').offset().top;
var divLeft = $('#div1').offset().left;
//Get the current window height and width.
var winHeight = $(window).height();
var winWidth = $(window).width();
if (divPos <= winHeight && divLeft <= winWidth) {
//Div is visible in window
//Fade in Chart
}
});
});
</script>

Switch tabs based on mouse scroll

I would like to have a widget on a webpage containing a number of tabs. When the user scrolls the page and the widget comes in to view and he keeps scrolling down, the tabs should be activated one by one (without the page scrolling further down). Once the last tab is showing, the page should resume scrolling as usual. Is this doable using JS/jQuery?
UPDATE:
Since this seems too broad a question:
The problem is, I don't know how to use the scroll offset and prevent the page from scrolling down until I decide it can resume its normal behavior
UPDATE 2
I created This fiddle,
$(document).ready(function(){
$('#tabbed').mouseover(function(){
$(this).focus();
}).scroll(function(){
console.log("scrolling tabs");
});
$(window).scroll(function(evt){
var scrollPos = $(this).scrollTop()
console.log(scrollPos);
// BULLETPROOF WAY TO DETECT IF THE MOUSE IS OVER THE
// SCROLLABLE DIV AND GIVE IT FOCUS HERE?
});
});
it contains a long page and a scrollable div among its contents. The only problem is that the div starts catching scroll events only if I move my mouse. If I could find a bulletproof way to activate the scrolling div whenever the mouse is over it I'm there. Any ideas?
You can't prevent scrolling with javascript. Using iframes and divs with scroll will only work if the mouse is over them.
You can cancel the mouse wheel and keys events related to the scrolling, however the user will be able to scroll using the scrollbar (more here).
Another approach is leaving an empty area and fixing your widget inside this area, like in this working example
$(window).bind('scroll', function()
{
var scroll = $(window).scrollTop(),
innerHeight = window.innerHeight || $(window).height(),
fooScroll = $('#fooScroll'),
emptyArea = $('#emptyArea'),
offset = emptyArea.offset(),
fixedClass = 'fixed';
if(scroll > offset.top)
{
if(scroll < offset.top + emptyArea.height() - fooScroll.height())
{
fooScroll.addClass(fixedClass);
fooScroll.css("top", 0);
}
else
{
fooScroll.removeClass(fixedClass);
fooScroll.css("top", emptyArea.height() - fooScroll.height());
}
}
else
{
fooScroll.removeClass(fixedClass);
fooScroll.css("top", 0);
}
});
Then you can change the tabs while the page is scrolling.
You should be able to do this. You can use the jQuery scroll event to run your own code whenever the user scrolls up or down. Also, so long as you call e.preventDefault() whenever the scroll event is fired, you can prevent the whole window from scrolling up or down.

How can I get the element visible in the viewport? jQuery

I have a list of images on a page. As I scroll through the page I would like to show some options in a naviationbar of the image currently in the viewport. Therefore I need to get the image element currently in the viewport, is this possible ?
Jakob
Who says there's just one image in viewport? What would you like to do when there are many?
But otherwise you can always get the scroll position of your container with images as well as your images' top offset to see which one is currently in-view.
So these values will get you to your result
container scroll position
container visible client height
images' top offset
Using these values will make it possible to locate all images in the view regardless whether they're fully or partially displayed (at the top or bottom).
This is a simplified JSFiddle that gives red border around the first fully-in-the-view image. The code does this:
// get top positions and references to all images
var pos = $("img").map(function(){
var $this = $(this);
return {
el: $this,
top: $this.offset().top
};
}).get();
// provide document scrolling
$(document).on("scroll", function() {
$("img").removeClass("first-in-view");
var scroll = $(this).scrollTop();
var i = 0;
while(pos[i].top < scroll) i++;
pos[i].el.addClass("first-in-view");
}).scroll();
This should be optimised to only toggle class when it needs to. Otherwise we have flickering in every scroll. But it demonstrates how this can be done and you can get going from here.
IMPORTANT
It is utterly important that you attach your image position determining process on document load event and not the usually use DOM ready, because you have to wait for the document to load in order for your images to have final positions.

Javascript to detect if item no longer visible due to scrolling

I've got a javascript slideshow at the top of my page. When a slide changes to the next image, I call another function to change the background colour of the page.
The client wants the background colour to stop changing when the slideshow is no longer in view, i.e. when the user has scrolled down the page.
Is there any way to detect if an element is no longer visible due to scrolling?
Test code in jQuery
function test() {
var $elem = $('.test');
var visibleAtTop = $elem.offset().top + $elem.height() >= $(window).scrollTop();
var visibleAtBottom = $elem.offset().top <= $(window).scrollTop() + $(window).height();
if (visibleAtTop && visibleAtBottom) {
alert('visible');
} else {
alert('invisible (at ' + (visibleAtTop ? 'bottom' : 'top') + ')');
}
}
Full working example at http://jsfiddle.net/9PaQc/1/ (Updated: http://jsfiddle.net/9PaQc/2/ )
P.S. This only checks for vertical scroll. For horizontal, just do the same with top replaced with left, Y -> X and height() -> width()
EDIT
Made it all the way jQuery (to ensure x-browser compatibility) by changing window.scrollY -> $(window).scrollTop()
You can use the jQuery $.scrollTop function, probably from a scroll event handler to script this.
Use the window.pageYOffset to determine scroll amount in window. Use current offset of the object to check if it is in view. Note that these values are mostly browser dependent, so first check if it exists then act on it.

Categories