i saw a stack question posted already:
[question]: < Text in div - automated scrolling with jQuery - jsFiddle inside >
My question adding to this is, is it possible to have the text in each paragraph or separated divs highlighted (boldness, background color, etc.) once they are in main view, whilst the p's or div's leaving/entering the slider box are faded?
So like the jsfiddle referenced, you have a div container with say 4,5,6,... div's or p's inside of it and one div or p is visible whilst the div or p above and below it, only half would be visible (faded), whilst the remaining overflow is hidden.
thanks.
If I understand you correctly, you're looking for an effect like this:
http://jsfiddle.net/2RRWS/
My code assumes an html structure like:
<div id="scrollContainer">
<p>Some text</p>
<p>More text</p>
...
</div>
And some CSS to set the width/height of the containing div as appropriate. Also it assumes some classes for "dimmed" and "highlighted" paragraphs.
There's probably a cleaner way to do this, but this is just what I cobbled together and it seems to work, so...
var $container = $("#scrollContainer"),
$ps = $container.find("p"),
containerHeight = $container.height(),
contentHeight = 0,
scrollTop = 0;
// figure out the height of the content
$ps.each(function() {
contentHeight += $(this).outerHeight();
});
// add some blank space at the beginning and end of the content so that it can
// scroll in from the bottom
$("<div></div>").css("height", 400).appendTo($container).clone().prependTo($container);
setInterval(function() {
if (paused)
return;
// if we've gone off the end start again
if (scrollTop > contentHeight + containerHeight)
scrollTop = 0;
// scroll up slightly
$container.scrollTop(scrollTop++);
$ps.removeClass("highlighted") // for each paragraph...
.addClass("dimmed") // dim it
.each(function() { // unless it is in view
var $this = $(this),
top = $this.position().top,
height = $this.height();
if (top > 0 && top + height < containerHeight)
$(this).addClass("highlighted").removeClass("dimmed");
});
}, 20);
$container.hover(function() {
paused = true;
}, function() {
paused = false;
});
EDIT: Updated to implement "pause" feature as per comment. http://jsfiddle.net/2RRWS/8/
Related
This question already has answers here:
How to check if element is visible after scrolling?
(46 answers)
Closed 5 years ago.
Function to check if the div class "media" is within the browsers visual viewport regardless of the window scroll position.
<HTML>
<HEAD>
<TITLE>My first HTML document</TITLE>
</HEAD>
<BODY>
<div class="main">
<div class="media"></div>
</div>
</BODY>
</HTML>
Trying to use this plugin https://github.com/customd/jquery-visible with this function but
I don't know how to make it work.
$('#element').visible( true );
You can write a jQuery function like this to determine if an element is in the viewport.
Include this somewhere after jQuery is included:
$.fn.isInViewport = function() {
var elementTop = $(this).offset().top;
var elementBottom = elementTop + $(this).outerHeight();
var viewportTop = $(window).scrollTop();
var viewportBottom = viewportTop + $(window).height();
return elementBottom > viewportTop && elementTop < viewportBottom;
};
Sample usage:
$(window).on('resize scroll', function() {
if ($('#Something').isInViewport()) {
// do something
} else {
// do something else
}
});
Note that this only checks the top and bottom positions of elements, it doesn't check if an element is outside of the viewport horizontally.
Check if element is visible in viewport using jquery:
First determine the top and bottom positions of the element. Then determine the position of the viewport's bottom (relative to the top of your page) by adding the scroll position to the viewport height.
If the bottom position of the viewport is greater than the element's top position AND the top position of the viewport is less than the element's bottom position, the element is in the viewport (at least partially). In simpler terms, when any part of the element is between the top and bottom bounds of your viewport, the element is visible on your screen.
Now you can write an if/else statement, where the if statement only runs when the above condition is met.
The code below executes what was explained above:
// this function runs every time you are scrolling
$(window).scroll(function() {
var top_of_element = $("#element").offset().top;
var bottom_of_element = $("#element").offset().top + $("#element").outerHeight();
var bottom_of_screen = $(window).scrollTop() + $(window).innerHeight();
var top_of_screen = $(window).scrollTop();
if ((bottom_of_screen > top_of_element) && (top_of_screen < bottom_of_element)){
// the element is visible, do something
} else {
// the element is not visible, do something else
}
});
This answer is a summary of what Chris Bier and Andy were discussing below. I also used an answer to the following question to formulate my answer: Show Div when scroll position.
According to the documentation for that plugin, .visible() returns a boolean indicating if the element is visible. So you'd use it like this:
if ($('#element').visible(true)) {
// The element is visible, do something
} else {
// The element is NOT visible, do something else
}
You can see this example.
// Is this element visible onscreen?
var visible = $(#element).visible( detectPartial );
detectPartial :
True : the entire element is visible
false : part of the element is visible
visible is boolean variable which indicates if the element is visible or not.
var visible = $(".media").visible();
I have jquery script where you can click a left and right button and it will scroll horizontally to show more content.
The content that needs to be scrolled are in a div with a width of 1296px, but i want to set my jquery code to automatically get the width of the div and when you press on one of the left or right scroll button it will scroll exactly 1296px.
I want to do it this way because I need to later on optimize the design for all screen size and this would be the easier way.
My code:
var $item2 = $('div.group'), //Cache your DOM selector
visible2 = 1, //Set the number of items that will be visible
index2 = 0, //Starting index
endIndex2 = ( $item.length ); //End index
$('#arrowR').click(function(){
index2++;
$item2.animate({'left':'-=1296px'});
});
$('#arrowL').click(function(){
if(index2 > 0){
index2--;
$item2.animate({'left':'+=18.5%'});
}
});
This Javascript should work:
var $item2 = $('div.group'), //Cache your DOM selector
visible2 = 1, //Set the number of items that will be visible
index2 = 0, //Starting index
endIndex2 = ( $item2.length ); //End index
var w = $("#group").width();
$('#arrowR').click(function(){
index2++;
$item2.animate({'left':'-=' + w + 'px'});
});
$('#arrowL').click(function(){
if(index2 > 0){
index2--;
$item2.animate({'left':'+=' + w + 'px'});
}
});
Check this fiddle. Basically we calculate the width initially to not do the same thing repeatedly and the reuse it whenever we need it.
Why not get the width of the visible container first, and then use that value later? Quick example:
var width = $('container').width();
And then during animations:
var left = $item2.css('left') + width;
$item.animate({'left',left});
As a note, innerWidth and outerWidth may be more beneficial than just width depending on how you've set everything up, so if values aren't quite right take a look at those documents.
I've created a fiddle that I think solves your problem:
http://jsfiddle.net/77bvnw3n/
What I did was to create another variable (called width) which on page load, dynamically gets the width of the container.
var width = $('.group-container').width(); //Container Width
This variable is also reset whenever the Next or Previous buttons are pressed (in case the window has been resized since the page loaded).
$('#arrowR').click(function(){
index2++;
//recheck container width
width = $('.group-container').width();
$item2.animate({'left':'-=' + width + 'px'});
});
Take a look and let me know if it helps.
Note: I replaced the 'Next' and 'Previous' images with coloured boxes in my Fiddle and I think you also had a typo in your code, should
endIndex2 = ( $item.length )
be changed to:
endIndex2 = ( $item2.length )
I am trying to add a class when the bottom of a div reaches the top of the window, but am not sure of how to do it.
I have managed to add the class when the top of the div gets to the top of the window, but am not having much luck with the bottom of the div.
Code I am using:
$(document).ready(function() {
var menuLinksTop = $('.container').offset().top;
var menuLinks = function(){
var scrollTop = $(window).scrollTop();
if (scrollTop > menuLinksTop) {
$('header').addClass('black-links');
} else {
$('header').removeClass('black-links');
}
};
menuLinks();
$(window).scroll(function() {
menuLinks();
});
Any help is appreciated.
You should use javascript's getBoundingClientRect() method, watch $(window).scroll event, and look at element's rectangle, its bottom value will give you what you need (if it's negative, your element is all the way up)
$(window).scroll(function() {
console.log($("div.watch")[0].getBoundingClientRect());
if ($("div.watch")[0].getBoundingClientRect().bottom < 0)
alert ("i'm out :3");
});
see jsFiddle http://jsfiddle.net/ja5nnbwr/2/
Add the height of the div. Assuming it is the .container :
var menuLinksTop = $('.container').offset().top + $('.container').height();
How can I detect an element that is completely (not partially) outside of a specific containers width?
For example, I have the following:
<div id="content">
<div class="wrapper">
<p>This is a paragraph</p>
<p>This is a paragraph</p>
<p>This is a paragraph</p>
<p>This is a paragraph</p>
</div>
</div>
My content div has the width of 100%, and my p tags are animated to scroll across the screen. How can I detect if they are outside of the content div so that I can remove them?
Testing for outside of the viewport is not an option since my content div also has a container.
I believe the getBoundingClientRect() method should work well. Made a better working example using the paragraphs, here's the fiddle.
function HorizontallyBound(parentDiv, childDiv) {
var parentRect = parentDiv.getBoundingClientRect();
var childRect = childDiv.getBoundingClientRect();
return parentRect.left >= childRect.right || parentRect.right <= childRect.left;
}
var bound = HorizontallyBound(document.getElementById("parent"), document.getElementById("some_paragraph"));
Or using jQuery with the same concept:
function HorizontallyBound($parentDiv, $childDiv) {
var parentRect = $parentDiv[0].getBoundingClientRect();
var childRect = $childDiv[0].getBoundingClientRect();
return parentRect.left >= childRect.right || parentRect.right <= childRect.left;
}
var bound = HorizontallyBound($("#parent"), $("#some_paragraph"));
Updated my answer because I reread that you're checking if the child is completely outside of the parent, not partially.
If I understand what you're asking correctly, you could try something I use on one of my own sites:
var $elem = $('#preview_link_box'),
top = $elem.offset().top,
left = $elem.offset().left,
width = $elem.width(),
height = $elem.height();
if (left + width > $(window).width()) {
console.log("Looks like its outside the viewport...");
}
I don't know what you're trying to do, but I tried to create something similar. It's a really simple idea as far as the logic. jsfiddle here
Basically the idea was to use the width of #content div and slide the p elements over until it reached that number and then remove them.
var width = $('.wrapper p:first').width(),
i = 0,
$me = $('.wrapper p');
// slide paragraphs over to the left, once out of bounds they are removed
var interval = setInterval(function() {
if (i == -width) {
clearInterval(interval);
$me.remove();
}
$me.css('margin-left', --i);
}, 10);
Background
I am trying to create an infinite scrolling table inside a fixed position div. The problem is that all the solutions I come across use the window height and document scrollTop to calculate if the user has scrolled to the bottom of the screen.
Problem
I have tried to create a jQuery plugin that can calculate if a user has scrolled to the bottom of a fixed div with overflow: scroll; set.
My approach has been to create a wrapper div (the div with a fixed position and overflow: scroll) that wraps the table, I also place another div at the bottom of the table. I then try calculate if the wrapper.scrollTop() is greater than the bottom div position.top every time the wrapper is scrolled. I then load the new records and append them to the table body.
$.fn.isScrolledTo = function () {
var element = $(this);
var bottom = element.find('.bottom');
$(element).scroll(function () {
if (element.scrollTop() >= bottom.position().top) {
var tableBody = element.find("tbody");
tableBody.append(tableBody.html());
}
});
};
$('.fixed').isScrolledTo();
See Example http://jsfiddle.net/leviputna/v4q3a/
Question
Clearly my current example is not correct. My question is how to I detect when a user has scrolled to the bottom of a fixed div with overflow:scroll set?
Using the bottom element is a bit clunky, I think. Instead, why not use the scrollHeight and height to test once the scrollable area has run out.
$.fn.isScrolledTo = function () {
var element = this,
tableBody = this.find("tbody");
element.scroll(function(){
if( element.scrollTop() >= element[0].scrollHeight-element.height()){
tableBody.append(tableBody.html());
}
});
};
$('.fixed').isScrolledTo();
EDIT (12/30/14):
A DRYer version of the plugin might be much more re-usable:
$.fn.whenScrolledToBottom = function (cback_fxn) {
this.on('scroll',this,function(){
if( ev.data.scrollTop() >= ev.data[0].scrollHeight - ev.data.height()){
return cback_fxn.apply(ev.data, arguments)
}
});
};
Plugin Usage:
var $fixed = $('.fixed'),
$tableBody = $fixed.find("tbody");
$fixed.whenScrolledToBottom(function(){
// Load more data..
$tableBody.append($tableBody.html());
});
I have modified your code to handle the scroll event with a timer threshold:
$.fn.isScrolledTo = function () {
var element = $(this);
var bottom = element.find('.bottom');
$(element).scroll(function(){
if (this.timer) clearTimeout(this.timer);
this.timer=setTimeout(function(){
if( element.scrollTop() >= bottom.position().top){
var tableBody = element.find("tbody");
tableBody.append(tableBody.html());
}
},300);
});
};
$('.fixed').isScrolledTo();
The issue you are having is that as you scroll, new scroll event is being generated. Your code might have other issues, but this is a start.