Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

在 ios 或 Safari 上这个地方会有问题 #8

Open
hugeorange opened this issue Feb 1, 2020 · 8 comments
Open

在 ios 或 Safari 上这个地方会有问题 #8

hugeorange opened this issue Feb 1, 2020 · 8 comments

Comments

@hugeorange
Copy link

if (intersectionRatio === 1) {

image

在 ios 或电脑端 Safari 里面,上面的判断会造成 this.tracks 全为false,因为它没有进到这个判断里

在 ios 里如果手机息屏之后再点亮好像还有点问题,弹幕也会停止,我现在没法debugger ios,还没找到问题

其实我没太看懂您这里的判断逻辑,我只是把这个判断条件去除了,就好了


if (intersectionRatio === 1) {

@hugeorange
Copy link
Author

由仔细看了看,好像是看明白了,你是靠这个 intersectionRatio,做防重叠检测的,,,Chrome和安卓上只会出现 <=1 的情况,,,但 ios 和 Safari 会出现大于 1的情况

image

@zerosoul
Copy link
Owner

zerosoul commented Feb 3, 2020

由仔细看了看,好像是看明白了,你是靠这个 intersectionRatio,做防重叠检测的,,,Chrome和安卓上只会出现 <=1 的情况,,,但 ios 和 Safari 会出现大于 1的情况

image

啊 改一下判断条件应该就好了 感谢反馈 我修复下...

@hugeorange
Copy link
Author

hugeorange commented Feb 4, 2020

@zerosoul

hello,,我今天又仔细看了一下您的源码,发现有一个地方不解: queues 这个队列

// 构造函数内
queues = [];

// push 操作内
if (currIdletrack === -1 || this.allPaused) {
    // 考虑到全部暂停的情景
    this.queues.push([item, bulletContainer, top]);
} else {
    this._render(item, bulletContainer, currIdletrack, top);
}

// render 操作内--- IntersectionObserver 观察
// 完全处于视窗之内
console.log('this.queue---observer', this.queues)
const { intersectionRatio, target } = entry;
if (intersectionRatio == 1) {
    let trackIdx = target.dataset.track;
    if (this.queues.length) {
    const [item, container, customTop] = this.queues.shift();
    this._render(item, container, trackIdx, customTop);
    } else {
    this.tracks[trackIdx] = true;
    }
}

疑问:
当执行全部暂停事件后,后续所有的 push 都会进入 queues,同时也会进入 bullets,
或者当所有跑道被占据也会将 新push 的弹幕放入 queues

场景:
我的场景是这样的:后台有个分页接口,每页20条数据,我会把这个20条数据每隔一秒执行 push 操作,当这一页的数据push完,继续请求下一页的数据,然后在执行上述操作,

结果现象:
正常情况,一直push是没问题的,当我把app返回主页面,然后再过一段时间,再进来(相当于浏览器最小化操作),此时会发现 this.tracks 里面全变成false了,导致弹幕不能出现了(尽管我还在不停地执行push 操作),,这个问题好像电脑和安卓都不出出现,只有 ios 会出现


在研究源码之后,我猜测问题应该出现在这个 queue上,不过我还没有证据

我现在的解决办法:
每一页数据实例化一个BulletScreen对象,当这页数据push完之后,销毁这个实例,等下一页数据请求回来之后再重新实例化一个 BulletScreen 对象,好像这样操作,不会出现我上面描述的问题了

@zerosoul
Copy link
Owner

zerosoul commented Feb 5, 2020

由仔细看了看,好像是看明白了,你是靠这个 intersectionRatio,做防重叠检测的,,,Chrome和安卓上只会出现 <=1 的情况,,,但 ios 和 Safari 会出现大于 1的情况
image

啊 改一下判断条件应该就好了 感谢反馈 我修复下...

已在最新版本修复,另外优化了下调取空跑道规则:优先使用空闲(idle)跑道。p.s.跑道状态分为:idle,feed,running

1 similar comment
@zerosoul
Copy link
Owner

zerosoul commented Feb 5, 2020

由仔细看了看,好像是看明白了,你是靠这个 intersectionRatio,做防重叠检测的,,,Chrome和安卓上只会出现 <=1 的情况,,,但 ios 和 Safari 会出现大于 1的情况
image

啊 改一下判断条件应该就好了 感谢反馈 我修复下...

已在最新版本修复,另外优化了下调取空跑道规则:优先使用空闲(idle)跑道。p.s.跑道状态分为:idle,feed,running

@hugeorange
Copy link
Author

@zerosoul

hello,,我今天又仔细看了一下您的源码,发现有一个地方不解: queues 这个队列

// 构造函数内
queues = [];

// push 操作内
if (currIdletrack === -1 || this.allPaused) {
    // 考虑到全部暂停的情景
    this.queues.push([item, bulletContainer, top]);
} else {
    this._render(item, bulletContainer, currIdletrack, top);
}

// render 操作内--- IntersectionObserver 观察
// 完全处于视窗之内
console.log('this.queue---observer', this.queues)
const { intersectionRatio, target } = entry;
if (intersectionRatio == 1) {
    let trackIdx = target.dataset.track;
    if (this.queues.length) {
    const [item, container, customTop] = this.queues.shift();
    this._render(item, container, trackIdx, customTop);
    } else {
    this.tracks[trackIdx] = true;
    }
}

疑问:
当执行全部暂停事件后,后续所有的 push 都会进入 queues,同时也会进入 bullets,
或者当所有跑道被占据也会将 新push 的弹幕放入 queues

场景:
我的场景是这样的:后台有个分页接口,每页20条数据,我会把这个20条数据每隔一秒执行 push 操作,当这一页的数据push完,继续请求下一页的数据,然后在执行上述操作,

结果现象:
正常情况,一直push是没问题的,当我把app返回主页面,然后再过一段时间,再进来(相当于浏览器最小化操作),此时会发现 this.tracks 里面全变成false了,导致弹幕不能出现了(尽管我还在不停地执行push 操作),,这个问题好像电脑和安卓都不出出现,只有 ios 会出现

在研究源码之后,我猜测问题应该出现在这个 queue上,不过我还没有证据

我现在的解决办法:
每一页数据实例化一个BulletScreen对象,当这页数据push完之后,销毁这个实例,等下一页数据请求回来之后再重新实例化一个 BulletScreen 对象,好像这样操作,不会出现我上面描述的问题了

@zerosoul 能帮我看看这个吗

@hugeorange
Copy link
Author

hugeorange commented Feb 5, 2020

由仔细看了看,好像是看明白了,你是靠这个 intersectionRatio,做防重叠检测的,,,Chrome和安卓上只会出现 <=1 的情况,,,但 ios 和 Safari 会出现大于 1的情况
image

啊 改一下判断条件应该就好了 感谢反馈 我修复下...

已在最新版本修复,另外优化了下调取空跑道规则:优先使用空闲(idle)跑道。p.s.跑道状态分为:idle,feed,running


我看您的npm上已经更新了,能把最新代码更新下GitHub吗

@hugeorange
Copy link
Author

由仔细看了看,好像是看明白了,你是靠这个 intersectionRatio,做防重叠检测的,,,Chrome和安卓上只会出现 <=1 的情况,,,但 ios 和 Safari 会出现大于 1的情况
image

啊 改一下判断条件应该就好了 感谢反馈 我修复下...

已在最新版本修复,另外优化了下调取空跑道规则:优先使用空闲(idle)跑道。p.s.跑道状态分为:idle,feed,running


@zerosoul
我刚看过您更新后的代码感觉还是问题,不知道说的对不对,还请指教

tracks 之前的 true ,false 和现在的状态相比 idle、feed、 running

因为如果一条弹幕过长时, intersectionRatio 可能不会出现 >= 1 的情况(这条跑道就废了
应该在 animationend 的时候把这条跑道置位 idle

另外还有一个情况,当发弹幕速度过快时,跑道不够用的时候,是放在 queues 里面的,,感觉queues 没有得到消费

对这段代码不是很理解

              if (this.queues.length) {
                const [item, container, customTop] = this.queues.shift();
                this._render(item, container, trackIdx, customTop);
              } else {
                this.tracks[trackIdx] = 'feed';
              }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants