Home > database >  Make mousewheel marquee infinite?
Make mousewheel marquee infinite?

Time:10-23

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 ========== -->

  • Related