收藏
回答

报告一个Bug:交叉观察器只有从上面滑入滑出时生效

框架类型 问题类型 API/组件名称 终端类型 微信版本 基础库版本
小程序 Bug IntersectionObserver 微信iOS客户端 6.5.3 2.0.0

交叉观察器只有从上面滑入滑出时生效




1. 结构层 (index.wxml)

我们使用 <view> 替换 div<scroll-view> 实现滚动,并用小程序的数据绑定 {{ }} 来动态显示状态。

XML


<view id="status-panel" class="status-panel-fixed">
    <text>交叉状态:</text>
    <text id="log-display">{{ logDisplay }}</text>
</view>

<view id="root" class="root-container">
    观察器的根容器(蓝色边框)
    
    <scroll-view 
        id="intermediate_scroller" 
        class="intermediate-scroller" 
        scroll-y="{{true}}">
        
        <text>中间的滚动容器(橙色边框),请滚动这里!</text>
        
        <view style="height: 400px; background: #eee; margin-bottom: 10px;">占位内容</view>
        
        <view id="target" class="target-box">
            目标元素 (Target)
            <text>{{ targetStatusText }}</text>
        </view>
        
        <view style="height: 400px; background: #eee; margin-top: 10px;">更多占位内容</view>
    </scroll-view>
</view>

2. 样式层 (index.wxss)

小程序中的 position: fixed 和其他样式与 Web 类似,但单位通常使用 rpxpx,这里沿用 px

CSS


/* 状态显示面板 (Fixed) */
.status-panel-fixed {
    position: fixed; /* 关键:固定定位 */
    bottom: 20px;
    right: 20px;
    padding: 10px 15px;
    background-color: #333;
    color: white;
    border-radius: 5px;
    font-size: 14px;
    z-index: 1000;
}

/* 根容器 */
.root-container {
    border: 4px solid blue;
    height: 500px;
    overflow: hidden; 
    padding: 10px;
    display: flex;
    flex-direction: column; 
    font-family: sans-serif;
}

/* 滚动容器 */
.intermediate-scroller {
    border: 2px solid orange;
    height: 200px; /* 滚动容器的高度 */
    margin: 20px 0;
    padding: 5px;
    /* scroll-view 默认自带滚动条,无需 overflow-y: scroll */
}

/* 目标元素 */
.target-box {
    height: 100px; 
    background-color: lightgreen;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    font-weight: bold;
    text-align: center;
    margin: 10px 0;
}

3. 逻辑层 (index.js)

我们使用 wx.createIntersectionObserver API,并通过 this.setData 更新 WXML 中绑定的数据。

JavaScript


Page({
    data: {
        // 目标元素内部的状态
        targetStatusText: '等待初始化',
        // 固定面板显示的状态(对应 logDisplay)
        logDisplay: '等待初始化...' 
    },

    onReady() {
        this.initObserver();
    },

    initObserver() {
        // 1. 创建 IntersectionObserver 实例
        const observer = wx.createIntersectionObserver(this, {
            thresholds: [0], // 只要有一个像素进入/离开就触发
        });

        // 2. 指定根容器 (root)
        // 监听 id="target" 元素相对于 id="root" 元素(根容器)的交叉状态
        observer.relativeTo('#root').observe('#target', (res) => {
            
            const isIntersecting = res.intersectionRatio > 0;
            
            const statusMessage = isIntersecting 
                ? '✅ 进入根容器可视区' 
                : '❌ 离开根容器可视区';

            // 3. 更新 WXML 中绑定的数据
            this.setData({
                targetStatusText: statusMessage,
                logDisplay: statusMessage // 更新 fixed 面板的内容
            });
        });

        // 初始化面板提示
        this.setData({
            logDisplay: '请尝试滚动中间的容器...',
            targetStatusText: '等待滚动'
        });
    },
});


回答关注问题邀请回答
收藏

1 个回答

  • 智能回答 智能回答 本次回答由AI生成
    2025-10-21
    有用
登录 后发表内容