I have a very long div (height: 500px), and I want to detect if user scrolled to the bottom of this div.
I have seen so many answers in the stackoverflow, almost all the answers mentioned scrollTop. However, in my simple example (jsfiddle), the scrollTop is always 0. After reading the MDN, I realize maybe they are talking about scrollable div? But all I want is to detect whether user scrolled to the bottom of a normal div.
Code
<html>
<body>
<!-- This is the very very long div, which may be contained in some other divs -->
<div></div>
</body>
</html>
jQuery Code
Currently, there is no scrollBottom function of jQuery. But, I have created a function that will tell whether we can see the bottom of a specific div element or not.
let aDiv = document.getElementById("aDiv");
$(document).scroll(function () {
var y = $(this).scrollTop();
var windowHeight = $(window).height();
var bottomVal = aDiv.offsetTop + aDiv.offsetHeight- windowHeight;
let s = document.getElementById("txt");
if(y>bottomVal && y< bottomVal + windowHeight){ s.innerHTML = "You can see bottom of aDiv";}
else{ s.innerHTML = "Can't see bottom of aDiv"; }
});
You can go through the following example. This might help you.
https://jsfiddle.net/q2smtvya/3/
Update: Added Vanilla JS Code. The only change will be the following JS Code
let aDiv = document.getElementById("aDiv");
window.onscroll = function(){
var y = window.scrollY;
var windowHeight = window.innerHeight;
var bottomVal = aDiv.offsetTop + aDiv.offsetHeight- windowHeight;
let s = document.getElementById("txt");
if(y>bottomVal && y< bottomVal + windowHeight){ s.innerHTML = "You can see bottom of aDiv";}
else{ s.innerHTML = "Can't see bottom of aDiv"; }
};
You can go through the following example. This might help you.
https://jsfiddle.net/nrp7x61k/1/
Related
I have this scrollable text where the user is able to scroll so that my name is shown. I want to stop the text from being scrolled any further when the element reaches the middle of the user's screen. Is there any way to do that? Attached below is a snippet of the code.
let text = document.getElementById('text');
var textRect = text.getBoundingClientRect();
var bodyRect = document.body.getBoundingClientRect();
var w = window.innerWidth;
const scaler = 1/25
window.addEventListener('scroll', function(){
let value = window.scrollY;
if (value < w/2.65) /*when text is right of center*/{
text.style.marginRight = value * 3*scaler+ 'vw';
}
})
I have made many futile attempts at solving this issue but all have gone in vain. Thank you to anyone that helps me solve this issue.
I have tried using innerwidth to compare my value to the width of the screen and used document.body.getBoundingClientRect() but none of those have worked either
Strictly using JavaScript, I'd like to position the following div element right outside the window, to the right, so that no horizontal scrollbar is present.
How do I do this?
HTML:
<div id = "content">
<header>
<h2>Welcome!</h2>
</header>
</div>
I was thinking something like
$( "#content" ).offset({ left: 1345});
but that unfortunately results in a scrollbar, and it isn't responsive, causing the div to be located far outside the right edge of the window when in mobile view.
If you take the window.innerWidth; value and set that as the left position value it'll hang out right outside of the viewports width.
You'd need to set either your wrapper or body to overflow: hidden; to get rid of the horizontal scroll though.
var hiddenDiv = document.getElementById('content');
var docWidth = window.innerWidth;
hiddenDiv.style.position = 'relative'; // Or absolute, depending on what you want
hiddenDiv.style.display = 'inline-block';
hiddenDiv.style.left = docWidth+'px';
http://jsfiddle.net/c62sqvdk/ <-- JsFiddle for visual example.
Why not just hide it? You can easily do it with javascript with
var link = document.getElementById('content');
link.style.display = 'none';
link.style.visibility = 'hidden';
Depends on what you need it for.
Also, check this https://daneden.github.io/animate.css/
Try
document.body.style.overflow = "hidden";
var content = document.getElementById("content");
content.style.position = "absolute";
content.style.left = window.innerWidth + "px";
jquery
$(function() {
$("body").css("overflow", "hidden")
.find("#content").css({
"position" : "absolute",
"left" : window.innerWidth
});
});
jsfiddle http://jsfiddle.net/guest271314/9zhy2xax/
Here is a link to a JSFiddle http://jsfiddle.net/9NYcn/11/ i put together with what i would like to do, but i need to do this with pure css.
function expand(){
var sect = document.getElementById("sect");
var body = document.getElementById("main");
var panes = document.getElementById("panes");
var newHeight = 40 + "px";
var newHeight2 = 120 + "px";
var topVal = 120 + "px";
sect.style.display = "block";
sect.style.height = newHeight;
body.style.height = newHeight2;
panes.style.top = topVal;
}
In the above function i had to set the "top" property of panes in order to get this to work. i need to get it so that the panes section will work like it currently does without using javascript to change the "top" property of "panes". When the user clicks the "expand" button the div with the class "body" will expand and not stick behind or overlap the "panes" div.
I know im doing a terrible job explaining i apologize for that.
Remove the absolute positioning of .panes: http://jsfiddle.net/rHTM8/
It will make it naturally flow after the middle div.
Hi I am trying to implement a simple chatbox in django and was wondering how to scroll to the bottom of a div class using javascript? Basically when the page loads I would like so that users can see the most recent message sent to them instead of the least recent.
I had to do this recently for a similar thing. I found a basic jquery plug-in that will smoothly scroll an element onto the screen.
(function($) {
$.fn.scrollMinimal = function() {
var cTop = this.offset().top;
var cHeight = this.outerHeight(true);
var windowTop = $(window).scrollTop();
var visibleHeight = $(window).height();
if (cTop < windowTop) {
$('body').animate({'scrollTop': cTop}, 'slow', 'swing');
} else if (cTop + cHeight > windowTop + visibleHeight) {
$(jQuery.browser.webkit ? "body": "html")
.animate({'scrollTop': cTop - visibleHeight + cHeight}, 'slow', 'swing');
}
};
}(jQuery));
which is used like this:
$('#chat').scrollMinimal();
Well, the basic script is set the scrollTop equal to scrollHeight, so you need a script like this:
var DIV = document.getElementById('theDIVElement');
DIV.scrollTop = DIV.scrollHeight;
You only need to change theDIVElement to your DIV id.
This is the script I used in my chat:
<SCRIPT LANGUAGE="JavaScript">
<!--
function myScroll() {
window.scrollBy(0,01)
setTimeout('myScroll()',100); }
if (document.layers || document.all)
myScroll()
//--></SCRIPT>
This is also nice for when new messages are added, if you scroll to the bottom too fast, it's hard on your eyes while you're trying to read.
I am having this problem where i have a set of 6 UL's having a common class x.Each of them consist of a specific section of the page.Now i have 6 menus that are related to each of the section.What i have to do is highlight the menu when its related section is in users view.
For this i thought that may be jQuery position(); or offset(); could have helped but they give the top and left of the element.I also tried using jQuery viewport plugin but apparently view port is big it can show more than one UL at a time hence i cant apply element specific logic here.I am not familliar to this but does anything changes of an element on scrolling?If yes then how to access it?
Please share your views.
Regards
Himanshu Sharma.
Is very easy to do it using jQuery and a dummy fixed HTML block that helps you find the current position of the viewport.
$(window).on("scroll load",function(){
var once = true;
$(".title").each(function(ele, index){
if($(this).offset().top > $("#viewport_helper").offset().top && once){
var index = $(this).index(".title");
$(".current").removeClass('current')
$("#menu li").eq(index).addClass('current')
once = false;
}
});
})
Check out a working example: http://jsfiddle.net/6c8Az/1/
You could also do something similar with the jQuery plugin, together with the :first selector:
$(window).on("scroll load",function(){
$(".title:in-viewport:first").each(function(){
var index = $(this).index(".title");
$(".current").removeClass('current')
$("#menu li").eq(index).addClass('current')
});
})
You can get the viewport's width and height via $(document).width() and $(document).height()
You can get how many pixels user scrolls via $(document).scrollTop() and $(document).scrollLeft
Combining 1 and 2, you can calculate where the viewport rectangle is
You can get the rectangle of an element using $(element).offset(), $(element).width() and $(element).height()
So the only thing left to you is to determine whether the viewport's rectangle contains (or interacts) the elements's rectangle
So the whole code may look like:
/**
* Check wether outer contains inner
* You can change this logic to matches what you need
*/
function rectContains(outer, inner) {
return outer.top <= inner.top &&
outer.bottom >= inner.bottom &&
outer.left <= inner.left &&
outer.right >= inner.right;
}
/**
* Use this function to find the menu related to <ul> element
*/
function findRelatedMenu(element) {
return $('#menu-' + element.attr('id'));
}
function whenScroll() {
var doc = $(document);
var elem = $(element);
var viewportRect = {
top: doc.scrollTop(),
left: doc.scrollLeft(),
width: doc.width(),
height: doc.height()
};
viewportRect.bottom = viewportRect.top + viewportRect.height;
viewportRect.right = viewportRect.left + viewportRect.width;
var elements = $('ul.your-class');
for (var i = 0; i < elements.length; i++) {
var elem = $(elements[i]);
var elementRect = {
top: elem.offset().top,
left: elem.offset().left,
width: elem.width(),
height: elem.height()
};
elementRect.bottom = elementRect.top + elementRect.height;
elementRect.right = elementRect.left + elementRect.width;
if (rectContains(viewportRect, elementRect)) {
findRelatedMenu(elem).addClass('highlight');
}
}
}
$(window).on('scroll', whenScroll);
Let's see if i understood well. You have a page long enough to scroll, and there is an element that when it appears in the viewport, you wanna do something with it. So the only event that's is triggered for sure on the time the element gets in the viewport is the 'scroll'. So if the element is on the page and the scroll is on the viewport, what you need to do is bind an action to the scroll event to check if the element is in the view each time the event is trigger. Pretty much like this:
$(window).scroll(function() {
check_element_position();
});
Now, in order for you to know if the element is in the viewport, you need 3 things. The offset top of that element, the size of the viewport and the scroll top of the window. Should pretty much look like this:
function check_element_position() {
var win = $(window);
var window_height = win.height();
var element = $(your_element);
var elem_offset_top = element.offset().top;
var elem_height = element.height();
var win_scroll = win.scrollTop();
var pseudo_offset = (elem_offset_top - win_scroll);
if (pseudo_offset < window_height && pseudo_offset >= 0) {
// element in view
}
else {
// elem not in view
}
}
Here, (elem_offset_top - win_scroll) represent the element position if there was no scroll. Like this, you just have to check if the element offset top is higher then the window viewport to see if it's in view or not.
Finally, you could be more precise on you calculations by adding the element height (variable already in there) because the code i just did will fire the event even if the element is visible by only 1 pixels.
Note: I just did that in five minutes so you might have to fix some of this, but this gives you a pretty darn good idea of what's going on ;)
Feel free to comment and ask questions