繁体   English   中英

当元素可见时(滚动前),Intersection Observer 触发

[英]Intersection Observer trigger when element is visible (before scrolling)

我正在尝试与 Intersection Observer API 合作。 我有一个 function 在我的第一次迭代中工作。 基本逻辑是,如果用户向下滚动并从篮子中添加或删除项目,一旦篮子再次出现在视图中(因为它位于文档的顶部),那么我会触发 API 调用。

问题是它不会在滚动之前触发 function,如果项目可见或滚动后再次可见,我想触发它(第二部分正在工作)

这是原始的js:

var observerTargets = document.querySelectorAll('[id^="mini-trolley"]');
var observerOptions = {
    root: null, // null means root is viewport
    rootMargin: '0px',
    threshold: 0.01 // trigger callback when 1% of the element is visible
}
var activeClass = 'active';
var trigger = $('button');
var isCartItemClicked = false;

trigger.on('click', function() {
    isCartItemClicked = true;
});

function observerCallback(entries, observer) { 
    entries.forEach(entry => {
        if(entry.isIntersecting && isCartItemClicked){
            $(observerTargets).removeClass(activeClass);
            $(entry.target).addClass(activeClass);
            isCartItemClicked = false;
            console.log('isCartItemClicked and in view');
            // do my api call function here
        } else {
            $(entry.target).removeClass(activeClass);
        }
    });
}

var observer = new IntersectionObserver(observerCallback, observerOptions);
[...observerTargets].forEach(target => observer.observe(target));

我已经更新了这个,所以它现在检查该项目是否可见。 所以我更新了:

if(entry.isIntersecting && isCartItemClicked)

if((entry.isVisible || entry.isIntersecting) && isCartItemClicked)

据我了解,问题是观察者仅在滚动时触发,但 entry.isVisible 是观察者回调 function 的一部分。

我在这里做了一个 JSFIDDLE (它有 HTML 和 CSS 标记)。

是否可以修改代码。 奇怪的是, MDN 页面没有提到 isVisible 属性,但它显然是 function 的一部分。

在此处输入图像描述

这有点棘手,但可以通过创建一个由observerCallback设置的visible参数来完成。 有了这些,我们可以定义按钮触发器应该如何与每个相交条目的观察者回调分开处理。

 var observerTargets = document.querySelectorAll('[id^="mini-trolley"]'); var observerOptions = { root: null, // null means root is viewport rootMargin: '0px', threshold: 0.01 // trigger callback when 1% of the element is visible }; var activeClass = 'active'; var trigger = $('button'); var isCartItemClicked = false; var visible = true; trigger.on('click', function () { isCartItemClicked = true; if (visible) { console.log('fired from button'); [...observerTargets].filter(entry => isInViewport(entry)).forEach(entry => handleCartVisibleAndItemClicked(entry)); } }); function isInViewport(element) { const rect = element.getBoundingClientRect(); return ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth) ); } function handleCartVisibleAndItemClicked(entry) { $(entry).addClass(activeClass); // add API call here } function observerCallback(entries, observer) { visible = entries.some(entry => entry.isIntersecting); entries.forEach(entry => { if (entry.isIntersecting && isCartItemClicked) { console.log('fired from observer'); handleCartVisibleAndItemClicked(entry.target); isCartItemClicked = false; } else { $(entry.target).removeClass(activeClass); } }); } var observer = new IntersectionObserver(observerCallback, observerOptions); [...observerTargets].forEach(target => observer.observe(target));
 #content { height: 500px; }.active { background-color: orange; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="mini-trolley">Observer target1</div> <button>Top button</button> <div id="content"></div> <div id="mini-trolley">Observer target2</div> <button>Bottom button</button>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM