LoginSignup
0
0

Mobile Safariでinput type="file"をjsのclick()で開くと、onchangeが発火しない問題

Last updated at Posted at 2023-12-06

環境

iPhone 11 Pro
iOS 17.1.2

発生している問題の概要

Mobile Safariでカメラロールから読み込むための<input type="file">を、
JSからclick()で発火すると、onchangeが発火しない

やりたいこと

iPhoneから画像をアップする

読み込みボタンを押すなりしたら読み込みダイアログを出して、
選んだ画像を返すようなメソッド、showOpenImageDialog()を作る

動かないソース

function showOpenImageDialog() {
	return new Promise(resolve => {
		const input = document.createElement('input');
		input.type = 'file';
		input.accept = 'image/*';
		input.addEventListener('change' , (event) => {
			resolve(event.target.files[0]);
		});
		input.click();
	});
}

やっていること

inputDOMを作り、typefile、今回は画像なのでacceptimage/*を設定。
onchangeの中にはファイルを返してresolveする処理を記述
その後click()で発火する

発生事象

input.click()で読み込みダイアログは開く
カメラロールから画像を選択は出来るが、何のエラーも出ず、
ただただonchangeの内容が発火しない。

※他のブラウザでは問題ない

動いたソース

function showOpenImageDialog() {
	return new Promise(resolve => {
		const input = document.createElement('input');
		input.type = 'file';
		input.accept = 'image/*';
		input.addEventListener('change' , (event) => {
			resolve(event.target.files[0]);
		});
		input.click();
		document.body.onfocus = () =>{
			setTimeout(() =>{
				if(input.value == ""){
					resolve(null);
				}else if(input.value == null){
					resolve(null);
				}else {
					
				}
				document.body.onfocus = null;
			},1000);
		}
	});
}

なぜこれで動くか

謎です。だれか教えてください。

推測ではMobile Safari(たまにSafariでも)ではフォーカス状態のままになってしまい、
フォーカスが解除されないと、値が変化せずonchangeは発火しないのでは?と思います。

ので、1秒後とかにフォーカスを外す処理を挟むことで、値の変化が反映される?

2023/12/06 追記

changeではなくinputを使えば動くとのことでした。
フォーカスの機構を外して試してみると、動いたり動かなかったり、たまに検知漏れするようです。
changeと違って動くこともあるので、inputの方が良いかもしれませんが、、

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0