Load scrollable div at bottom - javascript

I'm developing a chat in javascript (angularjs without jQuery), and I would like to know if it's possible to load a scrollable div to the bottom.
I'm aware about the scrollTo js property, but in my case it's not satisfying.
First of all it's not a really good user experience to see the div scrolled to the bottom and furthermore I use onscroll (to top) pagination. So if my div is loaded to his top when triggered a scroll a new page will be loaded.
In outline I would something close to facebook chat windows.
If anybody know how to do that in an elegant way, thanks in advance.
EDIT :
Another constraints is that the chat message are loaded asynchronously, so if I only wait for the DOM to be loaded I scroll to the bottom of my empty div

I'm not sure if this is what you're looking for, but if your chat window is a div with overflow: scroll set (like the FB Chat), wouldn't it work if you set the scrollTop property?
This should set the new scrolling position immediately, so you shold not see any transition.
I created a little CodePen to demonstrate it: http://codepen.io/anon/pen/dpkxl

Why not do:
var yourEl= document.getElementById("yourEl");
yourEl.scrollTop = yourEl.scrollHeight;
And call it every time new content is added to the div (yourEl) in question?

you can use this for scrolling a div to bottom
$("element").animate({scrollTop : $("element").height()},1);

Based Arjun's answer, but using scrollHeight
$("element").animate({scrollTop : $("element")[0].scrollHeight},1);
will scroll to the [non currently visible] bottom of the element (div/ul/...)

Related

Nanoscroller doesn't create a scroll if the content is inserted after the scroller is initiated

I'm using nanoscroller js to create a scrollable area in a div element. The problem is that I'm filling that div element with data with ajax (imagine facebook notifications). First there are 0 notifications, no data. Then I fill it with 10. The scrollbar isn't there. When I refresh the page (with 10 notifications now already there), it creates itself, because it knows there is more content than there is room.
How can I make it create the scroller when the data is filled?
Reinitialize the nanoScroller $("your scrollable").nanoScroller(); after you inserted the content...
like
$("your content div").append("something");
$("your scrollable container").nanoScroller();
#Jonatas Answer didn't work with me, then I figured out this one
$("#my_scrollable_container")[0].nanoscroller.reset();
I had a similar problem. My nano div originally fills the width of the screen and the amount of content does not require a scrollbar. But then a user action causes a second div to appear on the right side, making the nano div skinner and too small to display all the content -- but the scrollbar didn't appear (although I could still use the mouse wheel to scroll the nano content).
Neither of the answers provided worked for me, or maybe I applied them incorrectly. So I looked in the jquery.nanoscroller.js code (which I guess is what I should have done in the first place) and found the call is just:
$(".nano").nanoScroller();
No need to reference the div ID or anything. Each time the size of your nano div is changed, make this call and the nano scrollbar should adjust to fit. And if you have multiple nano divs in the page, this one call will reset all of them.
beware of use such a kinda :
$(".nano").nanoScroller();
cause if U have a lot of .nano DIV's and U Ajaxing data to ONE of them,
better use for example:
$("#FaceBookAjaxNotifi .nano").nanoScroller();
as Jonatas wrote..
(it boost performance dramatically in some situations)

Javascript or Jquery: Scroll to Fixed position div

I want a html div which will scroll when user scroll down the page and it will get to fixed position when it's parent tag ends. For example:- See this link http://www.9gag.com/ they have alot to posts on one page. When we scroll one post and go to end of the first post, the title and share buttons become to fixed position and then the second post do the same and same for the next posts. Just exactly like that. How can we do this in Jquery or raw javascript or in css.
Maybe you want to try this plugin: http://labs.anthonygarand.com/sticky/ Sticky is a jQuery plugin that gives you the ability to
make any element on your page always stay visible by making the element to be floated when they has reached the limit.
$(window).scrollTop() will give you the number of pixels scrolled down in the browser, $('postcontainer').offset() will give you the x,y positions of a post container.
So if you bind an event to $(window).scroll() or to the mousescroll, you can check if the postcontainer's offset().top is less than the window.scrollTop. If it is then you start moving the item down relative to the post container. When doing this you need to keep track of the post container's height and the moving element's height to make sure it doesn't go down past the bottom of the container.
So if postcontainer.height - movingelement.position().top >= movingelement.height() then you need to fix the position of the moving element. Do the opposite while scrolling back up.
Hopefully this will get you thinking and starting to kick out some code.
This is the solution for your problem with a simple css property.
use position:sticky to follows the scroll.
Here is the article explained.
http://updates.html5rocks.com/2012/08/Stick-your-landings-position-sticky-lands-in-WebKit
and old way of doing this demo
with sticky position demo

jQuery: Run when scroll over a div of a certain class

so I have multiple divs of the same class below each other. I now want to trigger a "loading comments"-function every time a visitor scrolls to a new div. However, I have no idea how to track jQuery scroll over a div. The comments for each div should only be loaded once, my idea would be to save the current position in a variable and only load comments when the new scroll position is greater than the old one.
Can you please help me out?
EDIT: I created a image that shows what I need to do.
Image: http://i.imgur.com/78EYK.jpg
EDIT 2: SOLVED!
Solved with Viewport (thanks to Royi Namir)
http://www.appelsiini.net/projects/viewport
My code:
load = $(".my-div:in-viewport").attr('id');
load_comments(load);
This is executed every second.
you should read about viewport
Viewport ads couple of extra selectors to jQuery. With these selectors you can check whether element is inside or outside of viewport. To see how it works check the demo.
http://www.appelsiini.net/projects/viewport/3x2.html

Insert content at top of page without scrolling

Is there a way that I can insert content at the beginning of a webpage without causing the page to give the impression of scrolling up.
I'm trying to implement something kind of like infinite scrolling but I need to be able to scroll up infinitely as well as down (I'm also unloading content on the other end so that the scroll bar doesn't become infinitesimal and the app doesn't take up too much memory).
I'm happy to use javascript, I'd rather not use a library (I'm trying to stay lighter weight than that).
Any ideas?
Before executing the code to create your element, simply do something like this:
var scrollY = window.scrollY;
window.onscroll = function(){
window.scrollTo(0, scrollY);
window.onscroll = null;
};
Keep in mind that, if you already have an onscroll function, you will need to reassign the function after this...
In my case layout was something like this:
<div class='container'>
<div class='list'>
product cards...
</div>
<button>Load more</button>
</div>
By clicking on button I want fetch data from server, dynamically create product cards with that data and add this cards to .list
Problem was that when dynamically cards added to the DOM, screen automaticaly scroll and I see only last added cards, but not first added.
I think its default behavior for all browsers (I may be wrong) - if content added in DOM above the focused element browser scroll page in order to focused element was on screen. If content added below the focused element scroll not happened and the focused element also on the screen.
To solve this problem I just add something like document.activeElement.blur() before add cards to the DOM and all was fine.
You can use window.scrollBy(x, y) to scroll down when you add content (you have to calculate the height of what you add).
One possible idea is to bypass the scroll mechanism completely and do your own.
Basically, position every element with display: fixed. You can then load elements above the screen using negative positions.
You'll have to sync the height of the document (just by adding white space) so the document scrollbars are correct. Then, you trap the scroll event and adjust the fixed positioning of all the elements within your page.
I'm not sure how smooth it will be, but I'm fairly certain you could get the effect you're looking for.
I solved it by saving the first element of the container in a variable and then after inserting I called "scrollIntoView" on it. Looks smooth to me.

How can I temporarily prevent a scrollable div from scrolling?

Here is my current situation:
I have a web page containing a couple scrollable divs. Each of those divs contains a number of objects. I am using YUI to display popup menus of actions that can be performed on each object. Each object has its own menu associated with it that is constructed and displayed dynamically. The popup menus can be large and can overlap the bounds of the scrollable div.
From what I believe are issues with focus (the menus must be accessible), when I hover the mouse over an action that lies on top of an edge of the scrollable div, the div automatically scrolls, moving the content but leaving the menu stationary. Trying to move the menu dynamically when this happens is not something I want to do as I believe it would provide a poor user experience.
So I need to prevent this focused menu from scrolling the div. My idea for providing the best user interface is to prevent these inner divs from scrolling when a menu is open. This leaves the menu positioned in the optimal location to show the user which item is being acted upon. If the user wants to scroll the box, they can click to close the menu and then scroll normally.
How can I do this? I need a solution that works across the major browsers.
My first thought was to listen to the onscroll event for that particular element. Unfortunately, there does not seem to be an easy way from there to just prevent the scrolling from happening. For one, my JavaScript event code appears to execute after the actual scrolling has occurred.
Then, I thought that since my code is being run after the object has scrolled, I could just reset obj.scrollTop and obj.scrollLeft. Sure enough, this appears to work, though I am worried that on slow browsers the user will see the content inside the div "jump around". Also, it would be really nice if the amount the element scrolls is part of the event object. Is it stuck in there somewhere? I'm looking for an alternative to having to store the scrollTop and scrollLeft variables for this element and then using them while the scrolling is temporarily disabled.
What is the best way to solve this entire problem?
I agree with Anthony regarding the presentation of the functionality you're trying to disallow. If you're going to disable scrolling, then you should make that part of the page visually disabled or removed.
To that end, you can position a semi-transparent div on top of the scrollable div in question, which would capture the mouse events and visually show that the scrollable div is inactive for now. It would be hard to make cross-browser compatible and wouldn't be perfect, but then again very few client-side tricks like this are.
The simple answer is no you can't do this. Its doubly no if you want a cross-browser solution.
Providing the user with the clear affordance that something can be scrolled then denying them that is just plain poor UI design.
Ok so after your edit it turns out you are not actually trying to prevent the user from scrolling.
The main answer remains true though. It sounds as though the focus is going to rectangle (probably an anchor?) that is not fully in view and causes a scroll. Is there a reason this rectangle must get the focus? For accessibility?
What if you didn't have overflow: scroll and instead you used overflow: hidden and provided scroll up/down buttons that allowed the user to scroll when necessary? These buttons could of course be disabled easily.
Though it may not be the answer you are looking for, if you are to set the display value of the div to 'none' while the page loads (from the server) and then have an event wired to the page load (either pageLoad in ajax.net or attach it to the onload event via javascript) that will make the div display set to 'block' .. that would ensure that slower browsers wouldn't see the div 'jumping around' (could even put a 'loading' image in the div to show users it's doing something and not just invisible)
sorry i couldn't provide a more complex/fluent solution.
I found a way to work around this issue. By removing the menu element from the scrollable div and then appending it directly to document.body, the browsers all stop trying to scroll the div to reveal the focused element (even though the element is already completely visible).
Thanks to all for your time and your answers!

Categories