我正在开发一个React应用,它将通过Cordova嵌入到Android Webview中。
我尝试为Div.Deal制作动画,该动画应该退出HTML默认流程并缓慢扩展以显示为模态。
此问题在Android Webview上出现,但在一切正常的笔记本电脑上的Chrome上不会出现。
当在DevTool上分析动画(Android USB调试)时,我得到以下结果:
有时,缺少top属性:
有时,存在top属性(我的Ripple效果未执行,但是可能相关吗?):
all 0.5s linear
更改为height 0.5s linear, width 0.5s linear, left 0.5s linear, top 0.5s linear
window.getBouncingClientRect()
的值,该值对于每个属性都是正确的。这是我的div.Deal的默认CSS代码:
.Deal {
border-radius: var(--deal-border-radius);
background-color: var(--deal-background-color);
position: relative;
height: 100%;
z-index: 0;
}
这是执行动画的方法(打开的动画发生在条件的“其他”部分):
handleClick() {
this.setState({
opened: !this.state.opened
})
if (this.state.opened) {
// I get the current height, width, top, left value of its
// position on the page with window.getBouncingClientRect().
// I apply those values to get rid of % values and have px values
this.deal.current.style.height = `${this.deal.current.getBoundingClientRect().height}px`;
this.deal.current.style.width = `${this.deal.current.getBoundingClientRect().width}px`;
this.deal.current.style.left = `${this.deal.current.getBoundingClientRect().x}px`;
this.deal.current.style.top = `${this.deal.current.getBoundingClientRect().y}px`;
// I set back position values to those kept in cssStyleState and the close animation occurs
this.deal.current.style.height = `${this.cssStyleState.height}px`;
this.deal.current.style.width = `${this.cssStyleState.width}px`;
this.deal.current.style.left = `${this.cssStyleState.left}px`;
this.deal.current.style.top = `${this.cssStyleState.top}px`;
this.deal.current.style.boxShadow = 'var(--deal-box-shadow)';
// I wait 500ms that the animation finish and I set up manually
// the CSS property to those in my CSS file, emptying the
// transition property value.
setTimeout(() => {
this.deal.current.style.position = 'relative';
this.deal.current.style.height = '100%';
this.deal.current.style.width = '';
this.deal.current.style.left = '';
this.deal.current.style.top = '';
this.deal.current.style.zIndex = '0';
this.deal.current.style.transition = '';
}, 500);
} else {
// I get the height, width, top, left value of its position on the page with window.getBouncingClientRect(),
// I save it in cssStyleState to keep the starting state.
this.cssStyleState = {
width: this.deal.current.getBoundingClientRect().width,
height: this.deal.current.getBoundingClientRect().height,
left: this.deal.current.getBoundingClientRect().x,
top: this.deal.current.getBoundingClientRect().y
};
// I change position value to position: absolute;
// and I manually set height, width, top, left value;
// Which visually gives the same result.
// After more investigation it appears that : in the set
// of 4 instructions below (without zIndex), the last
// line will be sometime missed by android webview. I
// tried swaping instruction and it gives the same
// result.
this.deal.current.style.height = `${this.deal.current.getBoundingClientRect().height}px`;
this.deal.current.style.width = `${this.deal.current.getBoundingClientRect().width}px`;
this.deal.current.style.left = `${this.deal.current.getBoundingClientRect().x}px`;
this.deal.current.style.top =
`${this.deal.current.getBoundingClientRect().y}px`;
this.deal.current.style.zIndex = '1';
this.deal.current.style.position = 'absolute';
// Then I apply the CSS transition property on those 4 properties to fire
// my animation with new values. I use the timeout make sure the handler
// executes after the instructions aboves (to avoid a glitch).
setTimeout(() => {
this.deal.current.style.transition = 'height 0.5s linear, width 0.5s linear, left 0.5s linear, top 0.5s linear';
this.deal.current.style.height = '50%';
this.deal.current.style.width = '80%';
this.deal.current.style.left = '10%';
this.deal.current.style.top = '25%';
this.deal.current.style.boxShadow = 'var(--deal-opened-box-shadow)';
}, 0)
}
有时,我将div从其位置移动并扩展为一种表现良好的模式(主要在PC上,有时在Android上),有时此动画触发而无需关心top
属性(仅在Android上) )。
编辑:经过更多调查,似乎:在4条指令的集合中(参见代码),android webview有时会遗漏最后一行。我尝试交换指令,并且根据哪一条指令是最后一条指令,它具有相同的效果。