Dynamically scrolling a DIV layer down when data is loaded - javascript

I coded a chat script and I plucking my hair for couple of months to understand how a DIV layer can be scrolled down on loading some data to it using a Databinder with Repreater in ASP.NET with AJAX extensions.
I read a blog today where the author just gave me the logic but not code and I am not an expert in writing highend JavaScripts. Can anybody help me in constructing it.
Get scroll bar position.
If scroll bar position is not bottom then move to bottom.
If scroll bar is scrolled up do no action until new item is loaded to Databinder.
Can anybody provide me with the syntax for the above three please.
Or kindly let me know if there is any other way to get rid of my issue.

You can use scrollTop property in native JS and $(selector).scrollTop() method in jQuery. In both cases you can assign a value to it to change the scroll position of that element.
Example:
document.getElementById("myDiv").scrollTop = 100;
$("#myDiv").scrollTop(100);
EDIT
var div = document.getElementById('myDiv');
var scrollHeight = div.scrollHeight;
var scrollTop = div.scrollTop;
var height = parseInt(div.style.height);
if(scrollHeight - (scrollTop + height) == 0) {
// do something when you're at the bottom
} else {
// do something when you're NOT at the bottom
}

Related

Test if element can be seen by the user on an html page

Is there any way to know if an element is visible on an html page?
Like this:
One can probably do it considering the horizontal/vertical scrolling positions, the width/height of the browser window and the position/size of the element on the page, but I have little experience in jQuery so I don't know how to do it. And there might be a simple function one can call, I don't know.
You can use the .is(':visible') selectors to check if an element is currently visible in the DOM.
Edit:
However, as #BenM mentioned, this doesn't check if the elements on your page are actually out of your scrollable range - a great little plugin you could use in that case would be Viewport Selectors for jQuery.
Here is some code that I use to do this. It has been tested to work great.
function isVisible($obj) {
var top = $(window).scrollTop();
var bottom = top + $(window).height();
var objTop = $obj.offset().top;
var objBottom = objTop + $obj.height();
if(objTop < bottom && objBottom > top) {
//some part of $obj is visible on the screen.
//does not consider left/right, only vertical.
}
}

So DOM scrollIntoView aligns top/bottom, but what about left/right?

I would like to scroll horizontally the given element. The only way I find is using ScrollIntoView DOM method, which allows either align the element's bottom with the view bottom or the top - with the view top.
But what if the element is OK with respect to the Y axis, and I only want to scroll it horizontally? How can I align its left with the view left or its right with the view right?
EDIT
Here is more context. I have a YUI table with a horizontal scrollbar. I wish to scroll it programmatically to a certain TD node. I do not think window.scrollTo is of any help to me, since the scrollbar is on a div element, not on the whole page.
EDIT2
Turns out there is a duplicate SO question with the right answer - How can I scroll programmatically a div with its own scrollbars?
Voting to close mine.
I've recently had a problem with a table header that had inputs as filters for each column. Tabbing through the filters would move the focus, but if one of the inputs wasn't visible or if it was partly visible, it would only JUST bring the input into view, and I was asked to bring the full input and column into view. And then I was asked to do the same if tabbing backwards to the left.
This link helped to get me started: http://www.webdeveloper.com/forum/showthread.php?197612-scrollIntoView-horizontal
The short answer is that you want to use:
document.getElementById('myElement').scrollLeft = 50;
or:
$('#myElement')[0].scrollLeft = 50;
Here's my solution (which may be overkill for this question, but maybe it'll help someone):
// I used $.on() because the table was re-created every time the data was refreshed
// #tableWrapper is the div that limits the size of the viewable table
// don't ask me why I had to move the head head AND the body, they were in 2 different tables & divs, I didn't make the page
$('#someParentDiv').on('focus', '#tableWrapper input', function () {
var tableWidth = $('#tableWrapper')[0].offsetWidth;
var cellOffset = $(this).parent()[0].offsetLeft;
var cellWidth = $(this).parent()[0].offsetWidth;
var cellTotalOffset = cellOffset + cellWidth;
// if cell is cut off on the right
if (cellTotalOffset > tableWidth) {
var difference = cellTotalOffset - tableWidth;
$('#tableWrapper').find('.dataTables_scrollHead')[0].scrollLeft = difference;
$('#tableWrapper').find('.dataTables_scrollBody')[0].scrollLeft = difference;
}
// if cell is cut off on the left
else if ($('#tableWrapper').find('.dataTables_scrollHead')[0].scrollLeft > cellOffset) {
$('#tableWrapper').find('.dataTables_scrollHead')[0].scrollLeft = cellOffset;
$('#tableWrapper').find('.dataTables_scrollBody')[0].scrollLeft = cellOffset;
}
});
This is something I used a while back. There might be better and more efficient way of doing it but this gets the work done:
$(".item").click(function(event){
event.preventDefault();
// I broke it down into variable to make it easier to read
var tgt_full = this.href,
parts = tgt_full.split("#"),
tgt_clean = parts[1],
tgt_offset = $("#"+tgt_clean).offset(),
tgt_left = tgt_offset.left;
$('html, body').animate({scrollLeft:tgt_left}, 1000, "easeInOutExpo");
})
You just need to make sure that the item is an a tag with an href that corresponds to the target id element:
HTML:
go to section 1
...
<section id="one"> Section 1</section>
Hope this helps!

Get Default Height Of Element On Webpage after css height has been applied)

How do I go about getting what the height of an element on a page would be if it ignored the 'height' css property applied to it?
The site I'm working on is http://www.wncba.co.uk/results and the actual script I've got so far is:
jQuery(document).ready(function($) {
document.origContentHeight = $("#auto-resize").outerHeight(true);
refreshContentSize(); //run initially
$(window).resize(function() { //run whenever window size changes
refreshContentSize();
});
});
function refreshContentSize()
{
var startPos = $("#auto-resize").position();
var topHeight = startPos.top;
var footerHeight = $("#footer").outerHeight(true);
var viewportHeight = $(window).height();
var spaceForContent = viewportHeight - footerHeight - topHeight;
if (spaceForContent <= document.origContentHeight)
{
var newHeight = document.origContentHeight;
}
else
{
var newHeight = spaceForContent;
}
$("#auto-resize").css('height', newHeight);
return;
}
[ http://www.wncba.co.uk/results/javascript/fill-page.js ]
What I'm trying to do is get the main page content to stretch to fill the window so that the green lines always flow all the way down the page and the 'Valid HTML5' and 'Designed By' messages are never above the bottom of the window. I don't want the footer to stick to the bottom. I just want it to stay there instead of moving up the page if there's not enough content to fill above to fill it. It also must adapt itself accordingly if the browser window size changes.
The script I've got so far works but there's a small issue that I want to fix with it. At the moment if the content on the page changes dynamically (resulting in the page becoming longer or shorter) the script won't detect this. The variable document.origContentHeight will remain set as the old height.
Is there a way of detecting the height of an element (e.g. #auto-resize in the example) and whether or not it has changed ignoring the height that has been set for it in css? I would then use this to update the variable document.origContentHeight and re-run the script.
Thanks.
I don't think there is a way to detect when an element size changed except using a plugin,
$(element).resize(function() //only works when element = window
but why don't you call refreshContentSize function on page changes dynamically?
Look at this jsFiddle DEMO, you will understand what I mean.
Or you can use Jquery-resize-plugin.
I've got it working. I had to rethink it a bit. The solution is on the live site.
The one think I'd like to change if possible is the
setInterval('refreshContentSize()', 500); // in case content size changes
Is there a way of detecting that the table row has changed size without chacking every 500ms. I tried (#content).resize(function() but couldn't to get it to work.

Scroll div on pagescroll but stop after certain amount

I have currently got an element to scroll on page scroll and I am looking to get it to stop after around 750px as it currently overlaps the footer on smaller monitors.
I have found a couple of other examples which would require some restructuring of my code which I am trying to avoid, as the various other examples have to have certain divs relevant to eachother in order to stop the scrolling div at a certain point on the page.
My current script is as below and wrks great, only I am unsure as to edit this to stop the div at a certain point:
<script type="text/javascript">
$(function(){
var btn = $('.overview-wrap');
var btnPosTop = btn.offset().top;
var win = $(window);
win.scroll(function(e){
var scrollTop = win.scrollTop();
if(scrollTop >= btnPosTop){
btn.css({position:'fixed',top:0,marginTop:0});
}else if(btn.css('position') === 'fixed'){
btn.css({position:'',top:'',marginTop:'20px'});
}
});
});
</script>
Any pointers would be appreciated.
Personally, I hate dealing directly with the DOM for things like position, because it's so variable. Check out the jquery-position library for a nice abstraction on top of the dom.

How DIV scrolls in chat script?

I coded for a chat script and all the issue is with scrolling DIV layer. I downloaded few chat scripts and found the below after careful observation.
When ever a new line of chat is added, scroll bar doesn't scrolls down after chat line is added. Its adding to the bottom of the DIV layer as the scroll doesn't make any kind of disturbance while making it.
What I did:
Before I used javascript to scroll down for every fixed interval. Doing this I am unable to manually scroll up to view past lines(due to interval refresh scroll bar moves to set position). Later I coded for a javascript that can scrolls down OnClientClick but doing this I can only able to scroll down Chat sender side but it cannot scroll down at Chat receiver side when a new chat line is added.
I downloaded many chat scripts and checked how this particular issue is managed but I couldn't find any solution for it. I fairly guess that its the work of jQuery (not sure) can anybody tell me how to fix this issue?
I am sorry if you failed to understand my issue as I am unable to explain it in more detailed than as above. However I can give you more information on request.
Languages I am using are ASP.NET, AJAX update panels, timer ticks for updating div with new values, javascripts are till now used only to scroll down the element.
Your chat 'screen' should look like this:
<div id="chat">
<div class="wrapper">
<!-- chat messages go here -->
</div>
</div>
Put overflow-y: auto on the chat, but leave the wrapper as it is. Create on function that runs at an interval and add or removes a class "atBottom" to chat 'screen' based on value returned by $('#chat').scrollTop() method.
monitor = function() {
var $this = $(this),
wrap = $this.find('.wrapper'),
height = $this.height(),
maxScroll = wrap.height() - height,
top = $this.scrollTop();
if (maxScroll === top) {
$this.addClass('atBottom');
} else {
$this.removeClass('atBottom');
}
}
window.setInterval(function() {
monitor.call($('#chat').get(0));
}, 350);
Then you need to bind an event 'addMessage' that works like so:
$('#chat').bind('addMessage', function(e, message) {
var $this = $(this),
// store whether it's at the bottom before appending the message
scroll = $this.hasClass('atBottom');
// then append the message
$this.find('.wrapper').append(message);
if (scroll) {
// measure the new maxScroll and scroll to it.
var wrap = $this.find('.wrapper'),
height = $this.height(),
maxScroll = wrap.height() - height
$this.scrollTop(maxScroll);
}
})
$('button').click(function() {
$('#chat').trigger('addMessage', 'asdgagasdg<br/>');
});
Here's an example:
http://jsfiddle.net/WVLE2/

Categories

Resources