【问题标题】:How to reference dynamically created intersection observers in a JS library如何在 JS 库中引用动态创建的交叉点观察器
【发布时间】:2020-11-09 20:47:15
【问题描述】:

我正在尝试使用 this constructor pattern boilerplate 在网络上构建一个微型 JS 库来模拟 InDesign text threading。这个想法是用户以所需的顺序提供函数 DOM 选择器,例如

var thread=new TextThread(['#container1','#container2']);
thread.build();

然后库从那里将第一个容器的文本内容拆分为每个单词的 span。当单词不在视野范围内时,库会按顺序将其移动到以下容器中。

这就是 IntersectionObserver 的用武之地: 我需要为每个提供给构造函数的容器分配一个观察者,然后让它观察其中的跨度。当 span 不在视野范围内时,它会触发观察者回调,该回调应该使用 .takeRecords() 方法遍历所有观察者,以检查每个容器中哪些 span 不在视野范围内。我已经让观察者触发他们的回调没有问题,但问题是在回调中引用所有观察者

我尝试的是从样板文件中将数组变量存储在自执行函数中,然后在构建构造函数时,它将观察者推送到该数组。

var observers=[];

var Constructor = function (selectors) {
    /*placeholder for code that selects and assigns the containers*/

    containers.forEach((item, i) =>{
        var options={
            root: item,
            rootMargin: '0px',
            threshold: 1.0
        }
        var newObserver=new IntersectionObserver(callback,options);
        observers.push(newObserver);
    })
};

那么当文本被word分割成spans时

words.forEach((word,w) =>{
observers[ current container index ].observe(word); });

在回调中,触发回调的观察者的条目是可见的。但是,如果我尝试使用我的观察者数组变量引用 other 观察者,则 takeRecords() 返回一个空数组。这是我正在测试的回调:

function callback(entries){
    //the entries for the observer firing the callback are returning correctly
    console.log(entries)
    //the forEach below doesn't work though. It returns an empty array for each observer.
observers.forEach((item, i) => {
    console.log(item.takeRecords())
});
}

【问题讨论】:

  • 请贴出callback的代码。另外,我不明白您为什么需要引用其他观察者?
  • @Bergi 我现在添加了回调代码。我想引用其他观察者,因为我希望能够查看 每个 容器中的哪些跨度已经消失,而不仅仅是触发回调的那个,因为我的操作接受回调有可能将更多元素移出视野。没错,这会触发另一个回调,但我正在查看是否可以一次处理所有回流,以便完全控制时间。
  • 我认为你引用其他观察者就好了。它返回一个空数组,因为还没有更多的交集记录。您应该首先考虑到条目passed to the callback,而不是调用takeRecords method
  • @Bergi 让我怀疑它是否正确返回的是 takeRecords 返回空即使对于触发回调的观察者,同时记录条目(请参阅编辑的回调)正确返回状态改变的元素数组
  • 工作正常,as documented: "takeRecords() 返回一个 IntersectionObserverEntry 对象数组,每个目标元素对应一个自上次以来经历了交叉点变化的对象检查交叉点,通过调用此方法或通过自动调用对观察者的回调进行显式检查。注意:如果您使用回调来监视这些更改,则不要'不需要调用这个方法。"

标签: javascript class constructor scope intersection-observer


【解决方案1】:

在回调中,触发回调的观察者的条目是可见的。但是,如果我尝试使用我的观察者数组变量引用其他观察者,takeRecords() 将返回一个空数组——即使对于触发回调的观察者也是如此!

一切正常,as documented:

takeRecords() 返回IntersectionObserverEntry 的数组 对象,每个目标元素都经历了一个 自上次检查交叉口后的交叉口变化, 通过调用此方法或显式调用 自动调用观察者的回调。

注意:如果你使用回调来监控这些变化,你不需要 调用这个方法。

(强调我的)

【讨论】:

    【解决方案2】:

    您将观察者声明为该类的私有变量。您需要将其公开或静态。我不熟悉你的设计,但我建议make it static。从架构的角度来看,使这些静态对我来说更有意义

    【讨论】:

    • 不,它们应该是特定于实例的,而不是静态的。
    • 如果你在页面上运行多个线程,当然可以。
    • 是的,当然,否则TextThread 不会是一个可以被多次实例化的类。
    • 我不会说拥有一个类需要你做(或者如果你做的话是必需的)它的多个实例。我经常使用单个实例来封装代码。例如,处理 DOM 上的操作的 UIController 可以是一个单例类,它确保对 DOM 的每个操作都被考虑或不传播到整个代码库。但话又说回来,这真的取决于你需要做什么。
    • "我经常使用单个实例来封装代码。" - 那么您可能不应该在 javascript 中使用 class。对于单身人士来说,一个普通的对象就足够了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-20
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    • 2022-10-19
    • 1970-01-01
    相关资源
    最近更新 更多