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

Fix the penetration of click events when Mask nesting. #5749

Merged
merged 7 commits into from Dec 12, 2019

Conversation

@caryliu1999
Copy link
Contributor

caryliu1999 commented Nov 15, 2019

问题说明:

反馈自论坛:https://forum.cocos.org/t/cocos-creator-v2-2-1/85555/250?u=endevil

在 Mask 嵌套的情况下,因为节点的点击事件只会对第一个 Mask 父节点进行 hitTest,所以会出现 button 不显示的区域也会触发点击事件。

测试Demo:
scrollview_test 2.zip

修改说明:

  1. 这里对 touchListener 进行父节点的 Mask 查询及缓存的时候,之前只会缓存第一个 Maks节点,现在以单链表的形式缓存所有 Mask 父节点,在进行点击区域判定的时候,会对缓存的链表中的所有 Mask 节点进行 hitTest 判定,必须全部满足才会触发点击。

  2. 之前只有在节点 postActive 的时候才会查询记录事件的 mask,在 button 重新设置父节点的时候并没有重置 Mask 的记录,增加在 _onHierarchyChanged 节点层级发生变化时也进行重新查询的记录。

注意:

另外有一种情况就是当 button 的父节点层级发生变化,如果没有触发 button 节点的 _onHierarchyChanged 或者 active 状态改变,仍然不会重置事件的 Mask 记录。对于这种情况比较少见,为了不浪费性能,暂时忽略该使用场景,有需要的可以调用 _checkListenerMask 进行更新。

另:非新增问题,可在 v2.2.2 版本更新

cocos2d/core/CCNode.js Outdated Show resolved Hide resolved
cocos2d/core/CCNode.js Show resolved Hide resolved
let temp = {
index: -1,
node: null,
next: null

This comment has been minimized.

Copy link
@jareguo

jareguo Nov 22, 2019

Contributor

讲真,有点难理解这块的逻辑。能更清晰点吗?或者补充点注释

This comment has been minimized.

Copy link
@caryliu1999

caryliu1999 Nov 23, 2019

Author Contributor

加了点注释,这里解释一下。

因为Mask是可以嵌套的,比如节点链 A(Mask)->B->C(Mask)->D,对于D节点来说,可见区域其实是由A跟C的Mask区域共同决定的,可见区域其实就是D的点击事件可触发区域。之前我们在判断Mask的点击覆盖时只取了最近的一个Mask节点,也就是C节点, 这种情况就会导致用户反馈的问题。

所以这里加了next字段,来记录成一个单链表,表示父节点中的Mask节点链,判定点击区域是否满足在所有Mask组件的可见区域,来判定是否满足触发点击事件的条件。

This comment has been minimized.

Copy link
@jareguo

jareguo Nov 23, 2019

Contributor

目前所有监听事件的节点的 mask.index 和 mask.node 都是没用到的,感觉有点多余。直接让 mask = mask.next,如果没有 next,mask 就为 null 就行了吧

This comment has been minimized.

Copy link
@caryliu1999

caryliu1999 Nov 23, 2019

Author Contributor

目前所有监听事件的节点的 mask.index 和 mask.node 都是没用到的,感觉有点多余。直接让 mask = mask.next,如果没有 next,mask 就为 null 就行了吧

检测的时候会用到这两个数据

cocos2d/core/CCNode.js Outdated Show resolved Hide resolved
@jareguo jareguo changed the base branch from v2.2.1-release to v2.2.2 Nov 23, 2019
caryliu1999 added 2 commits Nov 23, 2019
cocos2d/core/CCNode.js Outdated Show resolved Hide resolved
@cocos-robot cocos-robot changed the base branch from v2.2.2 to v2.3.0 Nov 28, 2019
Copy link
Contributor

cocos-robot left a comment

@caryliu1999, v2.2.2 branch will be deleted, so we edited the base branch to v2.3.0, or this PR will be killed by GitHub.
Please review the commits history to ensure that the PR does not polluted by unneeded commits from your origin branch.
If you need to merge to other branch, you can first click the Edit button on the right side of the PR title, then switch the base branch.
If necessary, welcome to resubmit a new PR. Thanks!

}
} else {
// mask parent no longer exists
mask.splice(j, length - j);

This comment has been minimized.

Copy link
@holycanvas

holycanvas Dec 9, 2019

Contributor

这里直接用 mask.length = j 呢?

This comment has been minimized.

Copy link
@caryliu1999

caryliu1999 Dec 12, 2019

Author Contributor

这里直接用 mask.length = j 呢?

已修改

let temp = mask[j];
if (i === temp.index) {
if (parent === temp.node) {
let comp = parent.getComponent(cc.Mask);

This comment has been minimized.

Copy link
@holycanvas

holycanvas Dec 9, 2019

Contributor

这里是不是还可以优化下,searchComponentsInParent 的时候,getComponent 过一次, 这里又 getComponent 一次

This comment has been minimized.

Copy link
@caryliu1999

caryliu1999 Dec 12, 2019

Author Contributor

这里是不是还可以优化下,searchComponentsInParent 的时候,getComponent 过一次, 这里又 getComponent 一次

这里是需要重新get的,因为在判断的时候,一个是parent不一定是之前的顺序,一个是Mask组件不一定存在了。

@holycanvas holycanvas merged commit b436316 into cocos-creator:v2.3.0 Dec 12, 2019
1 check passed
1 check passed
ci/circleci: test Your tests passed on CircleCI!
Details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.