【问题标题】:Reading a local file a _second_ time using the html5 file reader API使用 html5 文件阅读器 API 读取本地文件 _second_ 次
【发布时间】:2021-02-12 02:01:49
【问题描述】:

我目前正在开发一些小型辅助实用程序。该方法是通常从本地文件系统加载的页内 Web 应用程序。这一切都有效。在该应用程序中,我需要能够加载和处理 local 文件(存储和重新加载配置文件)。到目前为止有效,但我还有一个问题想寻求帮助:

我在 html5 文件阅读器 API 周围使用 filereader.js 包装器。到目前为止一切正常,我能够在页面内选择、读取和处理文件。伟大的!我什至可以一个接一个地处理几个文件。但是有一个问题是我不知道如何开始调试它:我可以第二次读取特定文件。我可以选择它,当然,但它没有被读取,因此没有被处理。看起来文件阅读器 API 根本没有生成任何事件。这可能连接到缓存或文件的先前使用没有被我正确终止,我不知道。

下面是相关代码:

我的 FileReader JS 函数:

function FileReader( selector, options ) {
    var options = $.extend({
        clicked:  function(){},
        payload:  function(){},
        selected: function(){}
    }, options||{} );
    var widget   = convert( selector );
    var selector = widget.find( 'input:file');

    function clicked( event ) {
        event.stopPropagation();
        // highlight button as user feedback
        highlight();
        // raise the file selection dialog
        selector.click();
        // signal action to element
        options.clicked();
    }

    function convert( selector ) {
        var widget = $( selector );
        // create new content for widget
        var hotspot = $( '<a class="hotspot">' + widget.html() + '</a>' ).bind( 'click', clicked );
        var selector = $( '<input type="file" style="display:none;" />' );
        // replace initial content of widget
        widget.empty().append( $('<form />').append(selector).append(hotspot) );
        widget.find( 'input:file' ).fileReaderJS( { accept: false,
                                                                                                readAsDefault: 'BinaryString',
                                                                                                on: { load: selected } } );
        return widget;
    }

    function highlight() {
        // flash button by changing the background color for 100 msecs
        widget.css( 'background-color', 'whitesmoke' );
        setTimeout( function(){ widget.css( 'background-color', 'transparent' ); }, 100 );
    }

    function selected( event, file ) {
        // process payload
        options.payload( event.target.result );
        // signal event to controlling element
        options.selected();
    }

    return {}
} // FileReader

这个方法是用'#wProfileImport'作为参数selector的值调用的,它实际上工作并转换下面的标记

<span id="wProfileImport" class="control button">
    <img src="assets/img/profile-import.png">
</span>

这样它包含一个(隐藏的)文件输入标签,用于触发文件选择对话框(工作正常):

<span id="wProfileImport" class="control button">
    <form>
        <input type="file" style="display:none">
    </form>
    <a class="hotspot">
        <img src="assets/img/profile-import.png">
    </a>
</span>

现在,当单击图像时,文件选择器被触发,我可以选择一个 本地 文件,并将其内容移交给options.payload 回调。如前所述,一切都很好,并且一个接一个地为多个文件工作。剩下的唯一问题是:能够再次读取相同的文件。没有事件被触发,没有内容被读取,什么都没有。

所以我的问题是:如果用户选择了文件第二次,我该怎么做?

【问题讨论】:

  • 我认为你的问题是:用户选择文件A.ext,你的JavaScript 做了一些处理。用户再次选择文件A.ext 并且没有任何反应。这是正确的吗?
  • @Doge 这正是我的问题,是的。

标签: javascript jquery html


【解决方案1】:

这与 onchange 事件在 JavaScript 中的工作方式有关。

如果您有文本输入并输入了一个单词,假设为"bird"。您取消关注该字段,这将导致onchange 事件触发。如果您随后返回该字段并更改单词,则无需取消焦点将其更改回"bird" 并且然后取消焦点onchange 事件将不会触发,因为值没有改变。

不过,onkeydownonfocus 等其他事件将触发。

看看你是否能找到另一个你可以使用的事件。也许onclickonfocus。我确实担心这些火太早了。

一种解决方法,在您读取文件并在其位置渲染一个文件后销毁input。这样,如果用户选择 same 文件,它将再次被视为onchange

另一种可能性是不使用onchange 事件,而是在按下提交按钮后执行该过程。您可以通过以下方式获取对文件的引用:

var file = document.getElementById("#the_file_input").files[0];

【讨论】:

  • 没有提交按钮。我可以实现一个并捕获事件,但我更喜欢您的方法来简单地创建一个新的输入标签。听起来很简单,因为我可以简单地从已经存在的那个中获取细节......我会试一试......
  • 好的,我不得不重新组织一些东西,但是一般的方法确实有效。这证明确实问题在于输入标签的内容在第二次选择 same 文件的情况下没有改变。因此,您的回答为我指明了正确的方向。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多