Как я могу горизонтально прокручивать div колесом мыши, блокируя прокрутку тела?

#javascript #reactjs #ecmascript-6

#javascript #reactjs #ecmascript-6

Вопрос:

Я сделал так, чтобы мой div прокручивался по горизонтали. Но он не прокручивается с помощью колеса мыши. Я попробовал пакет ‘react-scroll-horizontal’, но его опция блокировки тела у меня не работала, и у него нет опции колеса. Кроме того, я хочу заблокировать прокрутку основного текста документа до тех пор, пока div не будет полностью прокручен до конца. Итак, я хочу контролировать и знать состояние прокрутки моего div.

 handleDivScroll = (e) => {
    const container = document.getElementsByClassName("labels-box");
    console.log(container.scrollTop)
    console.log(container.scrollLeft)
}

<div className="labels-box">
    {this.handleDivScroll}
    <img className="labels" src={LabelImg} alt="" />
    <img className="labels" src={LabelImg} alt="" />
    <img className="labels" src={LabelImg} alt="" />
    <img className="labels" src={LabelImg} alt="" />                              
</div>
  

это плохо отображает сообщение консоли.

 .labels-box {
  min-width: 100%;
  display: flex;
  overflow-x: scroll;
}
  

это заставляет div прокручиваться горизонтально, но колесо мыши не работает.

Кроме того, я пытался

 transform: rotate(-90deg); //for .labels-box
transform: rotate(90deg); //for .labels
  

но колесо мыши не работало.

Комментарии:

1. @SteveK это именно то, что я ищу!!

2. Горизонтальная прокрутка по умолчанию работает с помощью Shift Колесо мыши. Это также именно то, чего я ожидал бы как пользователь. Я бы не рекомендовал реализовывать что-либо, кроме этого стандартного поведения.

3. @connexo Хорошо, спасибо, но я должен это сделать..

Ответ №1:

Вы можете достичь этого с помощью scrollmagic. Вы можете увидеть библиотеку scrollmagic здесь, и у них есть пакет react, который вы можете установить с помощью npm или yarn Здесь. Я отправил пример, который я прокомментировал, на github, чтобы вы могли просто загрузить репозиторий и настроить по своему вкусу здесь. Основная идея этого заключается в том, чтобы прикрепить раздел к окну, а затем переместить раздел внутри по горизонтали во время прокрутки до завершения, а затем продолжить обычную прокрутку вниз по сайту. Итак, ваш компонент будет выглядеть примерно так:

 import React, { useState } from 'react';
import { Controller, Scene } from 'react-scrollmagic';
import { Tween, Timeline } from 'react-gsap';

const SlideContainer = () => {
  const [state] = useState({
    sections: [
      { id: 1, imgSrc: 'https://placehold.it/1920x1080' },
      { id: 2, imgSrc: 'https://placehold.it/1920x1080' },
      { id: 3, imgSrc: 'https://placehold.it/1920x1080' },
      { id: 4, imgSrc: 'https://placehold.it/1920x1080' }
    ]
  });

  const tweenPercentage = 100 - 100 / state.sections.length;

  return (
    <Controller>
      <Scene triggerHook="onLeave" duration={2000} pin>
        {progress => (
          <div className="pin-container" style={styles.pinContainer}>
            <Timeline totalProgress={progress} paused>
              <Tween from={{ x: '0%' }} to={{ x: '-'   tweenPercentage   '%' }}>
                <div
                  className="slide-container"
                  style={{
                    ...styles.slideContainer,
                    width: state.sections.length   '00%'
                  }}
                >
                  {state.sections.map(section => (
                    <div
                      className="panel"
                      key={section.id}
                      style={styles.panel}
                    >
                      <div
                        style={{
                          background: 'url('   section.imgSrc   ')',
                          backgroundSize: 'cover',
                          backgroundPosition: 'center',
                          width: '100%',
                          height: '100%'
                        }}
                      />
                    </div>
                  ))}
                </div>
              </Tween>
            </Timeline>
          </div>
        )}
      </Scene>
    </Controller>
  );
};

const styles = {
  normalSection: {
    background: '#282c34',
    height: '100vh',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center'
  },
  pinContainer: {
    height: '100vh',
    width: '100%',
    overflow: 'hidden'
  },
  slideContainer: {
    height: '100%',
    display: 'flex'
  },
  panel: {
    flex: 1,
    padding: '40px',
    display: 'flex',
    flexDirection: 'column',
    alignItems: 'center',
    justifyContent: 'center'
  }
};

export default SlideContainer;
  

В примере я просто перебираю объекты, которые я поместил в состояние, а затем у меня есть несколько уравнений для автоматической установки ширины div, но вы можете довольно легко настроить его по своему вкусу. Поместите divs внутри .slide-container и убедитесь, что вы установили ширину контейнеров слайдов по своему вкусу. Если у вас есть какие-либо вопросы, дайте мне знать.

Комментарии:

1. Спасибо за ваш ответ. но реализация этого не блокирует прокрутку тела окна. И как я могу реализовать это внутри div ?

2. При этом нет причин блокировать тело. Идея состоит в том, чтобы прикрепить контейнер к верхней части окна, а затем прокручивать этот дочерний div контейнера по горизонтали, пока вы не прокрутите содержимое по горизонтали, а затем продолжите прокрутку в обычном режиме. Я отредактировал github, чтобы показать это немного лучше. Итак, загрузите github и запустите его, и вы сможете увидеть, о чем я говорю. Что касается его реализации в вашем div, вы будете использовать .pin-container как div, который будет закреплен вверху, а .scoll-container будет горизонтально прокручиваться внутри .pin-container до тех пор, пока…

3. … настройка анимации, которую вы установили, закончилась, и затем вы можете прокручивать сайт обычным способом. Таким образом, не будет причин блокировать функцию прокрутки основного текста, потому что вы будете использовать встроенную функцию прокрутки для прокрутки содержимого по горизонтали. Возможно, я не понимаю, чего вы пытаетесь достичь, потому что ваш вопрос был довольно расплывчатым, поэтому я изначально опубликовал комментарий с примером. Но загрузите исправленный github и запустите его, и если у вас все еще есть вопросы, дайте мне знать. В github есть два разных примера, поэтому прокрутите до конца.

4. Хорошо, я спрошу более подробно в следующий раз. Я скачал ваш git-код и попробовал его. Вы действительно хорошо поняли, что я пытаюсь. Это именно то, что я хочу!!! Я действительно ценю вашу детализацию и любезный ответ 🙂

5. Я буду изучать глубже, просматривая ваш код. Вы не против, если я использую это для собственного использования?????