使用 FileReader 打开文件时出现问题 API

Problem opening files with the FileReader API

这几天一直困扰着我。我有一个网络应用程序,允许用户从他们的本地机器打开文档。我是第一次使用 FileReader API。

除一个用例外,它工作正常。

执行此序列时,第二次尝试无提示地失败(除了未加载文件)。

这里有一个例子 Reagent program (created from the figwheel-main template) 可以说明问题。

(ns a-bad-button.core
  (:require [reagent.core :as r]))

(def app-state-ratom (r/atom nil))

(defn new-doc []
  {:doc-text "Some MINIMAL text to play with."})

(defn add-new-button
  [aps]
  (fn [aps]
    [:input.tree-demo--button
     {:type     "button"
      :value    "New"
      :on-click #(reset! aps (new-doc))}]))

(defn load-doc-data!
  [aps file-data]
  (swap! aps assoc :doc-text file-data))

(defn handle-file-open-selection
  [aps evt]
  (let [js-file-reader (js/FileReader.)]
    (set! (.-onload js-file-reader)
          (fn [evt] (load-doc-data! aps (-> evt .-target .-result))))
    (.readAsText js-file-reader (aget (.-files (.-target evt)) 0))))

(defn add-open-button
  [aps]
  (fn [aps]
    [:div
     [:input {:type      "file" :id "file-open-id"
              :style     {:display "none"}
              :on-change #(handle-file-open-selection aps %)}]
     [:input {:type     "button"
              :value    "Open"
              :on-click #(.click (.getElementById js/document "file-open-id"))}]]))

(defn a-bad-button
  [aps]
  (fn [aps]
    [:div
     [:h4 "A Bad Button"]
     [:p#doc-text-p (or (:doc-text @aps) "Loaded text will go here.")]
     [add-new-button aps]
     [add-open-button aps]]))

(defn mount! [el]
  (reset! app-state-ratom (new-doc))
  (r/render-component [a-bad-button app-state-ratom] el))

(defn mount-app-element []
  (when-let [el (.getElementById js/document "app")]
    (mount! el)))

(mount-app-element)

(defn ^:after-load on-reload []
  (mount-app-element))

使用 println 调试消息,似乎执行到达了 add-open-button 函数中的 :on-click 处理程序,但从未到达或执行处理程序 handle-file-open-selection .

Safari、Opera、Brave 和 Vivaldi 浏览器出现故障。文件在 Firefox 上按预期打开。

有没有人以前见过这个并修复它?

类似问题:

Filereader - upload same file again not working

FileReader onload not getting fired when selecting same file in Chrome

基本上,问题是选择相同文件时不会触发onChange。一种解决方法是在文件浏览器打开之前将文件输入的值设置为 "" 之类的值,以始终触发 onChange 事件。在您的情况下,它可能看起来像将 handle-file-open-selection 函数更改为:

(defn handle-file-open-selection
  [aps evt]
  (let [js-file-reader (js/FileReader.)]
    (set! (.-onload js-file-reader)
          (fn [evt]
            (load-doc-data! aps (-> evt .-target .-result))))
    (.readAsText js-file-reader (aget (.-files (.-target evt)) 0))
    ;; add this
    (set! (.-value (.getElementById js/document "file-open-id")) "")
    ))