简体   繁体   中英

Restricting scroll direction from vertical/horizontal within same page

I'm trying to accomplish the same switch from vertical to horizontal scrolling seen here .

However, scrolling on the horizontal section while both sections are in view will enable horizontal scrolling. Is there a way to enable horizontal scrolling & restrict vertical scrolling only when the vertical section is not visible? Apologies for the awkward wording; essentially, I'd like the red portion to only be scrolled to when the white portion is already out of view.

 $(window).scroll(function () { var scrollTop = $(window).scrollTop(); if (scrollTop >= 1000){ $("html, body").mousewheel(function(event, delta) { this.scrollLeft -= (delta * 30); $("html,body").toggleClass("disable-scroll"); }); } });
 #outsidescrollwrapper{ width: 100vh; height: 100vw; transform: rotate(-90deg) translateX(-100vh); transform-origin: top left; overflow-y: scroll; overflow-x: hidden; position: absolute; } ::-webkit-scrollbar { display: none; } .sidescrollwrapper{ display: flex; flex-direction: row; width: 200vw; transform: rotate(90deg) translateY(-100vh); transform-origin: top left; } .sidescrollwrapper > .sidescroll { width: 100vw; height: 100vh; } #about{ height: 1000px; background: linear-gradient(to bottom, #FBFDFF, white); }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="about"> </div> <div id="outsidescrollwrapper"> <div class="sidescrollwrapper"> <div style="background-color:blue" class="sidescroll"></div> <div style="background-color:red" class="sidescroll"></div> </div> </div>

https://jsfiddle.net/1h4yeac0/

I have written this snippet below which observes elements that use a data-direction attribute. The values on these attributes can be whatever you want, but I chose to give them either horizontal or vertical value, which could be the scroll directions which you can use.

This will only monitor the elements that you query with the selector argument and will not change the direction of scrolling. That part I leave up to you to handle.

The callback will trigger whenever there is only 1 of the observerd elements in the viewport (which is what you requested, I believe). That callback has a parameter which is the current direction value. Based on that value you can switch your scroll directions.

I hope this helps you out, man.

 /** * Observes elements that indicate the current * scroll-direction based on a data-direction attribute. * The callbacks fires with the current direction whenever * a single observed element is in view. * * @param {string} selector * @param {function} callback * @returns {IntersectionObserver} */ function directionObserver(selector, callback) { /** * Store elements that are in view in a Set and * set the default direction. */ const elementsInView = new Set(); let currentDirection = 'vertical'; /** * Callback that runs whenever observed * elements intersect. * * @param {IntersectionObserverEntry[]} entries */ const intersectionCallback = entries => { /** * Check if current entries are in view. * If they are add them to the elementsInView array * and remove them if they are not. */ entries.forEach(entry => { const { target } = entry; if (entry.isIntersecting) { elementsInView.add(target); } else { elementsInView.delete(target); } }); /** * Whenever there is only one element in the view * switch the currentDirection to the value of the * direction data attribute. */ if (elementsInView.size === 1) { for (const element of elementsInView.values()) { currentDirection = element.dataset.direction; if ('function' === typeof callback) { callback(currentDirection); } } } } /** * Options for the observer */ const options = { root: null, rootMargin: '50px 0px', threshold: [0, 1] }; /** * Create observer */ const observer = new IntersectionObserver(intersectionCallback, options); /** * Observer elements based on the selector argument */ const sections = document.querySelectorAll(selector); sections.forEach(section => observer.observe(section)); return currentDirection; } // Use the observer and observe all the .section elements. directionObserver('.section', direction => { console.log(`Current direction is: ${direction}`); // Change scroll direction based on direction value. });
 *, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; } .section { display: block; height: 100vh; margin: 50px 0; } .vertical { width: 100%; background: repeating-linear-gradient( 0deg, white, white 50px, red 50px, red 100px ); } .horizontal { width: 300vw; background: repeating-linear-gradient( 90deg, white, white 50px, blue 50px, blue 100px ); }
 <div class="section vertical" data-direction="vertical"></div> <div class="section horizontal" data-direction="horizontal"></div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM