Launching the file open dialog box opens twice when a button is pressed in FireFox

I have a file <input> field and a <span> decorates the input field:

 <span class="span5 btn btn-primary btn-file" id="chose_files_btn" onclick="filechose_button.click()">chose files <input id="filechose_button" type="file" name="fileData" size="1" style="display: none"/> </span> 

While the behavior of this, I believe, in Chrome and Safari , FireFox opens two file input dialogs when you click button(span) .

Why could this happen?

I assume that the file input field is invisible, and it is accessed through a range with button behavior.

Update:

if I put <input> outside of <span> , it behaves normally.

  <span class="span5 btn btn-primary btn-file" id="chose_files_btn" onclick="filechose_button.click()">chose files</span> <input id="filechose_button" type="file" name="fileData" size="1" style="display: none"/> 

Jsfiddle

but why is the inside position wrong?

+4
source share
5 answers

This is due to some kind of mess spreading events

 <span class="span5 btn btn-primary btn-file" id="chose_files_btn" onclick="doOpen(event)">chose files <input id="filechose_button" type="file" name="fileData" size="1" style="display: none"/> </span> 

AND

 function doOpen(event){ event = event || window.event; if(event.target.id != 'filechose_button'){ filechose_button.click(); } } 

Demo: Fiddle

+7
source

This is due to the spread of events. When you click on a gap, a click event occurs, and in the click handler you called click on input type = "file", so it fires twice.

If you try the following code, it will not trigger a distributed event.

 <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script> <script type="text/javascript"> $(document).ready(function(){ $("#chose_files_btn").click(function(event){ filechose_button.click(); }); $("#filechose_button").click(function(event){ event.stopPropagation(); }); }); </script> <span class="span5 btn btn-primary btn-file" id="chose_files_btn">chose files <input id="filechose_button" type="file" name="fileData" size="1" style="display: none"/> </span> 

For more information, visit this link.

You should play around with this to get a better understanding of the spread of events.

+5
source

I needed to use "unbind click" so that my code worked fine.

 $("#chose_files_btn").unbind( "click" ); $("#chose_files_btn").click(function(event){ $("#filechose_button).click(); }); $("#filechose_button").unbind( "click" ); $("#filechose_button").click(function(event){ event.stopPropagation(); }); 
0
source

It seems that there may still be situations where the DOM bounces off the event, so the method of hiding the input field and programming its click is susceptible. Now I'm working on a modal dialog in an AngularJS application (intended for use on mobile devices with a corridor or on a desktop browser), which should run the file collector where this happens, and none of the above methods have helped.

When I put console logs in the bouncing event, it shows that the echo can arrive up to 1 second after the initial click.

The following is a solution that overcomes it by creating a small stack of events and eliminating duplicates that occur within 2 seconds.

Cheers, Z.

 <div id="fileInputImagePicker-container" onclick="openJustOnce( event )"> <script> var eventRecords=[]; const MAX_BOUNCE_DELAY = 2000; function addEvent( event ){ eventRecords.push( {id: event.target.id, time: Date.now()}) } function isBounceEvent( event ){ var ret = false, now = Date.now(), latestTime=0; for( var i=0; i < eventRecords.length && !ret; i++ ){ var record = eventRecords[ i ]; if( record.time > latestTime ) latestTime = record.time; if( record.id === event.target.id && (now - record.time) < MAX_BOUNCE_DELAY ){ ret = true; //console.log('BOUNCE EVENT, record=', JSON.stringify(record), ' event=', event); } } if( now - latestTime > MAX_BOUNCE_DELAY ) eventRecords = []; if( !ret ) addEvent( event ); return ret; } function openJustOnce( event ) { //console.log( "container event, event=", event, " event.target=", event.target, " now=", Date.now() ); if( isBounceEvent(event) ) { event.stopPropagation(); event.preventDefault(); //console.log( "BLOCK THIS EVENT" ); } else { fileInputImagePicker.click(); //console.log( "DONT BLOCK" ); } } </script> <input type="file" accept="image/*" id="fileInputImagePicker" style="display:none" /> </div> 
0
source

I have a complex application and for some reason the following jQuery selector:

 $('input[type=file]') 

returned two jQuery elements instead of one.

So call:

 $('input[type=file]').trigger('click') 

The called up two file dialog box open one after another.

To solve this problem, I just applied the click trigger on the first element

 $($('input[type=file]').get(0)).trigger('click'); 

Also, I used unbind and stopped the event propagation, here is the full code:

 $('#uploadFile').click(function(evt) { evt.stopPropagation(); evt.preventDefault(); evt = evt || window.event; if(evt.target.id == 'uploadFile'){ $($('input[type=file]').get(0)).trigger('click'); } }); $(':file').unbind(); $(':file').on('change', function(evt) { // extra non-relevant code }); 
0
source

All Articles