JavaScriptでは、ファイル入力要素に対してプログラムで「クリック」イベントを発生させることができますか?


261

<input type="file">プログラムでタグに対してクリックイベントを発生させたいのですが。

click()を呼び出しただけでは何も実行されないか、少なくともファイル選択ダイアログがポップアップされません。

私はリスナーを使用してイベントをキャプチャし、イベントをリダイレクトする実験をしてきましたが、誰かがクリックしたように実際にイベントを実行することはできませんでした。


1
トリガーするクリックイベントは、ユーザーが開始したクリックイベント内で呼び出す必要があります。呼び出さないと、機能しません。
Umagon

回答:


79

すべてのブラウザでこれを行うことはできません。IE では許可されてますが、MozillaとOpera では許可されていません。

GMailでメッセージを作成する場合、「ファイル添付」機能は、IEとこれをサポートするすべてのブラウザーに実装され、Firefoxとそうでないブラウザーに別の方法で実装されます。

なぜそれができないのかはわかりません、セキュリティリスクであり、どのブラウザーでも許可されていないことの1つ、プログラムでHTML File要素にファイル名を設定することです。


1
ドラット。まあ私は確かにそれが悪用可能であることを理解しています。これはどこかに文書化されていますか?私はそれが各ブラウザによって実装されると思いますか?
user28655 2008年

以前の回答よりも正確になるように私の回答を更新しました-要点は同じですが、説明が少し役立つはずです。この男は同じ問題に遭遇しました:bytes.com/forum/thread542877.html
Jason Bunting

ありがとうFF5はこのクリックを許可します
rshimoda

2
上記のコメントを明確にするために:Chromeは最近、ファイルinput要素が表示されるかどうかを確認するように変更されました。click要素が表示される場合は、コンソールを含め、メソッドのトリガーが機能します。
jwadsa​​ck

2
@Otvazhnii-おい、この答え(あなたが言っているのは間違っている)は10歳です-間違いなく正しくありません!(確かにわかりません、あなたの言葉を信じています)。:P
Jason Bunting 2018

257

私はこの一日の解決策を探していました。そして、これらは私が作った結論です:

  1. セキュリティ上の理由から、OperaとFirefoxはファイル入力のトリガーを許可していません。
  2. 唯一の便利な代替手段は、「隠された」ファイル入力を作成し(「隠された」または「表示:なし」ではなく、不透明度を使用する)、その後、その「下」にボタンを作成することです。このようにボタンが表示されますが、ユーザーがクリックすると、実際にファイル入力がアクティブになります。

お役に立てれば!:)

<div style="display: block; width: 100px; height: 20px; overflow: hidden;">
<button style="width: 110px; height: 30px; position: relative; top: -5px; left: -5px;"><a href="javascript: void(0)">Upload File</a></button>
<input type="file" id="upload_input" name="upload" style="font-size: 50px; width: 120px; opacity: 0; filter:alpha(opacity=0);  position: relative; top: -40px;; left: -20px" />
</div>

6
このソリューションはうまく機能します。なぜそれが見過ごされてきていないか、わからない。これは*質問が求めるものではありませんが、優れた回避策です。どのブラウザとも互換性がないことがわかりましたか?テストするために、関連するものの10以上のフレーバーをすべて処理する時間はありません。
Yevgeny Simkin

1
この答えをありがとう、それは素晴らしいです:D
mario.tco

素晴らしい解決策。Androidモバイルブラウザーでも動作します。
gstroup 2012年

1
これは真実ではありません。以下のDidierの応答を参照してください。プログラムによるクリックは、別のボタンのクリックハンドラーのように、ユーザーアクションコンテキストから行う必要があります。次に、それは正常に動作し、オーバーフロー要素を必要としません。
2014年

1
これに関する唯一の問題は、ホバー時にボタンのスタイルを変更したい場合に変更できないことです。つまり、アプリ内の他のすべてのボタンのように表示したい場合はできません。
Vincent

68

どのブラウザでもclick()を起動できますが、一部のブラウザでは、要素を表示してフォーカスする必要があります。jQueryの例を次に示します。

$('#input_element').show();
$('#input_element').focus();
$('#input_element').click();
$('#input_element').hide();

それは前に非表示で機能しclick()ますが、showメソッドを呼び出さずに機能するかどうかはわかりません。これをOperaで試したことはありません。IE/ FF / Safari / Chromeでテストしましたが、動作します。これがお役に立てば幸いです。


51
共有いただきありがとうございます。ご存じないかもしれませんが、jQueryでチェーンを使用できます:$(...).show().focus().click().hide();:)
pimvdb '31

1
@pimvdb:私がテストした限りでは、ソリューションはChromeでのみ機能します。
ホアンロング

1
@HoàngLong:連鎖かフロリン・モゴスの解決策ですか?チェーンによってブラウザ間の違いが生じるとは思いません。
pimvdb '10 / 10/11

1
@HoàngLongIE 8および9、最新のChrome、Safari、Firefoxで動作します。
Sami Samhuri

2
奇妙な。私がテストしたように、それはUbuntuのChromeでは動作しません。
Sandrew、2011

29

これは可能です:FF4 +、Opera?、Chromeでは:

  1. inputElement.click()ユーザーアクションコンテキストから呼び出す必要があります!(スクリプト実行コンテキストではありません)

  2. <input type="file" />可視にする必要があります(inputElement.style.display !== 'none')(可視性などで非表示にできますが、 "display"プロパティは不可)


これで解決しました。onclickイベントにバインドする代わりに、JavaScriptを属性に追加する必要がありました。
jasonlfunk 2013年

1
唯一の合理的な解決策を支持する。オーバーフローメソッドは醜いです。
2014年

ハ!私はそれが文脈と関係がある必要があることを知っていました!私は呼び出すことが観察していたinputElement.click()のKeyDownイベント内から(ショートカットは、ファイルを添付するために)働いたが、タイムアウトでそれを呼び出すか、AJAXコールバックはしませんでした。賛成。
brettjonesdev 2014

9
ところで、「ユーザーアクションコンテキスト」と「スクリプト実行コンテキスト」に関するリソースは他にありますか?検索時に表示されるものはすべて、実行コンテキストとに関係していthisます。:/
brettjonesdev

@bretjonesdevこれは、クリック、イベントハンドラーなど、ユーザーが開始したイベントハンドラー内で実行する必要があることを意味します。
Alex Guerra 2016年

10

リンクの上に非表示のフォームをオーバーレイする必要があることを理解しているが、書くのが面倒なので、私はあなたのためにそれを書きました。まあ、私にとっては、共有することもできます。コメントは大歓迎です。

HTML(どこか):

<a id="fileLink" href="javascript:fileBrowse();" onmouseover="fileMove();">File Browse</a>

HTML(気にならないところ):

<div id="uploadForm" style="filter:alpha(opacity=0); opacity: 0.0; width: 300px; cursor: pointer;">
    <form method="POST" enctype="multipart/form-data">
        <input type="file" name="file" />
    </form>
</div>

JavaScript:

function pageY(el) {
    var ot = 0;
    while (el && el.offsetParent != el) {
        ot += el.offsetTop ? el.offsetTop : 0;
        el = el.offsetParent;
    }
    return ot;
}

function pageX(el) {
    var ol = 0;
    while (el && el.offsetParent != el) {
        ol += el.offsetLeft ? el.offsetLeft : 0;
        el = el.offsetParent;
    }
    return ol;
}

function fileMove() {
    if (navigator.appName == "Microsoft Internet Explorer") {
        return; // Don't need to do this in IE. 
    }
    var link = document.getElementById("fileLink");
    var form = document.getElementById("uploadForm");
    var x = pageX(link);
    var y = pageY(link);
    form.style.position = 'absolute';
    form.style.left = x + 'px';
    form.style.top = y + 'px';
}

function fileBrowse() {
    // This works in IE only. Doesn't do jack in FF. :( 
    var browseField = document.getElementById("uploadForm").file;
    browseField.click();
}



7

このclickメソッドをChrome、Firefoxなどで機能させる場合は、入力ファイルに次のスタイルを適用します。それは完全に隠されます、あなたがするようなものですdisplay: none;

#fileInput {
    visibility: hidden;
    position: absolute;
    top: 0;
    left: -5000px;
}

それはとても簡単です、私はそれが機能することをテストしました!


古いブラウザーの中には、それが非表示になっているとinputElement.click()で何も実行しないものがあるため、この方法が一番好きです。
ニック

heightand widthを単に設定しないのはなぜ0ですか?
ソロモンウッコ2016年

5
$(document).one('mousemove', function() { $(element).trigger('click') } );

私が同じような問題に遭遇したときに私のために働いた、それは通常のeRube Goldbergです。


4

ワーキングソリューション

この古い記事に、私が使用していた実用的なソリューションを追加します。これは、新旧両方のすべてのブラウザーのおそらく80%以上で機能します。

ソリューションは複雑ですがシンプルです。最初のステップは、CSSを利用し、不透明度が0であることを示す「アンダーエレメント」で入力ファイルタイプを偽装することです。次のステップは、JavaScriptを使用して必要に応じてラベルを更新することです。

HTML 特定の要素にすばやくアクセスする方法が必要な場合は、IDを挿入するだけですが、このプロセス全体を設定するCSSに関連しているため、クラスは必須です。

<div class="file-input wrapper">
    <input id="inpFile0" type="file" class="file-input control" />
    <div class="file-input content">
        <label id="inpFileOutput0" for="inpFileButton" class="file-input output">Click Here</label>
        <input id="inpFileButton0" type="button" class="file-input button" value="Select File" />
    </div>
</div>

CSS 覚えておいてください。カラーリングやフォントスタイルなどは完全に好みです。この基本的なCSSを使用する場合、いつでも好きなようにスタイルにアフターエンドマークアップを使用できます。これは最後にリストされているjsFiddleに表示されます。

.file-test-area {
    border: 1px solid;
    margin: .5em;
    padding: 1em;
}
.file-input {
    cursor: pointer !important;
}
.file-input * {
    cursor: pointer !important;
    display: inline-block;
}
.file-input.wrapper {
    display: inline-block;
    font-size: 14px;
    height: auto;
    overflow: hidden;
    position: relative;
    width: auto;
}
.file-input.control {
    -moz-opacity:0 ;
    filter:alpha(opacity: 0);
    opacity: 0;

    height: 100%;
    position: absolute;
    text-align: right;
    width: 100%;
    z-index: 2;
}
.file-input.content {
    position: relative;
    top: 0px;
    left: 0px;
    z-index: 1;
}
.file-input.output {
    background-color: #FFC;
    font-size: .8em;
    padding: .2em .2em .2em .4em;
    text-align: center;
    width: 10em;
}
.file-input.button {
    border: none;
    font-weight: bold;
    margin-left: .25em;
    padding: 0 .25em;
}

JavaScript 純粋で真実ですが、一部の古い(廃止された)ブラウザーはまだ問題を抱えている可能性があります(Netscrape 2など)。

var inp = document.getElementsByTagName('input');
for (var i=0;i<inp.length;i++) {
    if (inp[i].type != 'file') continue;
    inp[i].relatedElement = inp[i].parentNode.getElementsByTagName('label')[0];
    inp[i].onchange /*= inp[i].onmouseout*/ = function () {
        this.relatedElement.innerHTML = this.value;
    };
};

jsFiddleの例


4

できます :

FirefoxとOperaのセキュリティ上の理由から、ファイル入力のクリックを起動することはできませんが、MouseEventsでシミュレートできます。

<script>
click=function(element){
    if(element!=null){
        try {element.click();}
        catch(e) {
            var evt = document.createEvent("MouseEvents");
            evt.initMouseEvent("click",true,true,window,0,0,0,0,0,false,false,false,false,0,null);
            element.dispatchEvent(evt);
            }
        }
    };
</script>

<input type="button" value="upload" onclick="click(document.getElementById('inputFile'));"><input type="file" id="inputFile" style="display:none">

1
createEvent()initMouseEvent()は現在非推奨であることに注意してください。
Alexis Wilke 2016年

4

私はこれが古いことを知っており、これらのすべてのソリューションはブラウザのセキュリティ対策を真の価値でハックするものです。

とはいえ、現在のところ、fileInput.click()は現在のChrome(36.0.1985.125 m)と現在のFirefox ESR(24.7.0)では機能しますが、現在のIE(11.0.9600.17207)では機能しません。ボタンの上に不透明度0のファイルフィールドをオーバーレイすることは機能しますが、目に見えるトリガーとしてリンク要素が必要でしたが、ホバーの下線はどのブラウザーでも機能しません。点滅して消えると、おそらくブラウザがホバースタイリングが実際に適用されるかどうかを考えます。

しかし、私はそれらすべてのブラウザで機能する解決策を見つけました。私はすべてのブラウザのすべてのバージョンをテストしたと主張したり、それが永久に機能し続けることを知っているとは主張しませんが、私のニーズを満たしているようです。

それは簡単です:ファイル入力フィールドを画面外(位置:絶対;上:-5000px)に配置し、その周りにラベル要素を配置して、ファイルフィールド自体ではなく、ラベルのクリックをトリガーします。

リンクはスクリプトでラベルのクリックメソッドを呼び出す必要があることに注意してください。ラベル要素内のテキストをクリックするときのように、リンクは自動的に実行されません。どうやらlink要素はクリックを捕捉し、それがラベルに到達しない。

フィールドが画面外にあるため、これは現在選択されているファイルを表示する方法を提供しないことにも注意してください。ファイルが選択されたらすぐに送信したかったので問題ありませんが、状況が異なる場合は多少異なるアプローチが必要になります。


わかりました。ボタンタグでは、onclick = "filetag.click()"はIE 9および10では機能しません(IE 11、Firefox 4/10/26/27/28、Chrome / Chromium 31/32/33 /では機能します) 36、Safari 7、Opera 23)。ただし、「id-of-file-input」にラベルを使用すると(onlickなし)、IE 9/10/11で機能します。
luigifab 2014

4

JSフィドル:http : //jsfiddle.net/eyedean/1bw357kw/

popFileSelector = function() {
    var el = document.getElementById("fileElem");
    if (el) {
        el.click();  
    }
};

window.popRightAway = function() {
    document.getElementById('log').innerHTML += 'I am right away!<br />';
    popFileSelector();
};

window.popWithDelay = function() {
    document.getElementById('log').innerHTML += 'I am gonna delay!<br />';
    window.setTimeout(function() {
        document.getElementById('log').innerHTML += 'I was delayed!<br />';
        popFileSelector();
    }, 1000);
};
<body>
  <form>
      <input type="file" id="fileElem" multiple accept="image/*" style="display:none" onchange="handleFiles(this.files)" />
  </form>
  <a onclick="popRightAway()" href="#">Pop Now</a>
    <br />
  <a onclick="popWithDelay()" href="#">Pop With 1 Second Delay</a>
    <div id="log">Log: <br /></div>
</body>


3

このコードは私にとってはうまくいきます。これはあなたがやろうとしていることですか?

<input type="file" style="position:absolute;left:-999px;" id="fileinput" />
<button  id="addfiles" >Add files</button>

<script language="javascript" type="text/javascript">
   $("#addfiles").click(function(){
      $("#fileinput").click();
   });
</script>

3

jQueryとjQuery-uiを使用したSafariの私のソリューション:

$("<input type='file' class='ui-helper-hidden-accessible' />").appendTo("body").focus().trigger('click');

ヘッドアップ:Firefox 33、Chrome 38では機能しません。trigger( 'click')は、ユーザーインタラクションイベントコンテキスト-イベントハンドラ内でのみ機能します。
Amit G

3

この問題に対する純粋なJavaScriptソリューションを次に示します。すべてのブラウザで正常に動作します

<script>
    function upload_image_init(){
        var elem = document.getElementById('file');
        if(elem && document.createEvent) {
           var evt = document.createEvent("MouseEvents");
           evt.initEvent("click", true, false);
           elem.dispatchEvent(evt);
        }
    }
</script>

2

イベントをコントロールにリダイレクトする方法はいくつかありますが、ブラウザーが(良い)セキュリティ上の理由でそれをブロックしようとするため、イベントを自分で簡単に起動コントロールに起動できるとは思わないでください。

ユーザーが何かをクリックしたときにファイルダイアログだけが表示されるようにしたい場合は、ファイルアップロードボタンの見栄えをよくしたい場合は、Shaun Inmanが考案したものを確認することをお勧めします。

キーダウン、キープレス、キーアップの各イベント間で、コントロールの内外でフォーカスをクリエイティブにシフトすることで、キーボードトリガーを実現できました。YMMV。

これはブラウザの非互換性の問題の世界なので、これをそのままにしておくことをお勧めします。マイナーなブラウザー更新も警告なしにトリックをブロックする可能性があり、機能を維持するにはハックを再発明し続ける必要がある場合があります。


2

ファイルダイアログを開いてすぐにアップロードを開始するカスタムボタンを作成したかったので、これについて少し前に調査しました。私はこれを可能にするかもしれない何かに気づきました-アップロードのどこかをクリックするとFirefoxがダイアログを開くようです。したがって、次のようにするとよいでしょう。

  1. ファイルのアップロードと、ボタンとして使用する画像を含む個別の要素を作成します
  2. それらを重ねて配置し、ファイル要素の背景と境界を透明にして、ボタンだけが見えるようにします
  3. ボタン/ファイル入力がクリックされたときにIEがダイアログを開くようにJavaScriptを追加します
  4. onchangeイベントを使用して、ファイルが選択されたときにフォームを送信する

私はすでに問題を解決するために別の方法を使用したので、これは理論上のものですが、うまくいくかもしれません。


2

私が持っていた<input type="button">視界から隠されたタグを。私がやったことは"onClick"、ラベルなど、あらゆるタイプの可視コンポーネントにイベントを。これは、右クリックの「HTMLの編集」コマンドを使用して、Google Chromeの開発者ツールまたはMozilla FirefoxのFirebugを使用して行われました。このイベントでは、次のスクリプトまたは同様のものを指定します。

JQueryがある場合:

$('#id_of_component').click();

そうでない場合:

document.getElementById('id_of_component').click();

ありがとう。


2

こんにちは、このソリューションは機能します。ダウンロードにはMSBLOBを使用する必要があります

$scope.getSingleInvoicePDF = function(invoiceNumberEntity) {
   var fileName = invoiceNumberEntity + ".pdf";
   var pdfDownload = document.createElement("a");
   document.body.appendChild(pdfDownload);

   AngularWebService.getFileWithSuffix("ezbillpdfget",invoiceNumberEntity,"pdf" ).then(function(returnedJSON) {
       var fileBlob = new Blob([returnedJSON.data], {type: 'application/pdf'});
       if (navigator.appVersion.toString().indexOf('.NET') > 0) { // for IE browser
           window.navigator.msSaveBlob(fileBlob, fileName);
       } else { // for other browsers
           var fileURL = window.URL.createObjectURL(fileBlob);
           pdfDownload.href = fileURL;
           pdfDownload.download = fileName;
           pdfDownload.click();      
       }
   });
};

AngularJSの場合、または通常のJavaScriptの場合でも。


1

これはFirefox 4で可能になり、ポップアップウィンドウとしてカウントされるため、ポップアップウィンドウがブロックされた場合は常にブロックされます。


2
実際、firefox4はファイルアップロードの状態を大幅に改善します。私の問題は、Google Chromeブラウザーで同じようにする方法です。
erick2red

1

ここに私のために働く解決策があります: CSS:

#uploadtruefield {
    left: 225px;
    opacity: 0;
    position: absolute;
    right: 0;
    top: 266px;
    opacity:0;
    -moz-opacity:0;
    filter:alpha(opacity:0);
    width: 270px;
    z-index: 2;
}

.uploadmask {
    background:url(../img/browse.gif) no-repeat 100% 50%;
}
#uploadmaskfield{
    width:132px;
}

「小さな」JQueryヘルプ付きのHTML:

<div class="uploadmask">
    <input id="uploadmaskfield" type="text" name="uploadmaskfield">
</div>
<input id="uploadtruefield"  type="file" onchange="$('#uploadmaskfield').val(this.value)" >

マスクされたフィールドは、本当のアップロードフィールドで強制的にカバーされていることを確認してください。



1

input(file)がフォームの外にある場合、クリックイベントを起動するとファイルダイアログが呼び出されることがわかりました。


1

うまくいけば、これは誰かを助ける-私はそれに頭を叩いて2時間費やした:

IE8またはIE9では、JavaScriptを使用してファイル入力を開くようにトリガーした場合(私はすべて試したことがあると思います)、JavaScriptを使用してフォームを送信することはできず、黙って失敗します。

通常の送信ボタンを使用してフォームを送信することはできますが、form.submit()を呼び出します。静かに失敗します。

機能する透過的なファイル入力でファイル選択ボタンをオーバーレイすることに頼らなければなりませんでした。


さらに、ファイル入力をラベルでラップして、IEでラベルのクリック可能な領域をボタン領域全体にカバーできるようにすることができます。一方、ファイル入力タグだけでは、IEでクリックできるのは半分だけです。
ガラティア人2014年

1

これは私のために働きました:

<script>
    function sel_file() {
        $("input[name=userfile]").trigger('click');
    }  
</script>

<input type="file" name="userfile" id="userfile" />

<a href="javascript:sel_file();">Click</a>

1

それは不可能ではありません:

var evObj = document.createEvent('MouseEvents');
evObj.initMouseEvent('click', true, true, window);  
setTimeout(function(){ document.getElementById('input_field_id').dispatchEvent(evObj); },100);

しかし、どういうわけか、これがクリックイベントを介して呼び出された関数内にある場合にのみ機能します。

したがって、次の設定がある可能性があります。

html:

<div onclick="openFileChooser()" class="some_fancy_stuff">Click here to open image chooser</div>
<input type="file" id="input_img">

JavaScript:

    function openFileChooser() {
      var evObj = document.createEvent('MouseEvents');
      evObj.initMouseEvent('click', true, true, window);  
      setTimeout(function()
      { 
        document.getElementById('input_img').dispatchEvent(evObj);      
      },100);      
    }

createEvent()そしてinitMouseEvent()非推奨されました。CustomEvent()今すぐ使用する必要があります...
Alexis Wilke

0

使用できます

<button id="file">select file</button>
<input type="file" name="file" id="file_input" style="display:none;">
<script>
$('#file').click(function() {
        $('#file_input').focus().trigger('click');
    });
</script>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.