文件输入标签单击的解决方法 (Firefox)

发布于 2024-12-09 14:40:23 字数 311 浏览 0 评论 0原文

<label for="input">Label</label><input type="file" id="input"/>

在 Firefox 7 中,无法通过单击标签来触发打开文件对话框。

这个问题非常相似,但它是绿色的,这是一个FF 中的错误。我正在寻找解决方法。

有什么想法吗?

<label for="input">Label</label><input type="file" id="input"/>

In Firefox 7 it is not possible to trigger the open file dialog by clicking on the label.

This SO question is very similar but that's green checked with it's a bug in FF. I'm looking for a workaround.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

蓝礼 2024-12-16 14:40:23

谢谢你的问答...帮助了我。

我对 @marten-wikstrom 解决方案的变体:

if($.browser.mozilla) {
  $(document).on('click', 'label', function(e) {
    if(e.currentTarget === this && e.target.nodeName !== 'INPUT') {
      $(this.control).click();
    }
  });
}

在任一解决方案中,使用 document.ready ($(function() {...});)的注释

  • 都是不必要的。 jQuery.fn.live 负责处理 @marten-wikstrom 的情况;在我的示例中,显式绑定到 document 是这样。
  • 使用 jQuery.fn.on...当前推荐的绑定技术。
  • 添加了 !== 'INPUT' 检查以确保执行不会陷入循环:

    <前><代码><标签>
    <输入类型=“文件”>

    (因为文件字段单击将冒泡回到标签)

  • event.target检查更改为event.currentTarget,允许初始单击< ;em> 中:

    
    
  • 使用 label 元素的 control 属性来实现更清晰、更简单、基于规范的表单字段关联。

thank you for this q&a... helped me out.

my variation of @marten-wikstrom's solution:

if($.browser.mozilla) {
  $(document).on('click', 'label', function(e) {
    if(e.currentTarget === this && e.target.nodeName !== 'INPUT') {
      $(this.control).click();
    }
  });
}

notes

  • using document.ready ($(function() {...});) is unnecessary, in either solution. jQuery.fn.live takes care of that in @marten-wikstrom's case; explicitly binding to document does in my example.
  • using jQuery.fn.on... current recommended binding technique.
  • added the !== 'INPUT' check to ensure execution does not get caught in a loop here:

    <label>
      <input type="file">
    </label>
    

    (since the file field click will bubble back up to the label)

  • change event.target check to event.currentTarget, allowing for initial click on the <em> in:

    <label for="field">click <em>here</em></label>
    
  • using the label element's control attribute for cleaner, simpler, spec-base form field association.
人生百味 2024-12-16 14:40:23

我想出了一个可行的解决方法:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript">
    $(function () {
        $("label").click(function () {
            $("#input").click();
        });
    });
</script>
<label for="input">Label</label><input type="file" id="input"/>

很奇怪的是,FF 允许您模拟文件输入上的点击。我认为这被认为是安全风险...

更新:这是一个通用的解决方法:

<script type="text/javascript">
    $(function () {
        if ($.browser.mozilla) {
            $("label").live("click", function (event) {
                if (event.target == this) {
                    $("#" + $(this).attr("for")).extend($("input", this)).first().click();
                }
            });
        }
    });
</script>

I came up with a feasible workaround:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript">
    $(function () {
        $("label").click(function () {
            $("#input").click();
        });
    });
</script>
<label for="input">Label</label><input type="file" id="input"/>

Quite strange that FF allows you to simulate a click on a file input. I thought that was considered a security risk...

UPDATE: This is a generic workaround:

<script type="text/javascript">
    $(function () {
        if ($.browser.mozilla) {
            $("label").live("click", function (event) {
                if (event.target == this) {
                    $("#" + $(this).attr("for")).extend($("input", this)).first().click();
                }
            });
        }
    });
</script>
回忆躺在深渊里 2024-12-16 14:40:23

使用 jQuery 浏览器检测时会出现一些问题,最明显的是使用浏览器检测而不是功能检测的反模式,此外 1.9+ 不提供该功能。

也许,我得出的解决方案有点虚伪,但它运作良好,并且似乎遵循了当今的大多数最佳实践。

首先,确保您使用 Paul Irish 的条件类。然后,使用类似:

  if($("html").hasClass("ie")) {
    $("label").click();
  } else {
    $("input").click();
  }

否则,我发现该事件将在 Chrome 等浏览器中双重触发。这个解决方案看起来足够优雅。

A couple problems arise when using the jQuery browser detection, most notably the anti-pattern of using browser detection rather than feature detection, in addition to the fact that 1.9+ doesn't provide that functionality.

Perhaps, then, the solution I arrived at is a bit hypocritical, but it worked well and seems to adhere to most best practices today.

First, ensure you're using Paul Irish's conditional classes. Then, use something like:

  if($("html").hasClass("ie")) {
    $("label").click();
  } else {
    $("input").click();
  }

Otherwise, I found the event would be double-fired in browsers such as Chrome. This solution seemed elegant enough.

注定孤独终老 2024-12-16 14:40:23

文件选择对话框可以通过 click() 事件。此问题的一个不显眼的解决方案可能如下所示:

$('label')
    .attr('for', null)
    .click(function() {
        $('#input').click();
    });

删除 for 属性很重要,因为其他浏览器(例如 Chrome、IE)仍然会批准它并显示对话框两次。

我在 Chrome 25、Firefox 19 和 IE 9 中测试了它,效果非常好。

The file-selection dialog can be triggered in all browsers by the click() event. An unobtrusive solution to this problem could look like that:

$('label')
    .attr('for', null)
    .click(function() {
        $('#input').click();
    });

Removing the for attribute is important since other browsers (e.g. Chrome, IE) will still ratify it and show the dialog twice.

I tested it in Chrome 25, Firefox 19 and IE 9 and works like a charm.

桜花祭 2024-12-16 14:40:23

它似乎在 FF 23 中得到了修复,因此浏览器检测变得危险并导致双系统对话框;(

您可以添加另一个测试来限制对版本 23 之前的 FF 版本的修复:

if(parseInt(navigator.buildID,10) < 20130714000000){
  //DO THE FIX
}

它非常丑陋,但此修复将被删除,因为一旦旧版本的FF就会消失。

It seems to be fixed in FF 23, so browser detection becomes hazardous and leads to double system dialogs ;(

You can add another test to restrict the fix to FF version prior to version 23:

if(parseInt(navigator.buildID,10) < 20130714000000){
  //DO THE FIX
}

It's quite ugly, but this fix will be removed as soon as old the version of FF will have disappeared.

眼角的笑意。 2024-12-16 14:40:23

当您不需要/不想有输入框(例如图像上传)时,解决方法是在元素中使用 opacity: 0 并使用 pointer-events: none;代码> 在标签中。
该解决方案确实是特定于设计的,但也许应该适用于遇到此问题的人。 (到目前为止,该错误尚未修复)

http://codepen.io/octavioamu/pen/ByOQBE< /a>

A work around when you don't need/want to have the input box (like image upload) is to use opacity: 0 in the element and use pointer-events: none; in the label.
The solution is really design specific but maybe should work for someone who comes to this. (until now the bug doesn't been fixed)

http://codepen.io/octavioamu/pen/ByOQBE

温柔嚣张 2024-12-16 14:40:23

颠倒标签和输入元素的顺序。 iow,将标签元素放在输入元素之后。

Reverse the order of the label and input elements. iow, put the label element after the input element.

你的往事 2024-12-16 14:40:23

如果需要,您可以将任何事件中的事件分派到 type=file 输入
使输入显示:无和可见性:隐藏,然后从以下位置调度事件:
比如说,点击|触摸图像......

<img id="customImg" src="file.ext"/>
<input id="fileLoader" type="file" style="display:none;visibility:hidden"/>

<script>
    customImg.addEventListener(customImg.ontouchstart?'touchstart':'click', function(e){
        var evt = document.createEvent('HTMLEvents');
        evt.initEvent('click',false,true);
        fileLoader.dispatchEvent(evt);
    },false);
</script>

you can dispatch the event from any event to the type=file input if you want
make the input display:none and visibility:hidden, and then dispatch the event from,
say, the click|touch of an image ...

<img id="customImg" src="file.ext"/>
<input id="fileLoader" type="file" style="display:none;visibility:hidden"/>

<script>
    customImg.addEventListener(customImg.ontouchstart?'touchstart':'click', function(e){
        var evt = document.createEvent('HTMLEvents');
        evt.initEvent('click',false,true);
        fileLoader.dispatchEvent(evt);
    },false);
</script>
画▽骨i 2024-12-16 14:40:23

React 环境中使用上面 Corey 的答案,我必须执行以下操作:

(Firefox 检查基于:如何检测 Safari、Chrome、IE、Firefox 和 Opera 浏览器?)


const ReactFileInputButton = ({ onClick }) => {

    const isFirefox = typeof InstallTrigger !== 'undefined';

    const handleClick = isFirefox ? (e) => {
        e.currentTarget.control.click();
    } : undefined;

    const handleFileSelect = (e) => {
        if (e.target.files && e.target.files[0]) {
            onClick({ file: e.target.files[0] });
        }
    }

    return (
        <>
            <input type="file" id="file" onChange={handleFileSelect} />
            <label htmlFor="file" onClick={handleClick}>
                Select file
            </label>
        </>
    );
};

Using the answer of Corey above in a React environment I had to do the following:

(Firefox check is based on: How to detect Safari, Chrome, IE, Firefox and Opera browser?)


const ReactFileInputButton = ({ onClick }) => {

    const isFirefox = typeof InstallTrigger !== 'undefined';

    const handleClick = isFirefox ? (e) => {
        e.currentTarget.control.click();
    } : undefined;

    const handleFileSelect = (e) => {
        if (e.target.files && e.target.files[0]) {
            onClick({ file: e.target.files[0] });
        }
    }

    return (
        <>
            <input type="file" id="file" onChange={handleFileSelect} />
            <label htmlFor="file" onClick={handleClick}>
                Select file
            </label>
        </>
    );
};
ゃ懵逼小萝莉 2024-12-16 14:40:23

试试这个代码

<img id="uploadPreview" style="width: 100px; height: 100px;" 
onclick="document.getElementById('uploadImage').click(event);" />
<input id="uploadImage" type="file" name="myPhoto" onchange="PreviewImage();" />
<script type="text/javascript">
    function PreviewImage() {
        var oFReader = new FileReader();
        oFReader.readAsDataURL(document.getElementById("uploadImage").files[0]);
        oFReader.onload = function (oFREvent) {
            document.getElementById("uploadPreview").src = oFREvent.target.result;
        };
    };
</script>

Try this code

<img id="uploadPreview" style="width: 100px; height: 100px;" 
onclick="document.getElementById('uploadImage').click(event);" />
<input id="uploadImage" type="file" name="myPhoto" onchange="PreviewImage();" />
<script type="text/javascript">
    function PreviewImage() {
        var oFReader = new FileReader();
        oFReader.readAsDataURL(document.getElementById("uploadImage").files[0]);
        oFReader.onload = function (oFREvent) {
            document.getElementById("uploadPreview").src = oFREvent.target.result;
        };
    };
</script>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文