gpt4 book ai didi

javascript - 循环遍历 jQuery 元素数组并在 View 中删除每个 'active' 元素?

转载 作者:行者123 更新时间:2023-12-02 16:56:51 24 4
gpt4 key购买 nike

我创建了一个元素数组,我想在窗口滚动时不断循环检查元素是否可见,如果可见,则将其设置为事件状态,然后我想从数组中删除该元素,最终进行检查查看数组是否为空,以便解除滚动事件的绑定(bind)。

目前我不知道应该如何删除这个元素?我目前正在使用:

var index = innerItems.index($thisEl.index());
innerItems.splice(index, 1);

然而,这似乎搞砸了我用来检查 View 中元素的函数,并且我的数组长度似乎从未改变。

任何人都可以建议我如何实现我的目标,即能够在每个元素变为事件状态时将其删除,直到我的数组为空并取消绑定(bind)滚动事件?另外,如果有人可以提供任何改进,那就太棒了。

Codepen http://codepen.io/styler/pen/zDJrx

JS

var $mainContainer = $('.main-container'),
innerItems = $mainContainer.children();

function isElementInViewport (el) {

//special bonus for those using jQuery
if (typeof jQuery === "function" && el instanceof jQuery) {
el = el[0];
}

var rect = el.getBoundingClientRect();

return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
);
}

function init() {
itemChecker();
}

init();

$(window).on('scroll.windowScroll', itemChecker);

function itemChecker() {
innerItems.each(function(i, element) {
console.log('Index', i);
console.log('Element', element);

var $thisEl = $(element);

// if isElementInViewport then add class is-active and remove from innerItems array
var inView = isElementInViewport(element);

if( inView ) {
$thisEl.addClass('is-active');

// Remove each element as it becomes ready/in view
var index = innerItems.index($thisEl.index());
innerItems.splice(index, 1);
}

console.log('innerItems length', innerItems.length);

if( innerItems.length === 0 ) {
$(window).off('scroll.windowScroll');
}
});
}

最佳答案

你的循环有缺陷。您不能使用 .each 循环数组并删除循环中的项目。循环将期望初始数量的项目,当涉及到被删除的索引时,它将吐出未定义的错误。

在这种情况下,您应该使用基本上从数组末尾到开头的逆循环。或者正常循环但更新索引变量,以防您从数组中删除该项目。

逆循环示例:

for (var i=arr.length;i--;) {
if (i%2==0) {
arr.splice(i, 1);
// We removed the item but this will not
// interfere with our counting as we are doing it in reverse
}
}

带有索引更新的正常循环示例:

for (var i=0,len=arr.length;i<len;i++) {
if (i%2==0) {
arr.splice(i, 1);
// We removed the item from the array and we need to decrease it's length by one
len--;
}
}

回到您的示例,这里是更新版本,forked codepen with fixed code here..

var $mainContainer = $('.main-container'),
innerItemsCache = $mainContainer.children(),
innerItemsVisible;

function isElementInViewport (el) {

//special bonus for those using jQuery
if (typeof jQuery === "function" && el instanceof jQuery) {
el = el[0];
}

var rect = el.getBoundingClientRect();

return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
);
}

function init() {
itemChecker();
}

init();

$(window).on('scroll.windowScroll', itemChecker);

function itemChecker() {
innerItemsVisible = [];
for (var i=innerItemsCache.length; i--;) {
console.log('Index', i);
console.log('Element', element);
var element = innerItemsCache[i];
var $thisEl = $(element);

// if isElementInViewport then add class is-active and remove from innerItems array
var inView = isElementInViewport(element);

if( inView ) {
$thisEl.addClass('is-active');

// Add elements that are visible
innerItemsVisible.push(innerItemsCache[i]);
} else {
$thisEl.removeClass('is-active');
}

console.log('innerItems length', innerItemsVisible.length);
}

if( innerItemsVisible.length === 0 ) {
$(window).off('scroll.windowScroll');
}

}

如您所见,我添加了一个缓存数组,因此您不必在每次迭代中搜索所有项目。同时,由于您已经循环遍历所有项目,因此更容易创建空数组并用可见项目填充它,如本工作示例所示。

关于javascript - 循环遍历 jQuery 元素数组并在 View 中删除每个 'active' 元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26106220/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com