Get fixed position based on underlying div if still exists - javascript

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.

Related

JavaScript setTimeout causes a scrollTop Event?

I have a collection of divs in a document that can be filtered by classname, as in hiding and showing elements. The list can be filtered by clicking either a corresponding element in the list or one of the items in the top menu.
I made this pen to illustrate my problem.
I call the filter function for each click event, which hide all elements, and after using window.setTimeout() I display the right ones like below. This is to get a delay as well as to trigger fade-in css3-animations.
var filter = function(el){
if(filterClass==='all'){
window.setTimeout(function(){
$('.project').show(); //show all projects
$('#filter-all').addClass('active');
}, 100);
}
else{
window.setTimeout(function(){
$('.'+filterClass).show(); //show filtered projects
$('#back2').show();
$('#'+elClassName).addClass('active');
}, 100);
}
};
The problem is that when I use window.setTimeout() the view scrolls up to the top, even if the view is in the bottom of the page.
Try this in the pen:
Show all
Scroll down to the bottom so that the top of the document is not visible in the view.
Filter by clicking some div.
Result:
It gets filtered correctly, but the view always scrolls/jumps up to the top.
Why is this happening?
I expected it to stay in the same relative scroll view when possible and otherwise end up at the bottom of the scrollbar. This is to me the standard and desired behavior.
The page scrolls top because you hide elements. So there is no more downward scrollable area. If you had 1000 items and you filtered 999 and show only 1, then what would you expect? The scrollable area would be way too short.
For your case, I would remove
$(".project").hide()
And hide non-matching items only:
else{
window.setTimeout(function(){
$('.'+filterClass).show();
$(".project:not(" + '.' + filterClass + ')').hide();
$('#back2').show();
$('#'+elClassName).addClass('active');
}, 100);
}
Not a perfect solution because there would be some scroll top. But in most cases, it would be less.

Scrolling to bottom elements of a page

I have prepared a pretty self-explaining jsfiddle:
http://jsfiddle.net/nt7xzxur/ with the following scrolling code inside:
function smoothScroll(hash) {
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 750);
When you click on one of the links available, the browser's window is scrolled to the point where the corresponding item on the right side is located. There's one thing I would like to achieve though:
Obviously last two items won't scroll up to the top because there's not enough content below them for scrolling. I would like for ALL items to be scrollable to the top and so far I haven't found a good way to do it. I could add some blank lines below the last item, but it adds length to the right scroll bar and is not very elegant.
Is there any other way to make it happen through css, js or otherwise?
You can dynamically calculate the extra space and add this to end of the page. I have created one small code you can look at it and use it according to your need http://jsbin.com/mubugusido/6/edit?html,js
This will add extra space at the bottom of your .main div:
wH = $(window).height();
$extraH = $('<div></div>').height(wH);
$('.main').append($extraH);
Or you could add a min-height to .main and set it to some amount to guarantee there's enough space.
I believe that the only way you can achieve this is to actually add some content at the bottom.
You cannot get the page to scroll to the top of the Fifth Item because there isn't anything below to display, because the page has ended.

Maintaining scroll position after height of body is changed

I am working on a page that has two states: edit mode and normal mode. The user switches between these states by clicking on a toggle button. Triggering edit mode adds more elements to the page (buttons, etc) and thus forces the body element to increase its height.
My issue arises when a user has scrolled down the page and then triggers edit mode - since the page's height has now increased, their current scroll position is lost. I have been trying to find a way through which I can calculate what the new scrollTop should be, but have not been successful.
I've got a jsFiddle as an example of my issue. It automatically scrolls to the third "entry", to simulate a user having scrolled down that far. Clicking the "trigger change" button in the top right hand corner will add more elements to the page, and the scroll position of having the third entry at the top of the page is lost.
I am aware that I could just redo $('body').scrollTop($('.entry:nth-child(3)').offset().top); after the new contents have been added, but I want the scroll position to be remembered for no matter where the user has scrolled to on the page.
http://jsfiddle.net/Jn8wq/2/
Any help is greatly appreciated!
Check this fiddle.
http://jsfiddle.net/Jn8wq/4/
I added this
var tempScrollTop = $(window).scrollTop();
//your append logic
$(window).scrollTop(tempScrollTop+9);
You would notice that I added '9' to the scroll position. It suits your requirement in the given fiddle. But when you implement this on your actual site, you would have to calculate the height of new appended divs dynamically and add that height instead of '9'.
To keep an element where it is in the window after something changes above it, try this:
var tmp = $('#element').offset().top - $(document).scrollTop();
// add stuff
$(document).scrollTop($('#element').offset().top - tmp);

jquery animating an object to the top layer of the page

So I have an interesting problem. I currently have a grid of four block elements, and I would like to enable some behavior to cause the div to grow when clicked on. The catch is, I am trying to animate it to the top level of the page, aka, I don't want it to dislocate the position of the other divs on the page.
It's difficult to explain, but I want it to kind of be like a modal window with the open animation originating from the element's location. Like a popup when it's clicked. Right now I am trying to do this in the click function:
$( "#cell" ).animate({
height:600, width:600, position:'fixed'
}, 1000, "linear", function(){ alert("all done"); });
This animates it bigger, but I was hoping to make it like an overlay. Has anyone seen anything like this, or a plugin that accomplishes this before?
Clone the element, absolutely position it over the original and animate the copy.
Press "Add to cart" and see this in action:
http://toys.scholarschoice.ca/products/Active-Play-536/12-Years-Old-Up-563/RipStik-Caster-Board-Silver-p46490/pstart1/
I tried to implement the idea of cloning and animate the clone..
See my DEMO

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

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
});

Categories

Resources