I have a page that scrolls normal (vertically) and I'd like to have a div that scrolls horizontally on mousewheel down, then resumes vertical scrolling once the horizontal scrolling is done. Here's what I'm trying to accomplish.
I have tried a few solutions but run in to the following problems
Here's what I have so far...
var scroller = {};
scroller.e = document.getElementById("scroll");
if (scroller.e.addEventListener) {
scroller.e.addEventListener("mousewheel", MouseWheelHandler, false);
scroller.e.addEventListener("DOMMouseScroll", MouseWheelHandler, false);
} else scroller.e.attachEvent("onmousewheel", MouseWheelHandler);
function MouseWheelHandler(e) {
// cross-browser wheel delta
var e = window.event || e;
var delta = - 30 * (Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail))));
var pst = $('#scroll').scrollLeft() + delta;
if (pst < 0) {
pst = 0;
} else if (pst > $('.box-wrap').width()) {
pst = $('.box-wrap').width();
}
$('#scroll').scrollLeft(pst);
return false;
}
var toolbox = $('#scroll'),
height = toolbox.height(),
scrollHeight = toolbox.get(0).scrollHeight;
toolbox.off("mousewheel").on("mousewheel", function (event) {
var blockScrolling = this.scrollTop === scrollHeight - height && event.deltaY < 0 || this.scrollTop === 0 && event.deltaY > 0;
return !blockScrolling;
});
#wrap {
max-width: 600px;
margin: 0 auto;
}
#scroll {
width: 600px;
border: 1px solid #111;
padding: 0px;
margin: 0px;
overflow-x: scroll;
overflow-y: hidden;
}
.box-wrap{
padding: 0px;
margin: 0px;
height: 200px;
width: 2040px;
}
.box {
height: 200px;
width: 200px;
padding: 0px;
background: #123;
display: inline-block;
color: #fff;
font-size: 20px;
text-align: center;
line-height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="wrap">
<h1>asl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdk</h1>
<div id="scroll">
<div class="box-wrap">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
<div class="box">7</div>
<div class="box">8</div>
<div class="box">9</div>
<div class="box">10</div>
</div>
</div>
<h1>asl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdk</h1>
</div>
The problem with this solution is that the vertical page scroll doesn't stop when I get to the horizontal scroll section.
Does anyone have any suggestions on how to accomplish what I want? If I'm not explaining this right please let me know.
Thanks!
You were almost there. Here's a blocker for your scroll:
$("#scroll").off("mousewheel").on("mousewheel", function(ev) {
var el = $(ev.currentTarget);
return ev.originalEvent.deltaY > 0
? el[0].scrollWidth - el.scrollLeft() <= el.innerWidth()
: el.scrollLeft() === 0;
});
Updated pen.
To watch them, use this logger in the mousewheel event:
console.log(
'ev.originalEvent.deltaY:', ev.originalEvent.deltaY,
'\nel[0].scrollWidth:',el[0].scrollWidth,
'\nel.scrollLeft():', el.scrollLeft(),
'\nel.innerWidth()',el.innerWidth()
);
For making the #scroll
div stick to the page, don't stop the normal vertical scrolling. Instead, increase the top position of the div so that it looks like the #scroll
div is staying in the same position.
I wrapped the portion that needs to stick inside a #fixedSec
.
Also, to make the .box-wrap
div scroll with the vertical window scroll, use the scrollTop()
function, and then translate your .box-wrap
accordingly.
The codepen link is this.
Below is code.
var scroller = {};
var topSpace = $('#topHeading').height();
const scrollWidth = $('.box-wrap').width();
console.log($(window).width());
scroller.e = document.getElementById("scroll");
$(window).scroll(function(event) {
var scroll = $(window).scrollTop();
if (scroll > 785 && ((765 - scroll) > ($(window).width() - $(".box-wrap").width()))) {
var scrollPos = scroll - 770;
$('#fixedSec').css({
'top': scrollPos + "px"
})
$('.box-wrap').css('transform', 'translateX(' + (755 - scroll) + 'px)');
}
});
h1 {
width: 500px;
}
#wrap {
margin: 0 auto;
}
#fixedSec {
position: relative;
}
#scroll {
width: 100vw;
border: 1px solid #111;
padding: 0px;
margin: 0px;
overflow-x: scroll;
overflow-y: hidden;
}
.box-wrap {
padding: 0px;
margin: 0px;
height: 200px;
width: 2040px;
}
.box {
height: 200px;
width: 200px;
padding: 0px;
background: #123;
display: inline-block;
color: #fff;
font-size: 20px;
text-align: center;
line-height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="wrap">
<h1 id="topHeading">asl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas
fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh
sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas
kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdk</h1>
<div id="fixedSec">
<div id="scroll">
<div class="box-wrap">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
<div class="box">6</div>
<div class="box">7</div>
<div class="box">8</div>
<div class="box">9</div>
<div class="box">10</div>
</div>
</div>
<h1>asl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas
fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh
sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs
kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdk</h1>
</div>
</div>
Note
Even if you make the overflow
of #scroll
hidden, the solution will still work since its using the transform: translateX()
function to horizontally scroll the .box-wrap
.
Personally, I'll make the overflow:hidden
as the scroll bar looks ugly.
Hope this implementation works for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With