Поместите ребенка поверх штабелируемых секций

Я хочу, чтобы .square div всегда был сверху, поэтому визуально кажется, что следующий раздел со своим собственным .square скользит вверх, а .square останавливается точно на том же месте, где находился квадрат предыдущего раздела.

Следующий код делает именно это:

$(document).ready(function() {
  const sections = document.querySelectorAll('.make-sticky');

  const observer = new IntersectionObserver(entries => {
    entries.forEach(({ target, isIntersecting }) => {
      if (isIntersecting) {
        $(target).addClass('sticky-section');
      } else {
        $(target).removeClass('sticky-section');
      }
    });
  }, {
    root: null,
    rootMargin: '0px',
    threshold: 0.1 // Trigger when 10% of the element is visible
  });

  sections.forEach((section) => {
    observer.observe(section);
  });
});
.scrollable {
  border: 5px solid red;
  position: relative;

  .make-sticky {
    position: relative;
    height: 100vh;
    padding: 20px;
    box-sizing: border-box;

    .line {
      position: absolute;
      left: 20px;
      top: 0;
      bottom: 0;
      width: 2px;
      background: black;
    }

    .square {
      position: absolute;
      left: 10px;
      width: 20px;
      height: 20px;
      background: transparent;
      border: 2px solid red;
      top: 25%; /* Adjust this percentage based on your design */
      z-index: 1;
    }

    p {
      margin-top: 50vh; /* Center text vertically */
    }

    &.sticky-section {
      position: -webkit-sticky;
      position: sticky;
      top: 0;
    }
  }
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.2/jquery.min.js"></script>
        <div class = "scrollable">
            <section class = "make-sticky" style = "background: cyan" id = "section1">
                <div class = "line"></div>
                <div class = "square"></div>
                <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. 1111111111111111111111 Esse tempora facere beatae, harum voluptatibus eveniet explicabo corporis suscipit error sit nostrum minima ducimus, perspiciatis aperiam blanditiis labore iure quidem est.</p>
            </section>

            <section class = "make-sticky" style = "background: salmon" id = "section2">
                <div class = "line"></div>
                <div class = "square"></div>
                <p>Quod magni natus dignissimos, voluptate incidunt ddddddddddddddddddddddddddddd reiciendis culpa labore nihil veritatis quasi eum exercitationem, laboriosam impedit tenetur deleniti itaque? Velit atque provident labore corrupti libero eius nostrum. Distinctio, qui pariatur?</p>
            </section>

            <section class = "make-sticky" style = "background: yellowgreen" id = "section3">
                <div class = "line"></div>
                <div class = "square"></div>
                <p>Quod magni natus dignissimos, voluptate incidunt 222222222222222222222222 reiciendis culpa labore nihil veritatis quasi eum exercitationem, laboriosam impedit tenetur deleniti itaque? Velit atque provident labore corrupti libero eius nostrum. Distinctio, qui pariatur?</p>
            </section>

            <section class = "make-sticky" style = "background: orange" id = "section3">
                <div class = "line"></div>
                <div class = "square"></div>
                <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. 3333333333333333333333333333 Esse tempora facere beatae, harum voluptatibus eveniet explicabo corporis suscipit error sit nostrum minima ducimus, perspiciatis aperiam blanditiis labore iure quidem est.</p>
            </section>

            <section class = "make-sticky" style = "background: blue" id = "section4">
                <div class = "line"></div>
                <div class = "square"></div>
                <p>Quod magni natus dignissimos, voluptate 4444444444444444444444444444 incidunt reiciendis culpa labore nihil veritatis quasi eum exercitationem, laboriosam impedit tenetur deleniti itaque? Velit atque provident labore corrupti libero eius nostrum. Distinctio, qui pariatur?</p>
            </section>
        </div>

но раздел СЛЕДУЮЩИЙ закрывает предыдущий квадрат, когда он «скользит вверх».

Ни для одного родительского элемента моего кода не установлен z-индекс, поэтому я хотел его использовать, но он просто не работает.

Что я могу сделать, чтобы это заработало?

Я предполагаю, что вы имеете в виду, что каждая секция скользит вверх по предыдущей... верно?

Paulie_D 20.07.2024 19:26

Но я не думаю, что вы сможете сделать это с помощью вашего текущего метода, z-index это не проблема, поскольку разделы не имеют общего контекста стекирования.

Paulie_D 20.07.2024 19:36
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
83
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я не уверен, что это на 100% то, что вы ищете, но это может вас приблизить.

.scrollable {
  border: 5px solid red;
  position: relative;
}

.make-sticky {
  position: relative;
  height: 100vh;
  padding: 20px;
  box-sizing: border-box;
}

.line {
  position: absolute;
  left: 20px;
  top: 0;
  bottom: 0;
  width: 2px;
  background: black;
}

.square {
  position: sticky;
  top: 25%;
  left: 10px;
  width: 20px;
  height: 20px;
  background: transparent;
  border: 2px solid red;
  z-index: 10; 
}

.make-sticky p {
  margin-top: 50vh; 
}
   <div className = "scrollable">
    <section class = "make-sticky" id = "section1">
      <div class = "line"></div>
      <div class = "square"></div>
      <p>Lorem ipsum dolor sit amet</p>
    </section>

    <section class = "make-sticky" id = "section2">
      <div class = "line"></div>
      <div class = "square"></div>
      <p>Quod magni natus dignissimos</p>
    </section>

    <section class = "make-sticky" id = "section3">
      <div class = "line"></div>
      <div class = "square"></div>
      <p>Quod magni natus dignissimos</p>
    </section>
  </div>

Вы можете сделать это, создав отдельный div, содержащий все квадраты/заголовки. Это div охватит весь .scrollable div. Затем вы можете использовать margin на square, чтобы выровнять его по соответствующему разделу.

Поскольку высота разделов .make-sticky будет использоваться для расчета поля, используются пользовательские переменные CSS, поэтому всякий раз, когда вы меняете высоту раздела, квадраты автоматически выравниваются.

В этом случае вам не нужен z-index, так как квадраты уже расположены последовательно, поэтому они будут перекрываться соответствующим образом (индекс z понадобится, если вы хотите, чтобы первый квадрат перекрывал второй или последний квадрат).

Кроме того, при закреплении позиции вы не можете использовать лево/право для позиционирования квадрата после того, как вы указали верхнее значение, в котором элемент прилипает. Итак, используйте поле для его позиционирования.

:root {
  --sticky-section-height: 100vh;
}

* {
  box-sizing: border-box;
}

.scrollable {
  border: 5px solid red;
  position: relative;
}

.make-sticky {
  height: var(--sticky-section-height);
  box-sizing: border-box;
  border-bottom: 1px solid green;
  padding: 10px;
  background-color: var(--clr);
  position: relative;
}

.line {
  position: absolute;
  left: 20px;
  top: 0;
  bottom: 0;
  width: 2px;
  height: 100%;
  background: black;
}

.sticky-container {
  height: 100%;
  width: 100%;
  position: absolute;
  top: 0;
  z-index: 10;
  border: 2px solid rgb(0, 21, 255);
}

.square {
  position: sticky;
  color: white;
  top: 0px;
  /* Margin used to position the element horizontally*/
  margin-left: 10px;
  margin-bottom: calc((var(--sticky-section-height) - 20px));
  width: 20px;
  height: 20px;
  background: black;
  border: 2px solid red;
  /* Adjust this percentage based on your design */
}

p {
  margin-top: 50vh;
  /* Center text vertically */
}
<div class = "scrollable">

  <div class = "sticky-container">
    <div class = "square">1</div>
    <div class = "square">2</div>
    <div class = "square">3</div>
  </div>

  <section class = "make-sticky" style = "--clr: green" id = "section1">
    <div class = "line"></div>
    <p>Lorem ipsum dolor sit amet</p>
  </section>

  <section class = "make-sticky" style = "--clr: orange" id = "section2">
    <div class = "line"></div>
    <p>Quod magni natus dignissimos</p>
  </section>

  <section class = "make-sticky" style = "--clr: cyan" id = "section3">
    <div class = "line"></div>
    <p>Quod magni natus dignissimos</p>
  </section>
</div>

Я не думал (мне плохо), что JS здесь понадобится, поэтому пропустил эту часть. .sticky-section добавляется динамически с помощью jQuery.

Greg Bialowas 21.07.2024 15:06

это желаемый результат?

Aniket Pandey 21.07.2024 18:40

Нет, мне нужно, чтобы квадраты перекрывали друг друга, как это было показано изначально, а не толкали их вверх. Хотя это тоже выглядит круто :). Самое главное, мне нужны разные цвета фона на этих участках. Благодарю вас за ваше усилие!

Greg Bialowas 22.07.2024 09:02

@GregBialowas Хорошо, понял... Я обновил свой ответ, чтобы сделать то же самое.

Aniket Pandey 22.07.2024 12:43

Выглядит неплохо, но мне нужен цвет фона раздела. Каждый раздел будет иметь свой цвет — и ЭТО вызывает проблему. Каждая (следующая) секция закрывает площадь предыдущей секции.

Greg Bialowas 22.07.2024 13:41
Ответ принят как подходящий

Я добавил элемент div «плавающий квадрат», который становится видимым, когда первый раздел «make-sticky» достигает верхней части окна: 0, и гаснет, когда последний раздел делает то же самое.

$(document).ready(function() {
  const sections = document.querySelectorAll('.make-sticky');
  const floatingSquare = $('.floating-square');
  let scrollingDown = true;

  // Function to update floatingSquare visibility
  function updateFloatingSquareVisibility() {
    const firstSection = sections[0];
    const lastSection = sections[sections.length - 1];

    const firstSectionRect = firstSection.getBoundingClientRect();
    const lastSectionRect = lastSection.getBoundingClientRect();

    if (scrollingDown) {
      if (firstSectionRect.top <= 0) {
        floatingSquare.show();
      }
      if (lastSectionRect.top <= 25) {
        floatingSquare.hide();
      }
    } else {
      if (lastSectionRect.top > 25) {
        floatingSquare.show();
      }
      if (firstSectionRect.top > 0) {
        floatingSquare.hide();
      }
    }
  }

  // Intersection Observer to monitor sections
  const observer = new IntersectionObserver(entries => {
    entries.forEach(({ target, isIntersecting }) => {
      if (isIntersecting) {
        $(target).addClass('sticky-section');
      } else {
        $(target).removeClass('sticky-section');
      }
    });
  }, {
    root: null,
    rootMargin: '0px',
    threshold: [0, 0.25] // Trigger when 25% of the element is visible
  });

  sections.forEach((section) => {
    observer.observe(section);
  });

  // Event listener for scroll to determine scroll direction
  let lastScrollTop = 0;
  $(window).on('scroll', function() {
    const scrollTop = $(this).scrollTop();
    scrollingDown = scrollTop > lastScrollTop;
    lastScrollTop = scrollTop;
    updateFloatingSquareVisibility();
  });

  // Initial check for visibility
  updateFloatingSquareVisibility();
});
.scrollable {
  border: 3px solid darkblue;
  position: relative;

  .make-sticky {
    position: relative;
    height: 100vh;
    padding: 20px;
    box-sizing: border-box;
    margin-top: -22px;
    z-index: 1;

    .line {
      position: absolute;
      left: 20px;
      top: 0;
      bottom: 0;
      width: 2px;
      background: black;
    }

    .square {
      position: absolute;
      left: 10px;
      width: 20px;
      height: 20px;
      background: transparent;
      border: 2px solid red;
      top: 25%; /* Adjust this percentage based on your design */
      z-index: 1;
    }

    p {
      margin-top: 50vh; /* Center text vertically */
    }

    &.sticky-section {
      position: -webkit-sticky;
      position: sticky;
      top: 0;
    }
  }

  .floating-square {
    position: sticky;
    top: 25%; /* Match the position of the square */
    margin-left: 10px; /* Offset from the square for visibility */
    width: 20px;
    height: 20px;
    background: transparent;
    border: 2px solid red;
    z-index: 2; /* Ensure it is on top */
    display: none;
  }
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script>
<div class = "scrollable">
    <div class = "floating-square"></div>
    <section class = "make-sticky" style = "background: cyan" id = "section1">
        <div class = "line"></div>
        <div class = "square"></div>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. 1111111111111111111111 Esse tempora facere beatae, harum voluptatibus eveniet explicabo corporis suscipit error sit nostrum minima ducimus, perspiciatis aperiam blanditiis labore iure quidem est.</p>
    </section>

    <section class = "make-sticky" style = "background: salmon" id = "section2">
        <div class = "line"></div>
        <div class = "square"></div>
        <p>Quod magni natus dignissimos, voluptate incidunt 22222222222222 reiciendis culpa labore nihil veritatis quasi eum exercitationem, laboriosam impedit tenetur deleniti itaque? Velit atque provident labore corrupti libero eius nostrum. Distinctio, qui pariatur?</p>
    </section>

    <section class = "make-sticky" style = "background: yellowgreen" id = "section3">
        <div class = "line"></div>
        <div class = "square"></div>
        <p>Quod magni natus dignissimos, voluptate incidunt 3333333333333333 reiciendis culpa labore nihil veritatis quasi eum exercitationem, laboriosam impedit tenetur deleniti itaque? Velit atque provident labore corrupti libero eius nostrum. Distinctio, qui pariatur?</p>
    </section>

    <section class = "make-sticky" style = "background: orange" id = "section4">
        <div class = "line"></div>
        <div class = "square"></div>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. 44444444444444 Esse tempora facere beatae, harum voluptatibus eveniet explicabo corporis suscipit error sit nostrum minima ducimus, perspiciatis aperiam blanditiis labore iure quidem est.</p>
    </section>

    <section class = "make-sticky" style = "background: blue" id = "section5">
        <div class = "line"></div>
        <div class = "square"></div>
        <p>Quod magni natus dignissimos, voluptate 5555555555 incidunt reiciendis culpa labore nihil veritatis quasi eum exercitationem, laboriosam impedit tenetur deleniti itaque? Velit atque provident labore corrupti libero eius nostrum. Distinctio, qui pariatur?</p>
    </section>

</div>

Другие вопросы по теме