锁定身体​​滚动时滚动Div。溢出:隐藏

时间:2017-10-19 19:00:02

标签: javascript jquery html css

我正在使用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>

2 个答案:

答案 0 :(得分:0)

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

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

关于脚本的正文,我建议采用更轻松的方法。大多数情况下,CSS比JavaScript更快,所需资源更少。所以最好的方法是:

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

答案 1 :(得分:0)

尝试使用body-scroll-lock(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

希望它有所帮助。