在Safari

时间:2018-01-26 18:10:58

标签: css css3 safari css-animations

以下是我在Safari中遇到的错误的最小模型。

预期的行为:代码应该显示占位符,而另一个图像会加载,然后在删除占位符时淡入该图像。

placeholder -> fading in loaded image

实际行为 在Chrome和Mozilla中按预期工作,但 在Safari 中失败,从而产生以下效果:

placeholder -> white screen -> loaded image

有人可以帮我弄清楚为什么会在Safari中发生这种情况吗? (尝试在chrome或mozilla vs safari中以下示例运行以查找自己。)

const image = new Image();

image.onload = () => {
  document.getElementById('placeholder').remove();

  const el = document.createElement('img');
  el.setAttribute('src', 'http://deelay.me/1000/https://cdn.pixabay.com/photo/2014/06/03/19/38/board-361516_1280.jpg');
  el.setAttribute('width', '150');
  el.setAttribute('height', '150');

  el.style = `
    animation-name: testAnimation;
    animation-duration: 0.3s;
    animation-iteration-count: 1;
    animation-timing-function: ease-in;
    background: red;
  `;

  document.body.appendChild(el);
}

image.src = 'http://deelay.me/1000/https://cdn.pixabay.com/photo/2014/06/03/19/38/board-361516_1280.jpg';
#placeholder {
  background: #eee;
}

@-webkit-keyframes testAnimation {
  0% {
    opacity: 0.25;
  }
  50% {
    opacity: 0.5;
  }
  100% {
    opacity: 1;
  }
}
<img id="placeholder" src="data:image/svg+xml;charset=utf-8,%3Csvg xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg' width%3D'200' height%3D'300' viewBox%3D'0 0 200 300'%2F%3E" width="150" height="150">

(适用

另一个奇怪的行为是,如果animation-duration增加到3-4秒左右,那么图像会淡入,但白屏仍然存在,即

placeholder -> white screen -> fading in loaded image

更新

在使用img的背景颜色后,似乎在Safari中动画开始生效约1秒,然后图像才开始渲染到屏幕上。

  • 因此,如果真实图像不像占位符图像那样具有背景颜色,则白色轻弹,因此在将背景颜色添加到真实图像之后,为什么在图像甚至开始显示之前1秒左右可见背景颜色
  • 因此在图像开始显示之前约1秒开始发生淡入淡出效果

在Chrome和Mozilla中,动画似乎与图像完全同步。

运行更新的代码以便自己查看

(它似乎也只发生在<img>,我用其他一些元素(仍然在image.onload中)测试了它们,它们按预期工作。)

更新2:请参阅下面的答案中的修复以及解释

2 个答案:

答案 0 :(得分:1)

这是通过在 图像元素 上添加另一个init(from:)事件而不是在显式 图像对象上添加的em> 并将onload侦听器置于其中。

这似乎表明,在Safari中,只要image.onload被添加到DOM中,动画和样式就会被应用 - 在它完全加载之前(它的<img>事件被调用。)

  • 这可以通过给onload一个背景颜色进行测试,并在元素添加到DOM后立即看到它与动画一起显示,并且看到它需要额外的秒,直到图像本身变得可见

  • 只需给<img>一个背景色

  • ,你也可以看到同样的效果而不使用任何动画

(Safari中的错误? 我的Safari版本:版本11.0.2(13604.4.7.1.3))

编辑:实际上这个问题似乎是由缓存引起的,Safari似乎没有缓存预加载的代理图像,而其他浏览器会缓存它。当Safari渲染到屏幕时,Safari似乎会触发另一个请求 - 因此在查看实际图像之前样式是可见的,因为图像仍然被下载。

编辑2:经过进一步调查,似乎Safari实际上是这三种浏览器中唯一一种表现符合预期的浏览器 - 这是因为图像的HTTP响应包含<img>标头明确指示浏览器不缓存图像。

&#13;
&#13;
Cache-Control: no-cache, must-revalidate
&#13;
const image = new Image();
    
const el = document.createElement('img');
el.setAttribute('src', 'http://deelay.me/500/https://cdn.pixabay.com/photo/2014/06/03/19/38/board-361516_1280.jpg');
el.setAttribute('width', '150');
el.setAttribute('height', '150');
el.style = `
  animation-name: testAnimation;
  animation-duration: 1s;
  animation-iteration-count: 1;
  animation-timing-function: ease-in;
  background-color: red;
`;
    
el.onload = () => {
  image.onload = () => {
    document.getElementById('placeholder').remove();
    document.body.appendChild(el);
  }
}

image.src = 'http://deelay.me/500/https://cdn.pixabay.com/photo/2014/06/03/19/38/board-361516_1280.jpg';
&#13;
#placeholder {
  background: #eee;
}

@-webkit-keyframes testAnimation {
  0% {
    opacity: 0.25;
  }
  50% {
    opacity: 0.5;
  }
  100% {
    opacity: 1;
  }
}
&#13;
&#13;
&#13;

答案 1 :(得分:0)

这似乎与您使用的特定服务器/映像有关。我尝试仅更改图像URL(仅限于wikimedia.org上的内容,仅用于测试目的),动画在Safari 11.0.2(13604.4.7.1.6)中按预期开始工作。

预加载图像可能会有所帮助......甚至更好(假设您拥有正确的使用权限,所有这一切),您可以尝试将图像复制到Web服务器,以便可以在本地加载。从本质上讲,您只是通过Safari从远程服务器加载图像时完成运行动画的事实。您也可以尝试使用window.onload而不是image.onload来强制所有外部资源在运行之前加载。