How to know when a user scrolls past a <div>? - javascript

I'm building something where I show users items that they haven't seen.
Each item is in a <div>, so when the user scrolls past a div, or views the div, I want that item to be marked as having been seen.
Google reader does this, if you scroll past an item in your feed there it automatically marks it as read.
How can this be tracked? Advice please.
Note: It shouldn't be restricted to using the mouse to scroll, hitting page down/up, using arrow keys, etc should also be counted. The main criteria is that the user has seen a div.

You need jQuery's scrollTop.
Something like:
$(window).scrollTop() > $('#mydiv').offset().top;
for when it first comes into view, or add $('#mydiv').height() to the top offset if you want it to be marked when it's fully in view.

You could use a solution like this, http://www.appelsiini.net/projects/viewport, which I used in the past.
Or see this for other solutions: Detecting divs as rendered in the window to implement Google-Reader-like auto-mark-as-read?

Have a look at $("#divid").scrollTop().

I think you'll need something like this...
$(window).scroll(function(){
var scroll = $(this).scrollTop();
var vieweditems = $('div').filter(function(){
return scroll> $(this).offset().top;
//compare the div's offset top with the window scroll position
// this returns the collection of viewed divs
})// this object is colleection of viewd divs
.removeClass('hilight')
//Remove the class which distinguishes the unread and read items
.map(function(){
return this.id.split('_')[1];
}).get();
//This is the collection of ids of viewd divs
//vieweditems now holds the ids of viewed divs
});

Related

Correctly scroll down after adding new elements

I write a simple rss reader in JavaScript.
After loading new news items I want to scroll the view down so you can
read the new items.
var new_element = document.createElement('DIV');
new_element.innerHTML = loaded_feed_item_text;
parent.appendChild(new_element);
parent.scrollTop = parent.scrollTopMax;
Problem:
Some news items may contain pictures or other elements of unknown size.
And the elements load at unpredictable times.
So I load new items, scroll down to show them and then pictures load and
the items' height get adjusted and the view is no more scrolled down.
Desired result:
Elements load their subelements and the parent element is scrolled all
the way down to bottom to show the new elements.
I would consider putting a delay on this, as if you're just loading more and more content randomly and then scrolling the user to the bottom every time, they will not be able to read or view the content they want.
window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight); // Scroll to the bottom of the page
Also consider adding a button instead that says something like, "View Latest Posts" and then attach the preceding code to a function and call that.

Get fixed position based on underlying div if still exists

I created a rough idea of the filter I'm creating offline.
Basically the filter or "update row" section shows red, blue or green if available. Can be any combination of results(ie. just blue and green) I have a div that's positioned at the top at all times. So when viewing the blue section it is over that row(fixed to top).
If I select the filter the positioning is lost as you can imagine as sometimes rows will not be present from above or the underlying row may not exist anymore. My question is. How can I get the row name underneath at click then use that to scroll to once everything else is complete. Of course if it's not present then just go to top of table_listing.
success: function(data, textStatus, XMLHttpRequest) {
jQuery('#table_listing').hide().html(data).fadeIn('slow'); // put our list of links into it
$('html, body').animate({
scrollTop: $("#table_listing").offset().top
}, 1000);
I created a working example HERE.
So the idea is to use $(document).scrollTop() to find how much the page is scrolled. Then compare it with the height of the divs to find the one we are on. Then we store it in a variable in a dynamic manner. When user clicks filter button, we know where we have been before, so we can scroll back to that element. Check out the console to see the result. Since scroll() event is only bind to user manual scrolling, it will not be affected by animating of scroll, as you want to have.

Scrolling layout - like facebook or google plus right sidebar

Any idea how make a layout like google plus or facebook. You can see at google plus home as example,
at the beginning, if you scroll the page in the main content, they will scroll together (friend post and sidebar), but when you scroll until the bottom of sidebar (in the right of friend post), that sidebar will stop scrolling , but the another content (friend post) will still scrolling. can explain to me how to make layout like that? sample code or demo will be very help.
Fixed positioning with CSS is a very limited approach. There are a number of ways to do this style of "fixed" areas, many of which have already been given in answers to similar questions on here (try the search above?).
One technique (which many are based on) is like so (in brief)..
Capture the browser's scrolling
Get the position from top of chosen element (x)
Check if the scrolling > x, if so apply a class to the element to fix it to a certain position.
The same will work in reverse, for example:
var target = $('#div-to-stick');
var div_position = target.offset().top;
$(window).scroll(function() {
var y_position = $(window).scrollTop();
if(y_position > div_position) {
target.addClass('fixed');
}
else {
target.removeClass('fixed');
}
}
Note: Depending on how you chose to complete the code above, the page will often "jump" as the div's position is modified. This is not always a (noticeable) problem, but you can consider getting around this by using .before with target.height() and appending a "fake" replacement div with the same height.
Hope this helps.
The new approach with css3 is reduce your effort. use single property to get it.
position:sticky;
here is a article explained it and demo.
article
Demo
You are looking for CSS position:fixed (for the scroll-along sidebar), you can set the location with left:[length], right:[length], top:[length], bottom:[length] and the normal width and height combos
You will need to augment it with a window resize and scroll listener that applies the position:fixed property after the window has scrolled past the top of the sidebar.
Use css property (position:fixed). This will keep the position of the div fixed even if you scroll down or scroll up.

Prepend a div without shifting the contents down? Using iScroll

I've got a container div with a bunch of scrollable content (for the record I'm using iScroll - if that changes the solution). When I scroll to the top I want to load content above the current scroll position. If I simply prepend the div using jQuery "prepend();" the contents in my scrollable area shift down. Ideally we'd want to keep the current content in the frame and have the scrollable area grow upwards above the content.
Any thoughts?
Thanks!
According to the iScroll website, it has a method called scrollToElement:
scrollToElement(el, runtime): scrolls to any element inside the scrolling area. el must be a CSS3 selector. Eg: scrollToElement("#elementID", '400ms')
If you always prepend a fixed amount of divs (e.g. always a single div), I imagine you could use it to scroll to (e.g.) the second element right after you've prepended the new content:
// ... (prepend new content)
myScroll.scrollToElement('#scroller :nth-child(2)', '0ms');
I haven't tried this, so please let us know if this works for you.
After a quick look through iScroll's source, here's what I've found:
The current x and y are always available through myScroll.x and myScroll.y.
iScroll has an internal function _offset(el), which returns the left and top offset of any given element.
This basically opens up two solutions:
Use _offset(el). While possible, this is inadvisable. The underscore is a convention for marking a function "private", meaning, amongst other things, that it's not part of the official API.
or
Use the newly added element's height:
var x = myScroll.x;
var y = myScroll.y;
// ... (prepend new content)
y += $('#scroller :first-child').outerHeight();
myScroll.scrollTo(x, y, '0ms');
You may need to pass true to .outerHeight(), which makes it include margins.
Once again, I haven't tested this, so please let us know if it works.

How to scroll to an element in jQuery?

I have done the following code in JavaScript to put focus on the particular element (branch1 is a element),
document.location.href="#branch1";
But as I am also using jQuery in my web app, so I want to do the above code in jQuery. I have tried but don't know why its not working,
$("#branch1").focus();
The above jquery (focus()) code is not working for div, whereas If i am trying the same code with textbox, then its working,
Please tell me, how can I put focus on a div elemnt using jQuery?
Thanks!
For my problem this code worked, I had to navigate to an anchor tag on page load :
$(window).scrollTop($('a#captchaAnchor').position().top);
For that matter you can use this on any element, not just an anchor tag.
Like #user293153 I only just discovered this question and it didn't seem to be answered correctly.
His answer was best. But you can also animate to the element as well.
$('html, body').animate({ scrollTop: $("#some_element").offset().top }, 500);
You can extend jQuery functionalities like this:
jQuery.fn.extend({
scrollToMe: function () {
var x = jQuery(this).offset().top - 100;
jQuery('html,body').animate({scrollTop: x}, 500);
}});
and then:
$('...').scrollToMe();
easy ;-)
Check jQuery.ScrollTo, I think that's the behavior that you want, check the demo.
Check out jquery-scrollintoview.
ScrollTo is fine, but oftentimes you just want to make sure a UI element is visible, not necessarily at the top. ScrollTo doesn't help you with this. From scrollintoview's README:
How does this plugin solve the user experience issue
This plugin scrolls a particular element into view similar to browser
built-in functionality (DOM's scrollIntoView() function), but works
differently (and arguably more user friendly):
it only scrolls to element when element is actually out of view; if element is in view (anywhere in visible document area), no scrolling
will be performed;
it scrolls using animation effects; when scrolling is performed users know exactly they're not redirected anywhere, but actually see
that they're simply moved somewhere else within the same page (as well
as in which direction they moved);
there's always the smallest amount of scrolling being applied; when element is above the visible document area it will be scrolled to the
top of visible area; when element is below the visible are it will be
scrolled to the bottom of visible area; this is the most consistent
way of scrolling - when scrolling would always be to top it sometimes
couldn't scroll an element to top when it was close to the bottom of
scrollable container (thus scrolling would be unpredictable);
when element's size exceeds the size of visible document area its top-left corner is the one that will be scrolled to;
Use
$(window).scrollTop()
It'll scroll the window to the item.
var scrollPos = $("#branch1").offset().top;
$(window).scrollTop(scrollPos);
If you're simply trying to scroll to the specified element, you can use the scrollIntoView method of the Element.
Here's an example :
$target.get(0).scrollIntoView();
I think you might be looking for an "anchor" given the example you have.
This link will jump to the anchor named jump
<a name="jump">This is where the link will jump to</a>
The focus jQuery method does something different from what you're trying to achieve.
For the focus() function to work on the element the div needs to have a tabindex attribute. This is probably not done by default on this type of element as it is not an input field. You can add a tabindex for example at -1 to prevent users who use tab to focus on it. If you use a positive tabindex users will be able to use tab to focus on the div element.
Here an example: http://jsfiddle.net/klodder/gFPQL/
However tabindex is not supported in Safari.
maybe you want to try this simple one
$(document).ready(function() {
$(".to-branch1").click(function() {
$('html, body').animate({
scrollTop: $("#branch1").offset().top
}, 1500);
});
});

Categories

Resources