如何停止在特定元素上沿特定方向滚动?

时间:2019-05-06 22:21:21

标签: javascript jquery html

因此,我在JavaScript(+ jQuery,JS库)中有以下代码:

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>
(不确定为什么向上滚动时会跳过价格,但不会在真实网站上跳过价格)

当前,当向下滚动时,它将转到其下面的同级部分;当向上滚动时,它将转到其上方的同级部分;但是,当您查看#discord时,如果向下滚动您将被重定向到https://yoursite.com/website.html#undefined,然后您将无法再向上或向下滚动(在查看#home时向上滚动的情况相同)。

我该如何解决?

2 个答案:

答案 0 :(得分:1)

尝试以下方法。您可能需要对其进行一些修改。

foreach($factsheets as $key => $factsheet){
 $factsheet['relevance'] = 1;
}
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;
}

答案 1 :(得分:0)

您可以这样做:

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

这将阻止它失败