【问题标题】:Scroll Through Div While Locking Body Scroll. Overflow:Hidden?在锁定正文滚动时滚动浏览 Div。溢出:隐藏?
【发布时间】:2017-10-19 19:00:01
【问题描述】:

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

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

问题:

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

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

这是因为滚动事件依赖于坐标输入,并且由于身体滚动被锁定,它没有得到这些?是别的吗?您对我的项目如何使用有任何提示吗?这个项目有更好的事件监听器或滚动锁定方法吗?

代码:

    <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>

【问题讨论】:

标签: javascript jquery html css


【解决方案1】:

尝试使用 body-scroll-lock (https://www.npmjs.com/package/body-scroll-lock)。

在 body 上设置 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

希望对你有帮助。

【讨论】:

    【解决方案2】:

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

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


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

    1. 在 CSS 中定义一个类:
    body.no-scrollbar {overflow:hidden;}
    
    1. #timeline:hover 上将课程应用/删除到body
    $(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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-08
      • 2013-11-25
      相关资源
      最近更新 更多