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

标签 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时向上滚动时也会发生同样的情况)。

如何解决这个问题?

最佳答案

尝试以下操作。您可能需要根据您的需要对其进行一些修改。

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>

关于javascript - 如何停止在特定元素上沿特定方向滚动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56013108/

相关文章:

html - 有没有办法拥有与 URL 相关的 CSS 样式?

javascript - HTML 在 JavaScript 中显示值 "data"

javascript - 使用有条件禁用的控件进行内联编辑

javascript - 在 php 中使用唯一的 div Id 传递给 javascript 并用于运行另一个 php 脚本

javascript - 定义未定义(ESLint)

javascript - 从表中选择随机行,然后删除该行并用该行创建一个新表?

jQuery的removeAttribute()不工作

html - 表头应该如何使用?

javascript - 检查输入是否为空或有文本而不是数字

jquery星级回调