How can I detect where the mouse is positioned whenever I scroll? I can do this using a combination of onmousemove and scroll, but this seems like such a waste. I don't need to know where the mouse is before I scroll, only when I scroll - or perhaps even just right after I scroll. Please refer to my snippet below to see my attempt (event.clientY produces undefined) and please no jquery. Thanks.
var clientY_display_element = document.getElementById("clientY_display");
document.addEventListener('scroll', show_position = function (event) {
clientY_display_element.textContent = "event.clientY = " + event.clientY;
})
#container {
height: 50px;
}
#content {
height: 1000px;
background-color: rgba(120,120,120,1);
}
#clientY_display {
position: fixed;
}
<div id="container">
<div id="content"></div>
</div>
<div id="clientY_display">Scroll to see event.clientY position.. </div>
Is this what you want to achieve? Scroll inside the #container to see the number of pixels scrolled.
clientY is the coordinate of the mouse pointer when a mouse event was triggered. But you are listening for "scroll" event which is triggered when the document view has been scrolled. For scroll events, you can use the scrollTop to get the number of pixels that an element's content is scrolled vertically.
I also changed a bit your css, for this example's purpose.
var clientY_display_element = document.getElementById("clientY_display");
let scroller = document.querySelector("#container")
scroller.addEventListener('scroll', show_position = function (event) {
clientY_display_element.textContent = `scroll position = ${scroller.scrollTop}`;
})
#container {
height: 50px;
overflow: scroll;
}
#content {
height: 1000px;
background-color: rgba(120,120,120,1);
}
#clientY_display {
position: fixed;
}
<div id="container">
<div id="content"></div>
</div>
<div id="clientY_display">Scroll to see scroll position.. </div>
Related
I have a web page with two 100% height divs like this...
<style>
html, body{
height: 100%;
width: 100%;
margin: 0;
overflow: hidden;
}
#wrapper{
height:100%;
width:100%;
overflow: auto;
}
.scroll-item{
height: 100%;
width: 100%;
}
</style>
...
<body>
<div id="wrapper">
<div id="test1"
class="scroll-item">Simple Test 1</div>
<div id="test2"
class="scroll-item">Simple Test 2</div>
</div>
</body>
Now I want to "select" the one that is currently scrolled to. This means that the top of the element has reached the top of the browser but the bottom has not. This is where I am getting confused here is the JS...
<script type="module">
const body = document.getElementsByTagName("body")[0];
const handleScroll = function(info){
const items = body.getElementsByClassName("scroll-item");
for(let i = 0; i < length; i++){
const item = items[i];
// TODO How do I tell if it is there
}
}
body.addEventListener("wheel",handleScroll);
</script>
I have tried using the bounding box but I cannot figure out how to get that to work correctly.
How do I tell when the top or bottom of the element reaches the top of the browser (given possible offset for navbar)?
You can use getBoundingClientRect().
It gives you the DOMRect object containing the size and coordinates of an element.
...
if (item.getBoundingClientRect().top < 0) {
// items top has reached beyond window top
}
if (item.getBoundingClientRect().bottom > window.innerHeight) {
// items bottom is beyond window bottom
}
...
For advanced usage, see IntersectionObserver, which detects an elements visibility inside the viewport.
Use the wrapper to get current position and listen scroll event, also, is better to listen scroll instead of wheel event.
// Use the wrapper to get and listen scroll
const wrapper = document.querySelector('#wrapper')
const handleScroll = function(event) {
const top = wrapper.scrollTop;
document.querySelectorAll('.scroll-item').forEach((item, index) => {
// Calculate item bottom position
const bottom = item.offsetTop + item.offsetHeight;
// Is the scroll between item top and bottom?
if(top >= item.offsetTop && top < bottom) {
console.log(`Item ${index} is active`);
}
});
}
// scroll event is more accurate than wheel
wrapper.addEventListener("scroll", handleScroll);
html, body{
height: 100%;
width: 100%;
margin: 0;
overflow: hidden;
}
#wrapper{
height:100%;
width:100%;
overflow: auto;
}
.scroll-item{
height: 100%;
width: 100%;
}
<body>
<div id="wrapper">
<div id="test1"
class="scroll-item">Simple Test 1</div>
<div id="test2"
class="scroll-item">Simple Test 2</div>
</div>
</body>
I have a container of 200px that have a container itself with 400px height, I have a tracking mouse object that moves with it on mousemove event
when I'm moving the mouse in the not overflowed part, everything is fine, but when I move the scroll down the object do not track the mouse anymore
$(document).mousemove(function(e) {
$("#image").css({
left: e.pageX,
top: e.pageY
});
});
#image {
position: absolute;
}
.container {
height: 200px;
overflow: auto;
}
.image-container {
position: relative;
height: 400px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="image-container">
<img id="image" src="http://images.pictureshunt.com/pics/m/mouse-8557.JPG" />
</div>
</div>
There is JSFiddle link here too.
Because you're not taking account of the scrollTop property of .container when positioning the cursor element. Try this:
let container = $('.container'); //<-- get container
$(document).mousemove(e => {
$("#image").css({
left: e.pageX,
top: e.pageY + container[0].scrollTop //<-- add scroll top too
});
});
In the interests of efficiency, it would also be good to cache the reference to #image once rather than grab it afresh every time the event fires.
let
container = $('.container'),
image = $('#image')
;
$(document).mousemove(e => {
image.css({ ...
I have an odd situation. Look at this image:
I have that ruler along the top. I don't want it to scroll off when I scroll the content vertically, so I put it outside the scrolling container. But now it doesn't scroll horizontally either. I need to scroll that horizontally in sync with the content container's scrollbar when the content is scrolled.
How can I accomplish this?
This plain javascript function picks up the .scrollLeft value of the #content and reproduces it on the #ruler's .scrollLeft
jsfiddle
document.getElementById("content").addEventListener("scroll", myFunction);
function myFunction() {
var elmnt = document.getElementById("content");
var elmnt2 = document.getElementById("ruler");
elmnt2.scrollLeft = elmnt.scrollLeft;
}
#ruler {
background: skyblue;
overflow: hidden;
width: 100%;
}
#content {
height: 100px;
overflow: scroll;
background: plum;
}
<div id=ruler>1..2..3..4..5..6..7..8..9..0..1..2..3..4..5..6..7..8..9..0..1..2..3..4..5..6..7..8..9..0..1..2..3..4..5..6..7..8..9..0..1..2..3..4..5..6..7..8..9..0..1..2..3..4..5..6..7..8..9..0..1..2..3..4..5</div>
<div id=content>
<p>texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext</p>
<p>texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext</p>
<p>texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext</p>
<p>texttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttexttext</p>
</div>
Here is the code that i have so far:
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 120) {
$("#FixedBox").addClass("fixed");
} else {
$("#FixedBox").removeClass("fixed");
}
});
With this code when the page is scrolled with 120px it add the class fixed to the element with id FixedBox.
What i want?
The element with id FixedBox is contained in element with id Content. So when the page is scrolled with 120 px my script attaches fixed class to FixedBox which makes it fixed.
How can i remove that fixed class when FixedBox reaches the end of Content ?
Here is an image in example:
How i can achieve that?
I hope you can help me!
You could make a function which checks if the scroll height is in between the start and the end of the content and adds the class accordingly. This would even work if you have several blocks of content.
Live Demo (3rd content box is the target)
HTML
<div class="content">
<div class="box">
</div>
</div>
<div class="content" id="target">
<div class="box">
</div>
</div>
CSS
.content{
width: 100%;
height: 400px;
background: red;
margin-bottom: 20px;
position: relative;
}
.fixed{
width: 100px;
height: 100px;
position: fixed;
right: 10px;
top: 10px;
background: blue;
display: block;
}
jQuery
var content = $('#target');
$(window).scroll(function() {
var scroll = $(window).scrollTop();
var offset = content.offset();
var height = content.height();
if (offset.top <= scroll && scroll <= offset.top + height) {
$('.box', content).addClass("fixed");
} else {
$('.box', content).removeClass('fixed');
}
});
You can find the end of your content by finding its position by $('#content').offset() or $('#footer').offset() more in the jQuery API Docs.
When you calculate the height of your elements and positions you can figure out the top threshold where you need to remove the fixed class of the FixedBox. Keep in mind that you also need to alter the non-fixed position of your FixedBox when it returns to the DOM flow, else it will snap back to the starting position.
`
var maxScroll = 120 + document.getElementById('#content').offsetHeight;
if (scroll >= 120 && scroll <= maxScroll) {
$("#FixedBox").addClass("fixed");
} else {
$("#FixedBox").removeClass("fixed");
}
You just need to get #content height.
I've searched on Stackoverflow but can't seem to find a satisfactory answer to this question. Basically I'd like to know if the scroll was done via mousewheel or the browser scrollbar.
Something like this might work for you but it is not the best solution.
If the a wheel event occurs right before the scroll event, then the scroll is done with the wheel otherwise it is done with using something else then the wheel. There is a slight time difference between both events that are triggered thats why I use a threshold currTime - lastWheelTime > 30.
$('.test').on('scroll wheel DOMMouseScroll mousewheel', function(e) {
var lastWheelTime,
currTime = (new Date()).getTime();
if( e.type === 'scroll' ) {
lastWheelTime = $(this).data().lastWheelTime || 0;
if( currTime - lastWheelTime > 30 ) {
$('.info').text('no wheel');
} else {
$('.info').text('with wheel');
}
} else {
$(this).data().lastWheelTime = (new Date()).getTime();
}
});
.test {
width: 200px;
height: 300px;
border: 1px solid red;
overflow: auto;
}
.inner {
height: 600px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="info"></div>
<div class="test">
<div class="inner"></div>
</div>
Here is my trick to detect scrolling by wheel or not
(Thanks #t.niese for the code snippet, I have made some modification for my demo)
var withWheel = true;
$('.test').on('scroll', function() {
$(".info").text("with wheel: " + withWheel);
})
$('.inner').on('mouseover', function() {
withWheel = true;
}).on('mouseleave', function(e) {
e.stopPropagation();
withWheel = false;
});
.test {
width: 200px;
height: 300px;
border: 1px solid red;
overflow: auto;
}
.info {
position: fixed;
}
.inner {
height: 600px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="info"></div>
<div class="test">
<div class="inner"></div>
</div>
I'd say both the wheel scroll and scrollbar scroll are the same. See the jquery page Here.
The scroll event is sent to an element when the user scrolls to a different place in the element. It applies to window objects
Reading this, it looks like the same event is going to be fired for both.
Another way that might be possible (i haven't tried it yet) is checking whether a mouse button was pressed during the scroll event (one has to click the scrollbar, right?).