Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery .fadeOut Callback to .click Not Working

I'm working on an image uploader app, and everything is working great except for one bug, which is occurring only in Chrome. I've stripped down the problem to one callback which isn't going through.

The issue is that a .fadeOut callback to a .click() trigger isn't triggering. I've recreated a simplified version in a fiddle which is linked below. The first click starts the fadeOut, and when the fadeOut is finished, the .click trigger doesn't happen. Clicking a second time Does then trigger the trigger. Any ideas why?

HTML:

<div><input type="file" name="image_file" id="image_file"/></div>

<div class="overlay_wrap">
    Overlast
</div>

<a id="click" href="">Click</a>

jQuery:

$(document).ready(function() {
    $("#click").click(function(event) {
        event.preventDefault();
        $('.overlay_wrap').fadeOut(1000, function(event){
            $('#image_file').trigger('click');
        });
    });
});

http://jsfiddle.net/gg2a7/5/

Thank you for the help!

EDIT: Had the old Fiddle link, changed.

like image 859
Andy Mercer Avatar asked Nov 04 '22 03:11

Andy Mercer


1 Answers

Sadly, this will not work. It all has to do with timing/threading functions inside browsers.

The core of the problem is this: The <input type="file" /> can not be opened programmatically (Loads of questions on SO / stuff on Google about it). It's not only Chrome; Firefox is showing a message that a pop-up is blocked, Safari will block it too, and in IE the form will not submit.

The reason behind this is because it's a potential security risk. Only a user action can result inside opening this <input type="file" />. Because of the .fadeOut(), the browser doesn't recognize this as a user event anymore. Now we're getting back to the timing/threading of the browsers, since this does work. There isn't any delegation, nor another thread/timeout of some sort that prevents the dialog from opening.

$("#click").click(function(event) {
    event.preventDefault();
    $('#image_file').trigger('click');
});

JSFiddle.

To show that it is actually the <input type="file" />, here's an example with <input type="button" /> that does work:

HTML

<input type="button" name="image_file" id="image_file" value="type='button'" />

JS

$("#click").click(function(event) {
        event.preventDefault();
        $('.overlay_wrap').fadeOut(1000, function(){
            $('#image_file').trigger('click');
        });
    });

    $('#image_file').click(function() {
         alert('ok');   
    });

JSFiddle.

Long story short: You can't do this with a fade effect. You can simply open the dialog and hide the element, but that's all there is to it.

$("#click").click(function(event) {
    event.preventDefault();
    $('.overlay_wrap').hide();
    $('#image_file').trigger('click');
});

JSFiddle.

like image 97
MarcoK Avatar answered Nov 08 '22 08:11

MarcoK