Как вставить класс в меню навигации при прокрутке при прокрутке определенных областей - PullRequest
0 голосов
/ 15 апреля 2020

Я пытаюсь вставить класс во время прокрутки определенных элементов с пользовательским атрибутом данных и в зависимости от этого атрибута вставить класс в меню навигации. В то время как .product (s) видимы в окне просмотра, я хочу, чтобы в меню появился активный класс, и когда атрибуты данных продуктов меняются.

Я хочу достичь чего-то подобного https://www.kunkalabs.com/mixitup/docs/configuration-object/

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>


    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.0/jquery.min.js"></script>

    <style>
        .product {
            display: block;
            width: 100%;
            margin-top: 20px;
            background-color: #f4f4f4;
            height:300px;
        }


    </style>

</head>
<body>

    <ul>
        <li class="menu-list" data-category="1">Category 1</li>
        <li class="menu-list" data-category="2">Category 2</li>
        <li class="menu-list" data-category="3">Category 3</li>
        <li class="menu-list" data-category="4">Category 4</li>
        <li class="menu-list" data-category="5">Category 5</li>
        <li class="menu-list" data-category="6">Category 6</li>
    </ul>



    <div class="wrapper">
        <div class="product" data-category-id="1">product 1</div>
        <div class="product" data-category-id="2">product 2</div>
        <div class="product" data-category-id="2">product 3</div>
        <div class="product" data-category-id="2">product 4</div>
        <div class="product" data-category-id="3">product 5</div>
        <div class="product" data-category-id="3">product 7</div>
        <div class="product" data-category-id="3">product 8</div>
        <div class="product" data-category-id="4">product 9</div>
        <div class="product" data-category-id="4">product 10</div>


    </div>


    <script>

            $.fn.isInViewport = function() {
                var elementTop = $(this).offset().top;
                var elementBottom = elementTop + $(this).outerHeight();

                var viewportTop = $(window).scrollTop();
                var viewportBottom = viewportTop + $(window).height();

                console.log(viewportBottom);

                return elementBottom > viewportTop && elementTop < viewportBottom;
            };

            $(window).on('scroll', function() {

                $('.product').each(function() {
                    var activeColor = $(this).data('category-id');

                    if ($(this).isInViewport()) {
                    /* $('menu-list' + activeColor).addClass('bold'); */
                    $('menu-list').css("height","600px");
                    } else {
                    /* $('menu-list' + activeColor).removeClass('bold'); */
                    $('.product').css("background-color","green");
                    }
                });
            });



    </script>
    ```

1 Ответ

0 голосов
/ 15 апреля 2020

Вместо прослушивания события прокрутки вы должны взглянуть на Intersection Observer (IO) . Это было разработано для решения таких проблем, как ваша. И это намного эффективнее, чем прослушивание событий прокрутки и последующее вычисление позиции самостоятельно.

Вот краткий пример того, как изменить список классов заголовка, как только секция прокручивается в поле зрения (или находится за пределами view)

Вы можете отрегулировать это, конечно, чтобы использовать правильные пороговые параметры для вашего IO, чтобы получить желаемый результат. И вам не нужно переключать список классов в заголовке, вы можете использовать любой элемент, который вам нравится. Я использовал простой Javascript в этом примере, но не стесняйтесь также использовать jQuery внутри обратного вызова ввода-вывода, если это облегчит вам задачу.

const sections = document.querySelectorAll('.products');
const config = {
  rootMargin: '0px',
  threshold: 0
};

const observer = new IntersectionObserver(function (entries, self) {
  entries.forEach(entry => {
    // Feel free to use jQuery here.
    var headerEl = document.querySelector('header');
    if (entry.isIntersecting) {
      // if the section is intersecting with viewport
      headerEl.classList.add(entry.target.dataset.header);
    } else {
      // section is not visible within viewport
      headerEl.classList.remove('products-header');
    }
  });
}, config);

sections.forEach(section => {
  observer.observe(section);
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

.g-100vh {
height: 100vh
}

header {
  min-height: 50px;
  position: fixed;
  background-color: green;
  width: 100%;
}
  
header.products-header {
  color: white;
  background-color: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<header>
 <p>Header Content </p>
</header>
<section class="g-100vh" style="background-color:darkblue;">
    <h1> NOT PRODUCTS </h1>
</section>

<section class="g-100vh products" style="background-color:lightgrey;">
    <h1> PRODUCTS </h1>
</section>

<section class="g-100vh" style="background-color:lightgrey;">
    <h1> NOT PRODUCTS </h1>
</section>

<section class="g-100vh" style="background-color:lightgrey;">
    <h1> NOT PRODUCTS </h1>
</section>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...