I was trying to create a multi-control marquee built with vanilla JavaScript - for my website, so I made this marquee-like slider which is in its early stages.
It is basically a marquee which I made to be controlled using the mousewheel.
Now the issue is that, while it seems to work as intended, I wanted it to be infinite, that is, allowing the user to continue scrolling instead of stopping at the left side or the right side.
How do I convert this to an infinite scroll effect?
const categories = document.querySelector('div.categories')
const inner_categories = document.querySelector('div.inner_categories')
categories.addEventListener("mousewheel", function(e) {
if (e.deltaY > 0) {
this.scrollLeft = 100;
} else {
this.scrollLeft -= 100;
}
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Yu Gothic UI';
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100vh;
background-color: #8a5bcb;
}
div.categories {
border: 1px solid #000;
display: flex;
align-items: center;
background-color: #30b090;
overflow: hidden;
height: 40px;
width: 50vw;
position: relative;
}
div.inner_categories {
display: flex;
white-space: nowrap;
grid-column-gap: 10px;
position: absolute;
top: 50%;
transform: translateY(-50%);
left: 0;
right: 0;
width: 100%;
}
div.category {
font-size: 12px;
background-color: #E0E0E0;
padding-top: 2px;
padding-bottom: 2px;
padding-left: 5px;
padding-right: 5px;
border-radius: 5px;
}
div.category:hover {
cursor: pointer;
}
a {
text-decoration: none;
color: #111;
font-weight: 600;
}
<!-- ========== begin ========== MARQUEE TABS ========== begin ========== -->
<div >
<div >
<!-- ========== begin ========== CATEGORY TABS ========== begin ========== -->
<div >
<a href="https://google.com">Google</a>
</div>
<div >
<a href="https://yahoo.com">Yahoo</a>
</div>
<div >
<a href="https://bing.com">Bing</a>
</div>
<div >
<a href="https://facebook.com">Facebook</a>
</div>
<div >
<a href="https://instagram.com">Instagram</a>
</div>
<div >
<a href="https://twitter.com">Twitter</a>
</div>
<div >
<a href="https://tiktok.com">TikTok</a>
</div>
<div >
<a href="https://linkedin.com">Linkedin</a>
</div>
<div >
<a href="https://behance.net">Bēhance</a>
</div>
<div >
<a href="https://indeed.com">Indeed</a>
</div>
<div >
<a href="https://slot.ng">SLOT</a>
</div>
<div >
<a href="https://pointekonline.com">Pointek online</a>
</div>
<div >
<a href="https://gsmarena.com">GSM Arena</a>
</div>
<div >
<a href="https://stackoverflow.com">StackOverflow</a>
</div>
<div >
<a href="https://youtube.com">YouTube</a>
</div>
<div >
<a href="https://dailymotion.com">Daily Motion</a>
</div>
<div >
<a href="https://vimeo.com">Vimeo</a>
</div>
<div >
<a href="https://tumblr.com">Tumblr</a>
</div>
<div >
<a href="https://naijaterra.com">NaijaTerra</a>
</div>
<div >
<a href="https://gtbank.com">GT bank</a>
</div>
<div >
<a href="https://outlook.com">Outlook</a>
</div>
<!-- ========== end ========== CATEGORY TABS ========== end ========== -->
</div>
</div>
<!-- ========== end ========== MARQUEE TABS ========== end ========== -->
CodePudding user response:
There is no need for actual scrolling, just move elements from one end to the other using
inner_categories.append(inner_categories.firstChild)
and
inner_categories.prepend(inner_categories.lastChild)
In the snippet you'll notice it continues infinitely looping one item at a time in both directions:
const categories = document.querySelector('div.categories')
const inner_categories = document.querySelector('div.inner_categories')
categories.addEventListener("mousewheel", function(e) {
if (e.deltaY > 0) {
inner_categories.append(inner_categories.firstChild)
} else {
inner_categories.prepend(inner_categories.lastChild)
}
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Yu Gothic UI';
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100vh;
background-color: #8a5bcb;
}
div.categories {
border: 1px solid #000;
display: flex;
align-items: center;
background-color: #30b090;
overflow: hidden;
height: 40px;
width: 50vw;
position: relative;
}
div.inner_categories {
display: flex;
white-space: nowrap;
grid-column-gap: 10px;
position: absolute;
top: 50%;
transform: translateY(-50%);
left: 0;
right: 0;
width: 100%;
}
div.category {
font-size: 12px;
background-color: #E0E0E0;
padding-top: 2px;
padding-bottom: 2px;
padding-left: 5px;
padding-right: 5px;
border-radius: 5px;
}
div.category:hover {
cursor: pointer;
}
a {
text-decoration: none;
color: #111;
font-weight: 600;
}
<!-- ========== begin ========== MARQUEE TABS ========== begin ========== -->
<div >
<div >
<!-- ========== begin ========== CATEGORY TABS ========== begin ========== -->
<div >
<a href="https://google.com">Google</a>
</div>
<div >
<a href="https://yahoo.com">Yahoo</a>
</div>
<div >
<a href="https://bing.com">Bing</a>
</div>
<div >
<a href="https://facebook.com">Facebook</a>
</div>
<div >
<a href="https://instagram.com">Instagram</a>
</div>
<div >
<a href="https://twitter.com">Twitter</a>
</div>
<div >
<a href="https://tiktok.com">TikTok</a>
</div>
<div >
<a href="https://linkedin.com">Linkedin</a>
</div>
<div >
<a href="https://behance.net">Bēhance</a>
</div>
<div >
<a href="https://indeed.com">Indeed</a>
</div>
<div >
<a href="https://slot.ng">SLOT</a>
</div>
<div >
<a href="https://pointekonline.com">Pointek online</a>
</div>
<div >
<a href="https://gsmarena.com">GSM Arena</a>
</div>
<div >
<a href="https://stackoverflow.com">StackOverflow</a>
</div>
<div >
<a href="https://youtube.com">YouTube</a>
</div>
<div >
<a href="https://dailymotion.com">Daily Motion</a>
</div>
<div >
<a href="https://vimeo.com">Vimeo</a>
</div>
<div >
<a href="https://tumblr.com">Tumblr</a>
</div>
<div >
<a href="https://naijaterra.com">NaijaTerra</a>
</div>
<div >
<a href="https://gtbank.com">GT bank</a>
</div>
<div >
<a href="https://outlook.com">Outlook</a>
</div>
<!-- ========== end ========== CATEGORY TABS ========== end ========== -->
</div>
</div>
<!-- ========== end ========== MARQUEE TABS ========== end ========== -->
CodePudding user response:
Instead of mousewheel
use wheel
:) (mousewheel
is deprecated event)
We can't get scrollLeftMax
because that's not cross-browser feature, so we are going to get it using scrollWidth
, element's offsetWidth
and we shouldn't forget about styles :) (border size I mean)
const cats = document.querySelector('div.categories') // Meow
const inner_categories = document.querySelector('div.inner_categories')
cats.addEventListener("wheel", function(e) {
let max = cats.scrollWidth - cats.offsetWidth getSideBordersSize()
if(cats.scrollLeft >= max) {
this.scrollLeft = 0
} else if(cats.scrollLeft <= 0) {
this.scrollLeft = max
}
if (e.deltaY > 0) {
this.scrollLeft = 100;
} else {
this.scrollLeft -= 100;
}
});
function getSideBordersSize() {
let styles = window.getComputedStyle(cats)
let size = styles.borderLeftWidth.slice(0, -2) styles.borderRightWidth.slice(0, -2)
return size
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Yu Gothic UI';
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100vh;
background-color: #8a5bcb;
}
div.categories {
border: 1px solid #000;
display: flex;
align-items: center;
background-color: #30b090;
overflow: hidden;
height: 40px;
width: 50vw;
position: relative;
}
div.inner_categories {
display: flex;
white-space: nowrap;
grid-column-gap: 10px;
position: absolute;
top: 50%;
transform: translateY(-50%);
left: 0;
right: 0;
width: 100%;
}
div.category {
font-size: 12px;
background-color: #E0E0E0;
padding-top: 2px;
padding-bottom: 2px;
padding-left: 5px;
padding-right: 5px;
border-radius: 5px;
}
div.category:hover {
cursor: pointer;
}
a {
text-decoration: none;
color: #111;
font-weight: 600;
}
<!-- ========== begin ========== MARQUEE TABS ========== begin ========== -->
<div >
<div >
<!-- ========== begin ========== CATEGORY TABS ========== begin ========== -->
<div >
<a href="https://google.com">Google</a>
</div>
<div >
<a href="https://yahoo.com">Yahoo</a>
</div>
<div >
<a href="https://bing.com">Bing</a>
</div>
<div >
<a href="https://facebook.com">Facebook</a>
</div>
<div >
<a href="https://instagram.com">Instagram</a>
</div>
<div >
<a href="https://twitter.com">Twitter</a>
</div>
<div >
<a href="https://tiktok.com">TikTok</a>
</div>
<div >
<a href="https://linkedin.com">Linkedin</a>
</div>
<div >
<a href="https://behance.net">Bēhance</a>
</div>
<div >
<a href="https://indeed.com">Indeed</a>
</div>
<div >
<a href="https://slot.ng">SLOT</a>
</div>
<div >
<a href="https://pointekonline.com">Pointek online</a>
</div>
<div >
<a href="https://gsmarena.com">GSM Arena</a>
</div>
<div >
<a href="https://stackoverflow.com">StackOverflow</a>
</div>
<div >
<a href="https://youtube.com">YouTube</a>
</div>
<div >
<a href="https://dailymotion.com">Daily Motion</a>
</div>
<div >
<a href="https://vimeo.com">Vimeo</a>
</div>
<div >
<a href="https://tumblr.com">Tumblr</a>
</div>
<div >
<a href="https://naijaterra.com">NaijaTerra</a>
</div>
<div >
<a href="https://gtbank.com">GT bank</a>
</div>
<div >
<a href="https://outlook.com">Outlook</a>
</div>
<!-- ========== end ========== CATEGORY TABS ========== end ========== -->
</div>
</div>
<!-- ========== end ========== MARQUEE TABS ========== end ========== -->