Tigerrrrr
Tigerrrrr

Reputation: 1344

How do I Stop Scrolling in a Specific Direction on a Specific Element?

So, I have this code in JavaScript (+ jQuery, JS Library):

var $curr = $(".scroll");
$('body').on('wheel', function(event) {
    if (event.originalEvent.deltaY > 0) {
        $curr = $curr.nextUntil('#home');
        window.location.hash = $($curr).attr('id');
    }
    else {
        $curr = $curr.prevUntil('#discord');
        window.location.hash = $($curr).attr('id');
    }
});
* {
    font-family: Poppins;
}

::-webkit-scrollbar {
    width: 0;
}

html {
    scroll-behavior: smooth;
}

body {
    overflow: hidden;
    margin: 0;
}

section {
    height: 100vh;
}

#home {
    background: red;
}

#pricing {
    background: green;
}

#discord {
    background: yellow;
}

.scroll {
    background: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section id="home" class="scroll">Home</section>
<section id="pricing">Pricing</section>
<section id="discord">Discord</section>
(not sure why it skips pricing upon scrolling up, but it doesn't skip pricing on the real website)

Currently, When scrolling down, it will go to the sibling section below it and when scrolling up, it will go to the sibling section above it, but, when you're viewing #discord, if you scroll down you will be redirected to https://yoursite.com/website.html#undefined and then you will no longer be able to scroll up or down (the same happens when you scroll up when viewing #home).

How do I fix this?

Upvotes: 0

Views: 115

Answers (2)

acarlstein
acarlstein

Reputation: 1838

Try the following. You may have to modify it a little to your need.

function jumpTo(id){
if (typeof id !== 'undefined'){   
    $("div.log").append("<br>jump to: " + id);
      var top = $("#" + id).position().top;
      $('html').scrollTop(top);
      //window.location.hash = id;      
    }  
}


// Below is one way to tackle the issue of getting 'undefined' when next() and prev() cannot find the following element.
// Think of a double-linkedlist and these are the method to navigate it; however, they don't stop at the ends when they don't find a next element and the thing crashes returning 'undefined'

// We keep a reference to the original code
$.fn.oldNext = $.fn.next;
$.fn.oldPrev = $.fn.prev;

// We override next().
// If there are elements, we return them else we return reference to discord section
$.fn.next = function(selector){
    var selector = selector || '';
    return this.oldNext(selector).length ? this.oldNext(selector) : $("#discord");
}

// We override prev().
// If there are elements, we return them else we return reference to home section
$.fn.prev = function(selector){
    var selector = selector || '';
    return this.oldPrev(selector).length ? this.oldPrev(selector) : $("#home");
}

// Wait for all the DOMs in the page to be loaded prior to execute this code
$(function() {

  // Lets obtain the selector object of the home section and jump to it.
  var $curr = $("#home");
  jumpTo("home");

  // Self Explanatory
  $('body').on('wheel', function(event) {  
  
      // I am implementing my own logger here
      $("div.log").append("<br> " + $curr.prev('section').attr('id'));
      
      // deltaY return a positive or negative value depending of the direction the wheel its turned.
      if (event.originalEvent.deltaY > 0) {             
      
         // jQuery next() method, without modifying it, returns undefined when can't find a next element. Good policy to check prior using.
         if (typeof $curr.next('section') !== 'undefined'){
           $curr = $curr.next('section');
         }else{
           $curr = $("#home");
         }
      } else {  
      
      // jQuery prev() method, without modifying it, returns undefined when can't find a previous element. Good policy to check prior using.
         if (typeof $curr.prev('section') !== 'undefined'){
           $curr = $curr.prev('section');            
         }else{
           $curr = $("#discord");
         }
      }

      var id = $curr.attr('id');
      jumpTo(id);
  });
});
html, body {
  margin: 0;
  padding: 0;
  width: 100%
}

section {
  width: 100%;
  height: 100vh;  
}

div.log {
  position: fixed;
  top: 0px;
  left: 0px;
  width: 100%;
  height: 100vh  
  border: 1px black solid;
  color: black;
  text-align: right;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section id="home" class="scroller">Home</section>
<section id="pricing" class="scroller">Pricing</section>
<section id="discord" class="scroller">Discord</section>
<div class="log">Log goes here</div>

Upvotes: 1

LordRampantHump
LordRampantHump

Reputation: 384

You could just do:

if(typeof $($curr).attr('id') !== "undefined")
{
  window.location.hash = $($curr).attr('id');
} 

which would stop it failing

Upvotes: 0

Related Questions