safariだけimgのonloadイベントが走らないパターン


背景

画像と、その他のコンテンツが動的に切り替わっていく画面で、画像が見えてから他のコンテンツを表示させたいという要件があり、対象の画像のimageのonloadで他のコンテンツを表示、またタグごと取り換えると遅いということで、imageタグ内のsrc属性を書き換えていくような実装をしていました。
その際2連続で同じ画像を出した時にiphoneユーザーだけうまく動かず、その調査の備忘録です。

実験

こんなスクリプトをブラウザのコンソールに読ませます。これによりページのimgタグの最初の1つに、onload時にコンソールにメッセージが出るイベントが付与されます。

const img = document.getElementsByTagName("img")[0]

img.addEventListener('load', function() {
  console.log('load!')
}, false);

これを適当なimgタグのあるサイトで流したあと、さらにこのスクリプトを2回流します。imgに適当な画像のurlを埋め込んでいます。

// googleのロゴ
img.src = "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"; 

この時、2回目でload!と出力されるかを各ブラウザで調べました。

結果

ブラウザ OS 結果
chrome 92.0.4515.159 windows 10 21H1 2回表示
Firefox 90.0.2 windows 10 21H1 2回表示
Edge 92.0.902.84 windows 10 21H1 2回表示
chrome 91.0.4472.114 mac Catalina 10.15.2 2回表示
Firefox 89.0 mac Catalina 10.15.2 2回表示
safari13.0.4 (15608.4.9.1.3) mac Catalina 10.15.2 1回表示

結論

safariではimgのsrcに元と同じurlを与えたときに、onloadイベントが発火してくれない。ということがわかりました。対策としてはurlを与える前に空文字をあたえる処理を挟むなどすると良いです。ブラウザ依存でアプリケーションがうまく動かないパターンは開発者泣かせなので、なんとなく記憶の片隅においていただけると良いかもしれません。