そもそもの目的は、
JavaScript のイベントリスナーで contextmenu から <input type="file"> を発火させて "ファイル選択ダイアログ" を開かせる、というものでした。
結果、
Edge、FireFox、Chromeは、Win・Mac両方で問題なく "ファイル選択ダイアログ" が開きました。
ところが「Safari では開かない」というのが本記事です。
超マイナーですみません。
それでは、<input type="file"> を含むHTMLです。
JavaScript は head 内に、css はインラインで記入しています。
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Safari頼むよ</title>
<script>
window.onload=()=>{
const rc_area=document.getElementById("right_click_area");
rc_area.addEventListener('contextmenu',(e)=>{
e.preventDefault();
const select_file=document.getElementById("select_file");
select_file.click();
});
}
</script>
</head>
<body>
<div style="position: fixed; top: 0; left: 0; width: 100%; height:100%; display: flex; flex-direction: column; align-items: center; justify-content: space-around;">
<input type="file" id="select_file">
<div id="right_click_area" style="height: 100px; width: 200px; background-color: lightskyblue; border: solid 2px; display: flex; flex-direction: column; align-items: center; justify-content: space-around;">右クリックエリア</div>
</div>
</body>
</html>
<input type="file"> はブラウザで見ると『ファイル選択』という表示になります。
これを "左クリック" すると "ファイル選択ダイアログ" が開きます。
Edge、FireFox、Chrome、Safariで問題なく機能します。
"右クリック" では "ファイル選択ダイアログ" は開きません。
"右クリック" をするとブラウザのデフォルトのメニューが表示されます。
Edge、FireFox、Chrome、Safari同様です。
"右クリック" で <input type="file"> は反応しないということですね。
さて、『右クリックエリア』というものを作っています。
この場所で "右クリック" をすると JavaScript では、
イベントリスナーで contextmenu (右クリック)を検知、
e.preventDefault() でブラウザのデフォルトのメニューを非表示、
<input type="file"> エレメントを document.getElementById で select_file に代入、
それを click()する、ということが起こります。
ご承知のとおり、click()は "左クリック" をするメソッドです。
なので、実際にブラウザで、『右クリックエリア』で "右クリック" を行うと、
<input type="file"> が "左クリック" されて "ファイル選択ダイアログ" が開きます。
簡単に言えば、"右クリック" → "左クリック" → "ファイル選択ダイアログ" という流れができるのです。
Edge、FireFox、Chromeで問題なく機能しました。
ところが、Safariでは、上記の流れがうまく行きません。
「もしかして、contextmenu からのclick()は "左クリック" にならないのではないか?」
と考えました。
まさか "右クリック" → "右クリック" → <input type="file"> 反応せず
となってしまっているのかと。
そこで、HTML に書き足します。
<!--input type="file"にonclickを取り付けて、左クリックされたら反応するようにする-->
<input type="file" id="select_file" onclick="console.log('左クリックされました')">
<input type="file"> が左クリックされたらコンソールに"左クリックされました"と返すようにしました。
そして、Safariで確認です。
『右クリックエリア』で "右クリック" をすると、、、
なんとコンソールに "左クリックされました" と現れました。
contextmenu からのclick()は、"左クリック" としてちゃんと<input type="file">に届いていました。
いやしかし、それならなぜ "ファイル選択ダイアログ" は開かないのか?
謎です。