在锁定正文滚动的同时滚动浏览 div.溢出:隐藏



我正在使用ScrollStop来创建一种z轴时间轴。它使用滚动事件在时间线内容之间循环。

代码在此处作为网站上传 http://jcwebandgraphic.com/archive2/

问题:

我使用 mouseentermouseleave 来触发 CSS 更改 - 溢出隐藏和溢出可见,以防止在时间线div 中滚动时在正文上滚动。

这成功地停止了正文滚动,但它似乎也停止了允许我使用滚动事件在时间轴中移动的滚动停止功能。

这是因为滚动事件依赖于坐标输入,并且由于正文滚动被锁定,因此无法获取这些输入吗?是别的什么吗?您对如何与我的项目一起工作有什么提示吗?对于这个项目,是否有更好的事件侦听器或滚动锁定方法?

守则:

    <script>
        // When the Window Object is loaded and a Scroll Event is initiated, The following functions will Be Fired
        $(window).on('scrollstart', function() {
            // Timeline Functions for Touchless Devices
                // Block 1 - Scroll Locking
                    // Locks Body Scrolling While in Timeline
                    $('#timeline').on('mouseenter', function() {
                        $('body').css('overflow', 'hidden');
                    }); // Closes $(#timeline) mouseenter Function
                    // Rerstores Body Scrolling While Out of Timeline
                    $('#timeline').on('mouseleave', function() {
                        $('body').css('overflow', 'visible');
                    }); // Closes $(#timeline) mouseleave Function
                    // Closes Functions Block 1
                // Closes Block 1 - Scroll Locking
                // Block 2 - Transitions
                    // Reassigns jQuery Defined HTML Objects as HTML Elements (For Removal and Re-Insertion to the DOM)
                    var last = $('.scroll li:last-child')[0]; // Convert to HTML Element jQuery Element
                    var parent = last.parentElement;
                    // Animate to 0 Opacity
                    $('.scroll li:last-child').animate({opacity: '.1'});
                        // Animation and Re-Ordering Block
                        // 1 Removes Last Child From the DOM
                        // 2 Forces Opacity Back to 1
                        // 3 Re-Inserts it into the DOM at the First Child Position
                        // 1 Removal
                        parent.removeChild(last);
                        // 2 Opacity
                        last.style.opacity = 1;
                        // 3 Re-insertion
                        parent.insertBefore(last, parent.firstElementChild)
                    // Closes Animation and Re-Ordering Block
                // Closes Block 2 - Transitions
        }); //Closes $(window) Load Functions
        // Required Fixes
            // 1 Size / Positioning Glitch on mouseenter, mouseleave (CSS, jQuery)
            // 2 Restore Scroll Transitions on mouseenter (jQuery)
            // 3 Touch Device Usability for Simulated or Alternate mouseenter and mouseleave Functions
            // 4 Create Function Looping if Scroll Event lasts more than ~250ms
            // 5 Make #timeline Height Responsive
        // Completed Fixes
            // 9 Scroll Only Works on First Refresh, or Directly from File  
            // 8 Functions Break When Removing Unnecessary HTML Content
            // 7 Body Continues to Scroll While Scrolling Through Timeline
            // 6 Collapsing Parent Element on #timeline
            // 5 Last Child Failing to Re-Order
            // 4 Limited Scroll Area Forces Premature Animation Transition Completion
            // 3 Limited Scroll Area Prevents Opacity Completion
            // 2 Uncaught Exception Errors (4)
            // 1 Uncaught Token Errors (2)
    </script>
<body>
    <!-- Timeline  -->
    <section id='timeline'>
        <h2 class='subtitle'>Timeline</h2>
        <div class='scroll'>
            <li><img src='images/pa3.jpg'></li>
            <li><img src='images/pa2.jpg'></li>
            <li><img src='images/pa1.jpg'></li>
        </div>
    </section>
    <!-- Closes Timeline -->
</body>

尝试使用正文滚动锁定 (https://www.npmjs.com/package/body-scroll-lock)。

在正文上设置overflow: hidden在 iOS 上不起作用。你需要一些JS逻辑来让它在那里工作。要锁定所有设备的正文滚动,同时使目标元素仍然能够滚动,您可以使用 body-scroll-lock 执行以下操作:

// 1. Import the functions
const bodyScrollLock = require('body-scroll-lock');
const disableBodyScroll = bodyScrollLock.disableBodyScroll;
const enableBodyScroll = bodyScrollLock.enableBodyScroll;
// 2. Get a target element (such as a modal/lightbox/flyout/nav). 
const targetElement = document.querySelector("#someElementId");

// 3. ...in some event handler after showing the target element...disable body scroll
disableBodyScroll(targetElement);

// 4. ...in some event handler after hiding the target element...
enableBodyScroll(targetElement);

有关基本原理的更多详细信息,请查看 https://medium.com/jsdownunder/locking-body-scroll-for-all-devices-22def9615177。

希望对您有所帮助。

您的代码存在一个主要问题。您将在每个$(window) scrollstart事件上绑定它的新实例。第一个窗口滚动启动后,#timeline mousenter 代码将在#timeline鼠标事件上运行一次。在第二个窗口scrollstart每次您进入/退出#timeline时,它将运行两次,依此类推...

您必须将$(window).on('scrollstart', ...替换为$(window).on('load', ...。 所以你只绑定一次。


关于你的脚本正文,我建议采用更轻松的方法。大多数时候,CSS 比 JavaScript 更快,需要的资源更少。因此,更好的方法是:

  1. 在 CSS 中定义一个类:
body.no-scrollbar {overflow:hidden;}
  1. 应用/删除类以body #timeline:hover
$(window).on('load', function() {
  $('#timeline').hover(
    function() {
      $('body').addClass('no-scrollbar');
    },
    function() {
      $('body').removeClass('no-scrollbar');
    }
  );
});

我使用了不影响移动设备的hover()。这不应以任何方式影响其他脚本。

下面是一个快速演示:

$(window).on('load', () => $('#timeline').hover(
  () => $('body').addClass('no-scrollbar'),
  () => $('body').removeClass('no-scrollbar')
));
body.no-scrollbar {
  overflow: hidden;
}
/* rest is just styling for SO example. Disregard */
body {
  height: 200vh;
}
#timeline {
  border: 1px solid red;
  width: calc(100vw - 9rem);
  height: 3rem;
  margin: 3rem;
}
legend {padding: 0 .4rem;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<fieldset id="timeline">
  <legend>timeline</legend>
</fieldset>

最新更新