doka-guide / content

Контент Доки: статьи, картинки, демки и документация для авторов
https://doka.guide
Other
1.17k stars 621 forks source link

Рецепт с горизонтальным скроллом и тенями на телефоне #4299

Open punkmachine opened 1 year ago

punkmachine commented 1 year ago

Тема

Написать рецепт горизонтального скролла на телефоне, в котором будет работать логика того, что при клике на элемент. к нему будет идти скролл. Также, самое сложное, что было для меня в этой задаче, справа и слева должны появляться тени.

Зачем

Недавно у меня была таска рабочая с таким скроллом. Были затруднения, с которыми помогла Алёна Батицкая в чате. Могу перенести код, который написал с этим скроллом сюда и описать. Думаю будет полезно.

Кто напишет материал

punkmachine commented 1 year ago

Код мной был написан на вью 2, могу перенести на ванильный JS.

mixin:

export default {
  data() {
    return {
      visibleShadowRight: true,
      visibleShadowLeft: false,
    };
  },
  destroyed() {
    this.removeListenerScroll();
  },
  methods: {
    addListenerScroll() {
      this.$nextTick(() => {
        this.$refs.container.addEventListener('touchmove', this.onScrollContainer);
      });
    },
    removeListenerScroll() {
      if (this.$refs.container) {
        this.$refs.container.removeEventListener('touchmove', this.onScrollContainer);
      }
    },
    onScrollContainer() {
      const { scrollLeft } = this.$refs.container;

      this.visibleShadowRight = scrollLeft <= 0;
      this.visibleShadowLeft = scrollLeft > 0;
    },
  }
};

Стили:

.scroll-shadow {
  z-index: 2;
  width: calc(100% + 32px);
  position: absolute;
  top: 0;
  left: -16px;
  transition: 0.4s all;
  pointer-events: none;

  &--right {
    background: linear-gradient(90deg, rgba(255, 255, 255, 0) 74.65%,
      rgba(255, 255, 255, 0.6) 100%);
  }

  &--left {
    background: linear-gradient(270deg,
      rgba(255, 255, 255, 0) 76.32%, rgba(255, 255, 255, 0.6) 100%);
  }

  &--hide {
    opacity: 0;
  }
}

Клик по элементу:

onClick(card) {
        const container = document.querySelector(`[data-saved-card="${card.id}"]`);
        container.scrollIntoView({
          behavior: 'smooth',
          block: 'center',
          inline: 'center',
        });

        /* other logic */
      },

Разметка:

<div>
      <div ref="container" class="component__container">
        <div></div>
        <div></div>
        <div></div>
      </div>
    </div>
    <div
      class="component__shadow scroll-shadow scroll-shadow--left"
      :class="{
        'scroll-shadow__shadow--hide': !visibleShadowRight
      }"
    ></div>
    <div
      class="component__shadow scroll-shadow scroll-shadow--right"
      :class="{
        'scroll-shadow__shadow--hide': !visibleShadowLeft
      }"
    ></div>
</div>

Стили компонента:

.component {
  &__shadow {
    height: 44px;
  }

  &__container {
    padding: 0 16px;
    margin: 16px -16px;
    z-index: 3;
    display: flex;
    gap: 8px;
    overflow-y: scroll;
    -webkit-overflow-scrolling: touch;

    &::-webkit-scrollbar {
      display: none;
    }
  }
}
punkmachine commented 1 year ago

Код лишён логики проекта, в нём осталось только то, что относится к миксину*.

solarrust commented 1 year ago

@punkmachine очень жду этот рецепт! 🙏

solarrust commented 5 months ago

@punkmachine привет! Как успехи с этим рецептом?

punkmachine commented 5 months ago

@solarrust блин, у меня всё руки не доходят. я могу демку сделать и скинуть, чтобы кто-то описал её в статью, в целом можно сделать так.

solarrust commented 4 months ago

@punkmachine давай хотя бы так =)

Присылай сразу пулреквест, в нём и допишем текст статьи