防止窗口垂直滚动,直到div的水平滚动到达其末端

时间:2019-03-13 23:44:31

标签: javascript jquery html css

我有一个页面,该页面正常(垂直)滚动,并且我希望有一个div可以在鼠标滚轮上向下滚动,然后在完成水平滚动后恢复垂直滚动。这就是我要完成的工作。

  • 页面正常(垂直)滚动
  • 一旦到达div #scroll,我希望页面滚动停止,并且我希望#scroll中的内容垂直滚动
  • 一旦我滚动到#scroll的末尾,我希望恢复正常的页面滚动(垂直)。

我尝试了一些解决方案,但遇到以下问题

  • 当我水平#scroll内容时,垂直页面滚动不会停止
  • 当我停止垂直滚动并到达水平滚动的末尾时,我必须滚动50次才能离开该div。

这是我到目前为止所拥有的...

var scroller = {};
scroller.e = document.getElementById("scroll");

if (scroller.e.addEventListener) {
    scroller.e.addEventListener("mousewheel", MouseWheelHandler, false);
    scroller.e.addEventListener("DOMMouseScroll", MouseWheelHandler, false);
} else scroller.e.attachEvent("onmousewheel", MouseWheelHandler);

function MouseWheelHandler(e) {

    // cross-browser wheel delta
    var e = window.event || e;
    var delta = - 30 * (Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail))));

    var pst = $('#scroll').scrollLeft() + delta;

    if (pst < 0) {
        pst = 0;
    } else if (pst > $('.box-wrap').width()) {
        pst = $('.box-wrap').width();
    }

    $('#scroll').scrollLeft(pst);

    return false;
}


var toolbox = $('#scroll'),
    height = toolbox.height(),
    scrollHeight = toolbox.get(0).scrollHeight;

toolbox.off("mousewheel").on("mousewheel", function (event) {
  var blockScrolling = this.scrollTop === scrollHeight - height && event.deltaY < 0 || this.scrollTop === 0 && event.deltaY > 0;
  return !blockScrolling;
});
#wrap {
  max-width: 600px;
  margin: 0 auto;
}

#scroll {
    width: 600px;
    border: 1px solid #111;
    padding: 0px;
    margin: 0px;
    overflow-x: scroll;
    overflow-y: hidden;
}

.box-wrap{
    padding: 0px;
    margin: 0px;
    height: 200px;
    width: 2040px;
}

.box {
    height: 200px;
    width: 200px;
    padding: 0px;
    background: #123;
    display: inline-block;
    color: #fff;
    font-size: 20px;
    text-align: center;
    line-height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="wrap">

  <h1>asl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdk</h1>

  <div id="scroll">
    <div class="box-wrap">
      <div class="box">1</div>
      <div class="box">2</div>
      <div class="box">3</div>
      <div class="box">4</div>
      <div class="box">5</div>
      <div class="box">6</div>
      <div class="box">7</div>
      <div class="box">8</div>
      <div class="box">9</div>
      <div class="box">10</div>     
    </div>
  </div>

  <h1>asl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdk</h1>

</div>

此解决方案的问题是,当我到达水平滚动部分时,垂直页面滚动不会停止。

有人对如何实现我想要的东西有任何建议吗?如果我没有解释这项权利,请告诉我。

谢谢!

5 个答案:

答案 0 :(得分:7)

您快到了。这是您的滚动条的阻止程序:

$("#scroll").off("mousewheel").on("mousewheel", function(ev) {
  var el = $(ev.currentTarget);
  return ev.originalEvent.deltaY > 0
    ? el[0].scrollWidth - el.scrollLeft() <= el.innerWidth()
    : el.scrollLeft() === 0;
});

Updated pen
要观看它们,请在mousewheel事件中使用此记录器:

console.log(
  'ev.originalEvent.deltaY:', ev.originalEvent.deltaY,
  '\nel[0].scrollWidth:',el[0].scrollWidth, 
  '\nel.scrollLeft():', el.scrollLeft(), 
  '\nel.innerWidth()',el.innerWidth()
);

答案 1 :(得分:5)

您需要使用e.preventDefault()来避免屏幕垂直滚动。但是,仅当水平容器允许根据滚动方向向左或向右滚动更多滚动时,才需要应用此功能。

  

这显然仅在对水平可滚动元素进行滚动时才有效。

实施示例(向下滚动进行测试):

let scrollSpeed = 30;
let scroller = document.getElementById("scroll");

scroller.addEventListener("mousewheel", e=>{
  // block if e.deltaY==0
  if( !e.deltaY ) return;
  // Set scrollDirection (-1 = up // 1 = down)
  let scrollDirection = (e.deltaY > 0) ? 1 : -1;
  // convert vertical scroll into horizontal
  scroller.scrollLeft += scrollSpeed * scrollDirection;
  let scrollLeft = Math.round(scroller.scrollLeft);
  // calculate box total vertical scroll 
  let maxScrollLeft = Math.round( scroller.scrollWidth - scroller.clientWidth );
  // if element scroll has not finished scrolling
  // prevent window to scroll
  if( 
    (scrollDirection === -1  && scrollLeft > 0) ||
    (scrollDirection === 1 && scrollLeft < maxScrollLeft ) 
  ) e.preventDefault()
  // done!
  return true;
}, false);
#wrap {
  max-width: 600px;
  margin : auto;
}

.dummy-content{
  height: 400px;
  background: red
}

#scroll {
    overflow-x: scroll;
    overflow-y: hidden;
    margin :20px 0;
}

#scroll>div:first-child{
    height: 200px;
    width: 2040px;
    background-image: linear-gradient(to right ,red, yellow);
}
<div id="wrap">
<div class='dummy-content'></div>
  <div id="scroll">
      <div>
          <!-- Your horizontal content -->
      </div>
  </div>
  <div class='dummy-content'></div>
</div>

答案 2 :(得分:4)

https://codepen.io/anon/pen/oOgrEY

正如Andrei Gheorghiu answer所解释。只是缺少:

e.preventDefault(); // << add this
e.stopPropagation(); // << add this

return false;之前

var scroller = {};
scroller.e = document.getElementById("scroll");

if (scroller.e.addEventListener) {
  scroller.e.addEventListener("mousewheel", MouseWheelHandler, false);
  scroller.e.addEventListener("DOMMouseScroll", MouseWheelHandler, false);
} else scroller.e.attachEvent("onmousewheel", MouseWheelHandler);

function MouseWheelHandler(e) {
  // cross-browser wheel delta
  var e = window.event || e;
  var delta = -30 * Math.max(-1, Math.min(1, e.wheelDelta || -e.detail));

  var pst = $("#scroll").scrollLeft() + delta;

  if (pst < 0) {
    pst = 0;
  } else if (pst > $(".box-wrap").width()) {
    pst = $(".box-wrap").width();
  }

  $("#scroll").scrollLeft(pst);
  e.preventDefault(); // << add this
  e.stopPropagation(); // << add this
  return false;
}

$("#scroll").off("mousewheel").on("mousewheel", function(ev) {
  var el = $(ev.currentTarget);
  return ev.originalEvent.deltaY > 0
    ? el[0].scrollWidth - el.scrollLeft() <= el.innerWidth()
    : el.scrollLeft() === 0;
});
#wrap {
  max-width: 600px;
  margin: 0 auto;
}

#scroll {
    width: 600px;
    border: 1px solid #111;
    padding: 0px;
    margin: 0px;
    overflow-x: scroll;
    overflow-y: hidden;
}

.box-wrap{
    padding: 0px;
    margin: 0px;
    height: 200px;
    width: 2040px;
}

.box {
    height: 200px;
    width: 200px;
    padding: 0px;
    background: #123;
    display: inline-block;
    color: #fff;
    font-size: 20px;
    text-align: center;
    line-height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="wrap">

  <h1>asl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdk</h1>

  <div id="scroll">
    <div class="box-wrap">
      <div class="box">1</div>
      <div class="box">2</div>
      <div class="box">3</div>
      <div class="box">4</div>
      <div class="box">5</div>
      <div class="box">6</div>
      <div class="box">7</div>
      <div class="box">8</div>
      <div class="box">9</div>
      <div class="box">10</div>     
    </div>
  </div>

  <h1>asl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdk</h1>
  
</div>

经过测试:版本73.0.3683.86(正式内部版本)(64位),Firefox 66.0.2(64位),Microsoft Edge 42.17134.1.0(Microsoft EdgeHTML 17.17134),Internet Explorer 11.648.17134.0

答案 3 :(得分:0)

您需要使用mouseWheelHandler中的e.preventDefault()停止默认事件行为(垂直滚动)。

答案 4 :(得分:0)

要使#scroll div粘贴到页面上,请不要停止正常的垂直滚动。而是增加div的顶部位置,以使#scroll div保持在相同位置。

我将需要粘贴的部分包裹在#fixedSec内。

此外,要使.box-wrap div与垂直窗口一起滚动,请使用scrollTop()函数,然后相应地转换.box-wrap

代码笔链接为 this

下面是代码。

var scroller = {};
var topSpace = $('#topHeading').height();
const scrollWidth = $('.box-wrap').width();
console.log($(window).width());

scroller.e = document.getElementById("scroll");
$(window).scroll(function(event) {
  var scroll = $(window).scrollTop();

  if (scroll > 785 && ((765 - scroll) > ($(window).width() - $(".box-wrap").width()))) {


    var scrollPos = scroll - 770;
    $('#fixedSec').css({
      'top': scrollPos + "px"
    })
    $('.box-wrap').css('transform', 'translateX(' + (755 - scroll) + 'px)');



  }


});
h1 {
  width: 500px;
}

#wrap {
  margin: 0 auto;
}

#fixedSec {
  position: relative;
}

#scroll {
  width: 100vw;
  border: 1px solid #111;
  padding: 0px;
  margin: 0px;
  overflow-x: scroll;
  overflow-y: hidden;
}

.box-wrap {
  padding: 0px;
  margin: 0px;
  height: 200px;
  width: 2040px;
}

.box {
  height: 200px;
  width: 200px;
  padding: 0px;
  background: #123;
  display: inline-block;
  color: #fff;
  font-size: 20px;
  text-align: center;
  line-height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="wrap">

  <h1 id="topHeading">asl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas
    fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh
    sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas
    kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdk</h1>

  <div id="fixedSec">
    <div id="scroll">
      <div class="box-wrap">
        <div class="box">1</div>
        <div class="box">2</div>
        <div class="box">3</div>
        <div class="box">4</div>
        <div class="box">5</div>
        <div class="box">6</div>
        <div class="box">7</div>
        <div class="box">8</div>
        <div class="box">9</div>
        <div class="box">10</div>
      </div>

    </div>

    <h1>asl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas
      fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh
      sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs
      kjfhas kljfh sakjfhas fsdkasl fjas fhljksa flkjsahf kjsah fkjlsa fkjshf kljsha fkljhs kjfhas kljfh sakjfhas fsdk</h1>
  </div>


</div>

注意

即使您将overflow中的#scroll隐藏起来,该解决方案仍然可以使用,因为它使用transform: translateX()函数来水平滚动.box-wrap。 就个人而言,我将使overflow:hidden滚动条看起来很丑。

希望此实现对您有用。