5

我有一个file <input> field和一个<span>装饰输入字段:

<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>

虽然这种行为与我在ChromeSafari中行为一样,但FireFox在单击. file input dialogsbutton(span)

为什么会这样?

我假设,该文件输入字段是不可见的,只能通过具有按钮行为的跨度访问它。

更新:

如果我把它的<input>外部<span>表现正常。

 <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

但为什么就inside position没有呢?

4

5 回答 5

8

这是因为某种事件传播混乱

<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>

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

演示:小提琴

于 2013-04-30T05:10:59.187 回答
7

这是因为事件传播。当您单击跨度时,会引发单击事件,并且在单击处理程序中您调用了单击输入类型 =“文件”,因此它调用了两次。

如果您尝试以下代码,它不会引发传播事件。

<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>

欲了解更多信息,请访问此链接

您应该使用它来获得对事件传播的更多理解。

于 2013-04-30T06:44:56.250 回答
1

我有一个复杂的应用程序,出于某种原因,下面的 jQuery 选择器:

$('input[type=file]')

返回两个 jQuery 元素而不是一个。

所以调用:

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

触发两个文件对话框依次打开。

为了解决这个问题,我只在第一个元素上应用了点击触发器

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

另外我使用了 unbind 并停止了事件传播,这里是完整的代码:

$('#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
    });
于 2019-06-05T07:29:08.917 回答
0

似乎仍然存在 DOM 反弹事件的情况,因此隐藏输入字段并将其编程为单击的技术很容易受到影响。我现在正在开发需要启动文件选择器的 AngularJS 应用程序(设计用于带有 cordova 的移动设备或桌面浏览器)中的模式对话框,在这种情况下会发生这种现象并且上述技术都没有帮助。

当我将控制台日志放在弹跳事件上时,它显示回声可以在原始点击后最多 1 秒到达。

以下是一个解决方案,它通过创建一小堆事件并消除在 2 秒内发生的重复事件来克服它。

干杯,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>

于 2018-02-25T04:02:33.130 回答
0

我需要使用“取消绑定点击”来让我的代码正常工作。

$("#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();
});
于 2018-02-08T10:41:31.580 回答