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 🙏

© 2026 – Pkg Stats / Ryan Hefner

parcelpanel-polling-checker

v1.1.0

Published

React Hooks for visibility tracking and global object detection

Readme

React Hooks - Cross-sell 可见性检测工具

概述

React Hooks工具集提供了智能化的全局对象检测和可见性跟踪功能,专门用于与Cross-sell Tracking SDK配合使用。

🔧 可用的Hooks

1. useSmartVisibleCrossSellTracker (推荐)

智能可见性跟踪器,具有以下特性:

  • ✅ 自动检测元素初始可见性
  • ✅ 智能曝光检测(避免不必要的Observer创建)
  • ✅ 自动等待CrossSellTracker初始化
  • ✅ 防重复触发机制
import { useSmartVisibleCrossSellTracker } from "@packages/polling-checker"

const SmartCard = () => {
  const { ref, reset } = useSmartVisibleCrossSellTracker({
    onViewed: () => {
      console.log("智能检测:元素已曝光!")
      window.crossSellTracker?.logViewed("smart-uuid")
    },
    enabled: true,
    rootMargin: "0px",
    threshold: 0.5 // 50%可见时触发
  })

  return (
    <div ref={ref} className="smart-card">
      <h3>智能推荐卡片</h3>
      <button onClick={reset}>重置状态</button>
    </div>
  )
}

2. useVisibleCrossSellTracker

基础可见性跟踪器:

  • ✅ 标准IntersectionObserver功能
  • ✅ 自动等待CrossSellTracker初始化
  • ✅ 支持自定义配置
import { useVisibleCrossSellTracker } from "@packages/polling-checker"

const BasicCard = () => {
  const { ref, reset } = useVisibleCrossSellTracker({
    onViewed: () => {
      window.crossSellTracker?.logViewed("basic-uuid")
    },
    enabled: true,
    threshold: 0.1, // 10%可见时触发
    rootMargin: "50px" // 提前50px触发
  })

  return <div ref={ref}>基础跟踪内容</div>
}

3. useCrossSellTracker

CrossSellTracker专用加载检测器:

  • ✅ 等待全局CrossSellTracker对象加载
  • ✅ 300ms检测间隔,最多5次重试
  • ✅ 简化的API
import { useCrossSellTracker } from "@packages/polling-checker"

const TrackerListener = () => {
  useCrossSellTracker(() => {
    console.log("CrossSellTracker已加载!")
    // 可以安全使用tracker了
    window.crossSellTracker?.logViewed("ready-uuid")
  }, true) // enabled

  return <div>等待CrossSellTracker初始化...</div>
}

4. useGlobalObjectChecker

通用全局对象检测器:

  • ✅ 检测任意全局对象
  • ✅ 自定义检测配置
  • ✅ 错误重试机制
import { useGlobalObjectChecker } from "@packages/polling-checker"

const GlobalChecker = () => {
  const { reset } = useGlobalObjectChecker({
    globalKey: "MyGlobalObject",
    onReady: () => {
      console.log("全局对象已加载!")
    },
    enabled: true
  })

  return <div>等待全局对象加载...</div>
}

📖 详细配置选项

SmartVisibleCrossSellTracker 配置

interface UseSmartVisibleCrossSellTrackerOptions {
  onViewed: () => void         // 可见时的回调函数
  enabled?: boolean            // 是否启用(默认true)
  rootMargin?: string          // 根边距(默认"0px")
  threshold?: number           // 可见阈值(默认0.1)
}

VisibleCrossSellTracker 配置

interface UseVisibleCrossSellTrackerOptions {
  onViewed: () => void         // 可见时的回调函数
  enabled?: boolean            // 是否启用(默认true)
  rootMargin?: string          // 根边距(默认"0px")
  threshold?: number           // 可见阈值(默认0.1)
}

GlobalObjectChecker 配置

interface UseGlobalObjectCheckerOptions {
  globalKey: string            // 全局对象的键名
  onReady: () => void         // 对象加载完成后的回调
  enabled?: boolean           // 是否启用(默认true)
}

🚀 实际使用场景

场景1:推荐卡片列表

import { useSmartVisibleCrossSellTracker } from "@packages/polling-checker"

const RecommendationList = ({ items }) => {
  return (
    <div className="recommendation-list">
      {items.map(item => (
        <RecommendationCard 
          key={item.id} 
          item={item} 
          locationUuid={item.trackingUuid}
        />
      ))}
    </div>
  )
}

const RecommendationCard = ({ item, locationUuid }) => {
  const { ref } = useSmartVisibleCrossSellTracker({
    onViewed: () => {
      // 自动上报曝光事件
      window.crossSellTracker?.logViewed(locationUuid)
    },
    threshold: 0.6 // 60%可见时触发
  })

  const handleClick = () => {
    // 点击时上报
    window.crossSellTracker?.logClicked(locationUuid)
  }

  return (
    <div ref={ref} className="card" onClick={handleClick}>
      <img src={item.image} alt={item.title} />
      <h3>{item.title}</h3>
      <p>{item.description}</p>
    </div>
  )
}

场景2:分步加载检测

import { useCrossSellTracker } from "@packages/polling-checker"
import { useState } from "react"

const StepByStepTracker = () => {
  const [step, setStep] = useState(1)

  // 第一步:等待CrossSellTracker加载
  useCrossSellTracker(() => {
    console.log("步骤1:CrossSellTracker已加载")
    setStep(2)
  }, step === 1)

  // 第二步:初始化应用
  useEffect(() => {
    if (step === 2) {
      window.crossSellTracker?.initApp({
        shopify_id: 123456,
        user_id: 789,
        domain: "store.myshopify.com",
        plan: "premium",
        shopify_version: "2024-01"
      }).then(() => {
        console.log("步骤2:应用初始化完成")
        setStep(3)
      })
    }
  }, [step])

  return (
    <div>
      <p>当前步骤: {step}</p>
      {step === 1 && <p>等待CrossSellTracker加载...</p>}
      {step === 2 && <p>正在初始化应用...</p>}
      {step === 3 && <p>初始化完成,可以开始跟踪!</p>}
    </div>
  )
}

场景3:条件性跟踪

import { useSmartVisibleCrossSellTracker } from "@packages/polling-checker"
import { useState } from "react"

const ConditionalTracker = ({ shouldTrack, locationUuid }) => {
  const [hasTracked, setHasTracked] = useState(false)

  const { ref, reset } = useSmartVisibleCrossSellTracker({
    onViewed: () => {
      if (!hasTracked) {
        window.crossSellTracker?.logViewed(locationUuid)
        setHasTracked(true)
      }
    },
    enabled: shouldTrack && !hasTracked
  })

  const handleReset = () => {
    setHasTracked(false)
    reset()
  }

  return (
    <div ref={ref} className="conditional-tracker">
      <p>跟踪状态: {hasTracked ? "已跟踪" : "未跟踪"}</p>
      <p>跟踪开关: {shouldTrack ? "开启" : "关闭"}</p>
      <button onClick={handleReset}>重置跟踪</button>
    </div>
  )
}

⚡ 性能优化特性

智能检测机制

useSmartVisibleCrossSellTracker 的智能特性:

  1. 初始可见性检查:首先检查元素是否已在视窗内
  2. 避免不必要的Observer:如果元素已可见,直接触发,不创建Observer
  3. 自动清理:触发后自动停止观察,节省资源

防重复触发

所有hooks都内置防重复触发机制:

  • ✅ 状态管理确保回调只执行一次
  • ✅ 提供reset方法手动重置状态
  • ✅ 组件卸载时自动清理

错误处理

  • ✅ 全局对象检测失败不会影响主流程
  • ✅ 最大重试次数限制(5次)
  • ✅ 合理的检测间隔(300ms)

🔧 高级用法

自定义全局对象检测

const CustomObjectTracker = () => {
  const { reset } = useGlobalObjectChecker({
    globalKey: "MyCustomSDK",
    onReady: () => {
      // 自定义SDK加载完成
      window.MyCustomSDK.initialize()
    },
    enabled: true
  })

  return <div>等待自定义SDK加载...</div>
}

多重条件检测

const MultiConditionTracker = () => {
  const [isSDKReady, setIsSDKReady] = useState(false)
  const [isUserReady, setIsUserReady] = useState(false)

  // 检测SDK
  useCrossSellTracker(() => {
    setIsSDKReady(true)
  }, !isSDKReady)

  // 检测用户登录状态
  useEffect(() => {
    if (window.userAuth?.isLoggedIn()) {
      setIsUserReady(true)
    }
  }, [])

  // 两个条件都满足时才开始跟踪
  const { ref } = useSmartVisibleCrossSellTracker({
    onViewed: () => {
      window.crossSellTracker?.logViewed("multi-condition-uuid")
    },
    enabled: isSDKReady && isUserReady
  })

  return (
    <div ref={ref}>
      <p>SDK状态: {isSDKReady ? "就绪" : "等待中"}</p>
      <p>用户状态: {isUserReady ? "已登录" : "未登录"}</p>
    </div>
  )
}

🔗 与Core SDK的配合使用

建议的使用模式:

  1. 应用初始化时:使用core SDK初始化全局实例
  2. 组件中:使用React hooks进行可见性跟踪
  3. 手动事件:直接调用core SDK的快捷方法
// App.tsx - 应用入口
import { initGlobalCrossSellTracker } from "@packages/cross-sell-tracking"

const App = () => {
  useEffect(() => {
    initGlobalCrossSellTracker({
      apiKey: "your-api-key",
      environment: "production"
    })
  }, [])

  return <Router>...</Router>
}

// Component.tsx - 具体组件
import { useSmartVisibleCrossSellTracker } from "@packages/polling-checker"

const MyComponent = () => {
  const { ref } = useSmartVisibleCrossSellTracker({
    onViewed: () => window.crossSellTracker?.logViewed("uuid")
  })

  const handleClick = () => {
    window.crossSellTracker?.logClicked("uuid")
  }

  return <div ref={ref} onClick={handleClick}>内容</div>
}

🏗️ 最佳实践

  1. 优先使用SmartVisible:大多数场景下使用 useSmartVisibleCrossSellTracker
  2. 合理设置阈值:根据元素大小和业务需求设置threshold
  3. 启用条件控制:使用enabled参数控制何时开始跟踪
  4. 状态重置:必要时使用reset方法重置跟踪状态
  5. 错误边界:在关键组件外包裹错误边界组件