#javascript #html #jquery #css
Вопрос:
У меня есть горизонтальный скроллер, где каждый div занимает 100 Вт. Я хочу добавить активный класс в пункт меню, когда этот раздел меню находится в поле зрения.
Поэтому, например, когда отображается #content-one, я хочу добавить класс active в data-id=»content-one». А затем, когда появится #content-two, я хочу удалить класс из content-one и добавить его в content-two и т. Д.
Мой скрипт в настоящее время по какой-то причине добавляет активный к последнему контенту… Любая помощь была бы признательна в этом, спасибо.
Кодовый код здесь и пример ниже.
jQuery(document).ready(function ($) {
function isOnScreen(elem) {
// if the element doesn't exist, abort
if (elem.length == 0) {
return;
}
var $window = jQuery(window);
var viewport_top = $window.scrollTop();
var viewport_height = $window.height();
var viewport_bottom = viewport_top viewport_height;
var $elem = jQuery(elem);
var top = $elem.offset().top (viewport_height / 2);
var height = $elem.height();
var bottom = top height;
return (top >= viewport_top amp;amp; top < viewport_bottom);
}
$('.content-wrap').scroll(function () {
$('.nav-item').each(function () {
var _this = $(this);
var _data_id = _this.attr('data-id');
if (isOnScreen($('div#' _data_id))) {
$('.nav-item').removeClass('active')
_this.addClass('active')
}
});
});
// Horizontal Scroller -- IGNORE THIS
var width = $(window).width();
if (width >= 1200) {
(function () {
function scrollHorizontally(e) {
e = window.event || e;
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
document.getElementById('content-wrap').scrollLeft -= (delta * 80); // Multiplied by 40
e.preventDefault();
}
if (document.getElementById('content-wrap').addEventListener) {
// IE9, Chrome, Safari, Opera
document.getElementById('content-wrap').addEventListener('mousewheel', scrollHorizontally, false);
// Firefox
document.getElementById('content-wrap').addEventListener('DOMMouseScroll', scrollHorizontally, false);
} else {
// IE 6/7/8
document.getElementById('content-wrap').attachEvent('onmousewheel', scrollHorizontally);
}
})();
}
});
.content-wrap {
overflow-y: hidden;
overflow-x: auto;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
}
.content {
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
height: 50vh;
padding-left: 70px;
background-color: grey;
}
h1 {
width: 100vw;
border: 1px solid red;
}
.active {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<li class="nav-item" data-id="content-one">item1</li>
<li class="nav-item" data-id="content-two">item2</li>
<li class="nav-item" data-id="content-three">item3</li>
<li class="nav-item" data-id="content-four">item4</li>
</nav>
<!-- When content-one is in view, add class active to the nav item with a matching data-id value... do this for each content div/nav item -->
<div class="content-wrap" id="content-wrap">
<div class="content" id="content-one">
<h1>This scrolls horizontal 1</h1>
</div>
<div class="content" id="content-two">
<h1>This scrolls horizontal 2</h1>
</div>
<div class="content" id="content-three">
<h1>This scrolls horizontal 3</h1>
</div>
<div class="content" id="content-four">
<h1>This scrolls horizontal 4</h1>
</div>
</div>
Ответ №1:
Я удалил другой код, чтобы сосредоточиться на вашем прямом вопросе.
Так, например, когда #content-one
в поле зрения, я хочу добавить активный класс data-id="content-one"
. А затем , когда #content-two
появится в поле зрения, я хочу удалить класс content-one
и добавить его content-two
и т. Д.
Вам нужно получить левое и правое положения элемента и окна, а затем проверить их положение относительно друг друга при прокрутке с помощью условного обозначения.
$('#content-wrap').on('resize scroll', function() {
$('.content').each(function() {
// add 70 for padding
let elLeft = $(this).offset().left 70
let elRight = $(this).offset().left $(this).width()
let pgLeft = 0
// add 70 for padding
let pgRight = $(window).width() 70
elLeft < pgRight ?
// add active
$('.nav-item[data-id=' $(this).attr('id') ']').addClass('active') : null
elRight < pgLeft || elRight > pgRight ?
// remove active
$('.nav-item[data-id=' $(this).attr('id') ']').removeClass('active') : null
});
});
.content-wrap {
overflow-y: hidden;
overflow-x: auto;
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
}
.content {
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
height: 50vh;
padding-left: 75px;
background-color: grey;
}
h1 {
width: 100vw;
border: 1px solid red;
}
.active {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<li class="nav-item active" data-id="content-one">item1</li>
<li class="nav-item" data-id="content-two">item2</li>
<li class="nav-item" data-id="content-three">item3</li>
<li class="nav-item" data-id="content-four">item4</li>
</nav>
<!-- When content-one is in view, add class active to the nav item with a matching data-id value... do this for each content div/nav item -->
<div class="content-wrap" id="content-wrap">
<div class="content" id="content-one">
<h1>This scrolls horizontal 1</h1>
</div>
<div class="content" id="content-two">
<h1>This scrolls horizontal 2</h1>
</div>
<div class="content" id="content-three">
<h1>This scrolls horizontal 3</h1>
</div>
<div class="content" id="content-four">
<h1>This scrolls horizontal 4</h1>
</div>
</div>