【发布时间】:2018-10-16 12:54:04
【问题描述】:
我做了一个 React 组件,它在无限循环中动态改变 4 个 div 的背景,每次改变背景时,都会触发一个切换类的 css 动画。
为了获取所有图像,我使用与 url-loader 配对的 Webpack 'require.context' 函数来获得一个 base64 数据 url 数组,以将它们用作背景的新来源。
我在 Chrome (69.0.3497.100)、Opera (56.0.3051.43) 和 Firefox (62.0.3) 中按预期工作的方式。但它在 Safari (12.0) 中效果不佳,我可以看到一些“故障”。
当我检查页面时,我可以看到正确触发了动画,但是在它之后出现了图像,有时图像不可见。
另一个奇怪的行为是它会影响包含 div 的部分上方的固定元素,它们正在闪烁。
我记录了问题,以便您了解我的意思: https://www.youtube.com/watch?v=EO-9Ks-FhOo
这里还有一个暂存版本。 http://ferrarism.at/today/staging
这是我的 React 组件:
import React from "react"
function importAll(r) {
return r.keys().map(r);
}
const imageArray = importAll(require.context('../img/clients', true));
export default class ClientReel extends React.Component {
constructor(props){
super(props);
this.state = {
images: imageArray
}
}
render(){
const {images} = this.state
var count;
const randomClient = [];
for (count = 1; count <= 4; ++count) {
var i = Math.floor((Math.random() * (images.length - count)) + 1);
randomClient.push(images[i]);
images[i] = images[images.length - count];
}
const ImagesToRender = randomClient.map((item, i) => {
return (
<div key={i} className="clientReel-item">
<div className="itemImage" style={{ background: `url(${item}) center center / 100% no-repeat` }}></div>
</div>
)
})
return(
<React.Fragment>
{ImagesToRender}
</React.Fragment>
)
}
componentDidMount(){
const {images} = this.state
const reelItemImage = document.querySelectorAll(".itemImage")
const reelItems = document.querySelectorAll(".clientReel-item")
var i = 0;
var f = 0;
var timing = 500;
(function loop() {
setTimeout(function () {
reelItems[i].classList.toggle("reelFlip")
}, timing - 100)
if (f < (images.length - 1)) {
f++;
reelItemImage[i].style.background = "url(" + images[f] + ") center center / 100% no-repeat"
} else {
f = 0;
reelItemImage[i].style.background = "url(" + images[f] + ") center center / 100% no-repeat"
}
if (i < (reelItems.length - 1)) {
i++;
} else {
i = 0;
}
setTimeout(loop, timing);
})();
}
}
这是我的组件编译后的 css:
.section__client-reel .wrapper #clientReel .clientReel-item {
flex-basis: 21.739%;
height: 91px;
margin: 18px 0;
transform: rotateX(0deg);
transition: all 0.5s cubic-bezier(0.3, 1, 0.3, 1);
-webkit-transition: all 0.5s cubic-bezier(0.3, 1, 0.3, 1);
}
.section__client-reel .wrapper #clientReel .clientReel-item .itemImage {
width: 100%;
height: 100%;
}
.section__client-reel .wrapper #clientReel .reelFlip {
transform: rotateX(-180deg);
-webkit-transform: rotateX(-180deg);
transition: all 0.5s cubic-bezier(0.3, 1, 0.3, 1);
-webkit-transition: all 0.5s cubic-bezier(0.3, 1, 0.3, 1);
}
.section__client-reel .wrapper #clientReel .reelFlip .itemImage {
transform: rotateX(180deg);
-webkit-transform: rotateX(180deg);
}
我寻找解决方案已经好几个小时了,但我一无所获。如果你有什么想法,请随意!
【问题讨论】:
-
“真的很奇怪”不是对您问题的描述。在合理的细节中比较和对比你想要的和你得到的。该信息应该在您的问题中,而不是在第 3 方视频网站上。额外的细节,例如测试的浏览器版本也是明智的。
-
ewww。所以在挂载时你会启动一个 setTimeout 循环来处理 DOM 节点并改变它们的 classList 集合而没有办法阻止它?它可能适用于其他浏览器,但这不是反应方式。无论如何,您应该检查 safari 在循环时将背景 url 属性设置为什么,看看它是否可以修复。另外,我建议仅使用
backgroundImage属性并将其他道具保留在CSS 中它们所属的位置。它还有助于查看实际编译的 CSS,并确保它可以在没有循环的情况下与 webkit 和 safari 一起使用。 -
对不起@ADyson,我编辑了
标签: javascript reactjs webpack sass