如何触发只有 wapoints 才能看到的 class
How to trigger a class that is only in view with wapoints
我有多个部分,每个部分都有 class blockList li
。我如何才能只触发视图中的当前 blockList li
项?目前,一旦任何列表项在视图中,它们都会在整个页面中触发,即使它们不在视图中也是如此。
下面的代码片段说明了我遇到的问题。
$('.blockList').waypoint(function() {
$('.blockList li').each(function(index) {
setTimeout(()=>{
$(this).addClass('active');
}, 200*index);
});
}, {
offset: '60%'
});
#blue, #red {
width: 100%;
height: 100vh;
}
#blue {
background: blue;
}
#red {
background: red;
}
.blockList {
margin: 15px 0;
text-align: left;
}
.blockList li {
font-size: 1rem;
color: #FFF;
margin: 20px 0;
opacity: 0;
-webkit-transition: ease 0.4s;transition: ease 0.4s;
-webkit-transform: translateY(-15px);transform: translateY(-15px);
}
.blockList li.active {
opacity: 1;
-webkit-transform: translateY(0px);transform: translateY(0px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/waypoints/4.0.1/jquery.waypoints.min.js"></script>
<section id="blue">
<ul class="blockList">
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
</section>
<section id="red">
<ul class="blockList">
<li>E</li>
<li>F</li>
<li>G</li>
<li>H</li>
</ul>
</section>
您正在为所有项目添加活动 class。
$('.blockList li').each(function(index) {
setTimeout(()=>{
$(this).addClass('active');
}, 200*index);
});
TL:TR
简而言之。您基本上向每个列表元素添加了两次 active class 。由于您是在开始时添加它,然后在 60% 偏移处添加它。
它遍历所有 li 并激活 class。因此,不必考虑它,因为它不会增加负载。
一个解决方案可能是获取第二个对象在浏览器中的位置,或者制作一个紧凑的系统来检查所有对象,并将其放置在数组中。
因此它将检查其 位置 -> 滚动检查是否到达任何元素 -> 如果到达,将活动 class 添加到对应的 ID。
var p = $( "#red" ).position;
var Positions = {top: p.top};
然后得到你的中心 window 位置
类似于:
jQuery.fn.center = function () {
this.css("position","absolute");
this.css("top", Math.max(0, (($(window).height() - $(this).outerHeight()) / 2) +
$(window).scrollTop()) + "px");
this.css("left", Math.max(0, (($(window).width() - $(this).outerWidth()) / 2) +
$(window).scrollLeft()) + "px");
return this;
}
然后比较它们,如果到达元素。
然后获取它的id,在#red li
后面加上.active
class,不是一般的li.
遇到这种情况我会怎么做:
var global_list = {}; var elemCount = 0;
$(document).ready(function() {
//call initFunc, after its complete, call elimination (so it would check on load) and then set on scroll.
initFunc(function() {
elimination();
$(document).on('scroll', function() { elimination() });
});
//This function is basicaly your startup.
function initFunc(int) {
$('.blockList').each(function() {
var p = $(this).position(); //Lets get its position.
var id = $(this).attr('id'); //Lets get its ID
global_list[id] = p.top; //Lets asign ID -> topPosition, so { first: 8 }...
elemCount++;
});
int();
}
//This assigns needed stuff for allready reached objects.
function elimination() {
if(elemCount != 0) { //Did we allready show all elements?
var cb = $(this).scrollTop() + ($(this).height()), ct = $(this).scrollTop(); //Gets top position, and bottom.
var cP = ct + ((cb - ct)/2); //Gets your center point of viewport - ad half screen size to top;
for(var k in global_list) { //Loop trough all element that are left and see if we did scroll.
if(global_list[k] <= cP) { //Lets check if user scolled to it.
var ic=0;
$('#'+k+' li').each(function() {
setTimeout(()=>{
$(this).addClass('active');
}, 200*ic);
ic++
});
delete global_list[k]; //Lets delete allready assigned classes
elemCount--; //Decreses elements count, so eventualy once all reached, it becomes 0;
}
}
}
}
});
#first {
height: 1000px;
}
#second {
height: 1000px;
}
.beatiful {
background: yellow;
}
.div_div li {
font-size: 1rem;
color: #000;
margin: 20px 0;
opacity: 0;
-webkit-transition: ease 0.4s;transition: ease 0.4s;
-webkit-transform: translateY(-15px);transform: translateY(-15px);
}
.div_div li.active {
opacity: 1;
-webkit-transform: translateY(0px);transform: translateY(0px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class='div_div' id='first'>
<ul class="blockList" id='first'>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
</div>
<div class='div_div' id='second'>
<ul class="blockList" id='second'>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
</div>
我有多个部分,每个部分都有 class blockList li
。我如何才能只触发视图中的当前 blockList li
项?目前,一旦任何列表项在视图中,它们都会在整个页面中触发,即使它们不在视图中也是如此。
下面的代码片段说明了我遇到的问题。
$('.blockList').waypoint(function() {
$('.blockList li').each(function(index) {
setTimeout(()=>{
$(this).addClass('active');
}, 200*index);
});
}, {
offset: '60%'
});
#blue, #red {
width: 100%;
height: 100vh;
}
#blue {
background: blue;
}
#red {
background: red;
}
.blockList {
margin: 15px 0;
text-align: left;
}
.blockList li {
font-size: 1rem;
color: #FFF;
margin: 20px 0;
opacity: 0;
-webkit-transition: ease 0.4s;transition: ease 0.4s;
-webkit-transform: translateY(-15px);transform: translateY(-15px);
}
.blockList li.active {
opacity: 1;
-webkit-transform: translateY(0px);transform: translateY(0px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/waypoints/4.0.1/jquery.waypoints.min.js"></script>
<section id="blue">
<ul class="blockList">
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
</section>
<section id="red">
<ul class="blockList">
<li>E</li>
<li>F</li>
<li>G</li>
<li>H</li>
</ul>
</section>
您正在为所有项目添加活动 class。
$('.blockList li').each(function(index) {
setTimeout(()=>{
$(this).addClass('active');
}, 200*index);
});
TL:TR
简而言之。您基本上向每个列表元素添加了两次 active class 。由于您是在开始时添加它,然后在 60% 偏移处添加它。
它遍历所有 li 并激活 class。因此,不必考虑它,因为它不会增加负载。
一个解决方案可能是获取第二个对象在浏览器中的位置,或者制作一个紧凑的系统来检查所有对象,并将其放置在数组中。 因此它将检查其 位置 -> 滚动检查是否到达任何元素 -> 如果到达,将活动 class 添加到对应的 ID。
var p = $( "#red" ).position;
var Positions = {top: p.top};
然后得到你的中心 window 位置 类似于:
jQuery.fn.center = function () {
this.css("position","absolute");
this.css("top", Math.max(0, (($(window).height() - $(this).outerHeight()) / 2) +
$(window).scrollTop()) + "px");
this.css("left", Math.max(0, (($(window).width() - $(this).outerWidth()) / 2) +
$(window).scrollLeft()) + "px");
return this;
}
然后比较它们,如果到达元素。
然后获取它的id,在#red li
后面加上.active
class,不是一般的li.
遇到这种情况我会怎么做:
var global_list = {}; var elemCount = 0;
$(document).ready(function() {
//call initFunc, after its complete, call elimination (so it would check on load) and then set on scroll.
initFunc(function() {
elimination();
$(document).on('scroll', function() { elimination() });
});
//This function is basicaly your startup.
function initFunc(int) {
$('.blockList').each(function() {
var p = $(this).position(); //Lets get its position.
var id = $(this).attr('id'); //Lets get its ID
global_list[id] = p.top; //Lets asign ID -> topPosition, so { first: 8 }...
elemCount++;
});
int();
}
//This assigns needed stuff for allready reached objects.
function elimination() {
if(elemCount != 0) { //Did we allready show all elements?
var cb = $(this).scrollTop() + ($(this).height()), ct = $(this).scrollTop(); //Gets top position, and bottom.
var cP = ct + ((cb - ct)/2); //Gets your center point of viewport - ad half screen size to top;
for(var k in global_list) { //Loop trough all element that are left and see if we did scroll.
if(global_list[k] <= cP) { //Lets check if user scolled to it.
var ic=0;
$('#'+k+' li').each(function() {
setTimeout(()=>{
$(this).addClass('active');
}, 200*ic);
ic++
});
delete global_list[k]; //Lets delete allready assigned classes
elemCount--; //Decreses elements count, so eventualy once all reached, it becomes 0;
}
}
}
}
});
#first {
height: 1000px;
}
#second {
height: 1000px;
}
.beatiful {
background: yellow;
}
.div_div li {
font-size: 1rem;
color: #000;
margin: 20px 0;
opacity: 0;
-webkit-transition: ease 0.4s;transition: ease 0.4s;
-webkit-transform: translateY(-15px);transform: translateY(-15px);
}
.div_div li.active {
opacity: 1;
-webkit-transform: translateY(0px);transform: translateY(0px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class='div_div' id='first'>
<ul class="blockList" id='first'>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
</div>
<div class='div_div' id='second'>
<ul class="blockList" id='second'>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
</div>