npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@kricsleo/observer

v0.1.11

Published

easy to use intersection observer

Downloads

13

Readme

元素交叉状态检测

基于"了不起的"InterserctionObserver提供了检测子元素与容器之间交叉状态的方法, 没有这个 api 就没有这个库, 考虑到兼容性, 也许你需要先引入该 api 的polifill

仓库中包含reactvue的演示代码, 你可以在本地启动对应的demo查看.

Usage

Install

# for vue:
# npm install @kricsleo/observer-vue

# for react:
# npm install @kricsleo/observer-react

# core
npm install @kricsleo/observer

js


import { observerManager } from '@kricsleo/observer'

// 注册检测容器
// observerManager.registerObserver(key: string, options?: IKObserverOptions | undefined): KObserver | undefined;
observerManager.registerObserver('key', observerOptions);

// 检测子元素
// observerManager.observe(key: string, el: IObserveElement, value: IObserveChildValue): void;
observerManager.observe('key', el, obserserChildOptions);

React

import { useObserver, useObserverRoot } from "@kricsleo/observer-react";

// ...
  // 使用 hooks 注册检测容器
  useObserverRoot('key1', rootOptions);
  // 使用 hooks 注册被检测元素
  useObserver('key1', childEl, childOptions);
// ...

Vue

Used in Vue.directive

比较方便的一个用法是使用指令的方式来注册检测容器和被检测元素, 当元素满足条件时可以触发对应的回调函数

// First, import directive for vue.
import { vueObserverDirectives } from '@kricsleo/observer-vue'

// Second, register directive(you can chose your directive name).
Vue.directive('observe', vueObserverDirectives)
<!-- simplest usage -->
<section v-observe.key1:root>
  <div v-observe.key1="active"></div>
</section>

<script>
  export {
    methods: {
      active() {
        console.log('actived')
      }
    }
  }
</script>
<!-- complex usage -->
<section v-observe.key1:root>
  <section
    v-observe.key1="active1"
    v-observe.key2:root
    v-observe.key3:root="{threshold: 0.8, rootMargin: '10px 10px 10px 10px', root: null, timeout: 1500, useVisibility: true}"
  >
    <div
      v-observe.key1="active2"
      v-observe.key2="active3"
      v-observe.key3="{enter, leave, active: active4}"
    ></div>
  </section>
</section>

<script>
  export {
    methods: {
      active1() {
        console.log('actived1')
      },
      active2() {
        console.log('actived2')
      },
      active3() {
        console.log('actived3')
      },
      active4() {
        console.log('actived4')
      },
      enter() {
        console.log('entered')
      },
      leave() {
        console.log('leaved')
      },
    }
  }
</script>

如果有些时候不方便使用指令来注册检测器, 那么完全可以手动在任何地方任何时候注册检测器, 实际上指令只是一个语法糖, 帮助你手动完成注册和移除的工作而已.

<script>
  import { observerManager } from "@kricsleo/observer"
  export {
    mounted() {
      observerManager.registerObserver('key4')
      // Or register with custom options.
      // observerManager.registerObserver('key4', { threshold: 0.8, rootMargin: '10px 10px 10px 10px', root: null, timeout: 1500, useVisibility: true });
    },
    beforeDestroy() {
      // Do't forget to remove it, unless you want to want use it somewhere else.
      observerManager.deleteObserver('key4')
    }
  }
</script>

Api

检测容器

export interface IKObserverOptions {
  /**
   * 容器元素(同 IntersectionObserver 含义)
   * 当以指令方式注册时默认 root 是 挂载该指令的元素,
   * 当手动注册时默认 root 为 Document
   * @default Document
   */
  root?: Element | Document | null;
  /**
   * 容器元素边界盒的偏移值(同 IntersectionObserver 含义)
   * @default '0px 0px 0px 0px'
   */
  rootMargin?: string;
  /**
   * 进入容器最小面积比
   * @default 0
   */
  threshold?: number;
  /**
   * 是否响应页面可见/隐藏
   * @default false
   */
  useVisibility?: boolean;
  /**
   * 最短激活时间
   * @default 0
   */
  timeout?: number;
}

被检测元素

export interface IObserveCallbackValue {
  key: string;
  observer: KObserver;
  entry: IntersectionObserverEntry;
}

/**
 * 检测回调函数
 * 返回 {false} 则不再进行后续检测
 */
export type IObserveFn = (el: IObserveElement, value: IObserveCallbackValue) => void | false;

/**
 * 被检测元素配置
 * 当只传入一个函数时会作为 active 回调使用
 */
export type IObserveValue = IObserveFn | {
  /**
  * 完成检测回调
  */
  active?: IObserveFn;
  /**
  * 进入检测区域回调
  */
  enter?: IObserveFn;
  /**
  * 退出检测区域回调
  */
  leave?: IObserveFn;
}

How it works?

  • 一个元素可以被同时注册为多个检测容器
  • 一个元素可以被同时注册为多个被检测元素
  • 一个元素可以被同时注册为检测容器和被监测元素
  • 检测容器与被检测元素通过注册时指定的相同key被自动关联起来

Detect page visibility?

内置了对页面visibilitychange的监听, 当声明检测容器的时候使用了参数useVisibility: true那么该容器会把页面可见性(visibilityState)加入到检测可见性的逻辑中, 未使用该参数的容器不受影响

在某些运行环境中visibilitychange事件或者visibilityState值缺失或者不可信, 那么你也可以自定义自己的可见性判断逻辑, 在判定可见的时候调用observerManager.setVisibility(true), 不可见的时候调用observerManager.setVisibility(false) 则可以达到同样的效果(实际上内置的visibilitychange监听逻辑就是调用observerManager.setVisibility这个api来实现的),例如:

import { observerManager } from "@kricsleo/observer"

onPageShow() {
  observerManager.setVisibility(true);
}

onPageHide() {
  observerManager.setVisibility(false);
}

Use it for what?

例如通过视口交叉检测做代码的懒加载, 图片的懒加载, 或者做元素的进入退出动画, 或者记录元素的曝光状态, 或者更多我没想到的用法:)

feature

  • [x] support for Vue
  • [x] support for React
  • [x] support for js without any framework