在输入类型=“文件”上取消事件

时间:2016-01-18 12:59:31

标签: javascript jquery file-upload

我正在使用标准文件输入进行上传,我正在寻找一种方法,当用户点击/点击输入选择文件的“取消”按钮(或退出)时,将功能附加到事件对话。

我找不到任何适用于所有浏览器和平台的事件。

我已经阅读了这个问题的答案:Capturing cancel event on input type=file但它们不起作用,因为在取消选择文件对话框时,大多数浏览器都不会触发更改事件。

我正在寻找一个纯粹的js解决方案,但也可以使用jquery解决方案。

有人成功解决了这个问题吗?

5 个答案:

答案 0 :(得分:12)

一些研究表明,在“文件选择”对话框窗口中无法检测何时选择“取消”。您可以使用onchangeonblur来检查文件是否已被选中,或者是否已将某些内容添加到输入value

这可能如下所示:https://jsfiddle.net/Twisty/j18td9cs/

<强> HTML

<form>
  Select File:
  <input type="file" name="test1" id="testFile" />
  <button type="reset" id="pseudoCancel">
    Cancel
  </button>
</form>

<强>的JavaScript

var inputElement = document.getElementById("testFile");
var cancelButton = document.getElementById("pseudoCancel");
var numFiles = 0;

inputElement.onclick = function(event) {
  var target = event.target || event.srcElement;
  console.log(target, "clicked.");
  console.log(event);
  if (target.value.length == 0) {
    console.log("Suspect Cancel was hit, no files selected.");
    cancelButton.onclick();
  } else {
    console.log("File selected: ", target.value);
    numFiles = target.files.length;
  }
}

inputElement.onchange = function(event) {
  var target = event.target || event.srcElement;
  console.log(target, "changed.");
  console.log(event);
  if (target.value.length == 0) {
    console.log("Suspect Cancel was hit, no files selected.");
    if (numFiles == target.files.length) {
      cancelButton.onclick();
    }
  } else {
    console.log("File selected: ", target.value);
    numFiles = target.files.length;
  }
}

inputElement.onblur = function(event) {
  var target = event.target || event.srcElement;
  console.log(target, "changed.");
  console.log(event);
  if (target.value.length == 0) {
    console.log("Suspect Cancel was hit, no files selected.");
    if (numFiles == target.files.length) {
      cancelButton.onclick();
    }
  } else {
    console.log("File selected: ", target.value);
    numFiles = target.files.length;
  }
}


cancelButton.onclick = function(event) {
  console.log("Pseudo Cancel button clicked.");
}

我建议您自己取消或重置按钮,重置表单或清除输入中的值。

答案 1 :(得分:2)

我有一个完美的解决方案。

焦点事件将在更改事件之前执行。

因此,我需要使用setTimeout来使focus方法晚于change方法执行。

const createUpload = () => {
    let lock = false
    return new Promise((resolve, reject) => {
        // create input file
        const el = document.createElement('input')
        el.id = +new Date()
        el.style.display = 'none'
        el.setAttribute('type', 'file')
        document.body.appendChild(el)

        el.addEventListener('change', () => {
            lock = true
            const file = el.files[0]
            
            resolve(file)
            // remove dom
            document.body.removeChild(document.getElementById(el.id))
        }, { once: true })

        // file blur
        window.addEventListener('focus', () => {
            setTimeout(() => {
                if (!lock && document.getElementById(el.id)) {
                    reject(new Error('onblur'))
                    // remove dom
                    document.body.removeChild(document.getElementById(el.id))
                }
            }, 300)
        }, { once: true })

        // open file select box
        el.click()
    })
}



try {
    const file = createUpload()
    console.log(file)
} catch(e) {
    console.log(e.message) // onblur
}

答案 2 :(得分:1)

当我们选择文件时,以下事件称为-

方案1::单击选择文件,然后单击取消

Focus事件值=“”

Click事件值=“”

Blur事件值=“”

Focus事件值=“”

Blur 事件值=“”(当用户单击某处时)

方案2::选择文件后-

Focus事件值=“”

Click事件值=“”

Blur事件值=“”

Focus事件值=“”

Change事件value =“ filevalue”

Blur事件value =“ filevalue”

Focus事件value =“ filevalue”

Blur 事件value =“ filevalue”(当用户单击某处时)

我们在这里看到,在焦点事件之后没有文件值的情况下调用Blur事件(最后一个事件)意味着单击了Cancel按钮。

我的情况是在加载文件时将“提交”按钮文本更改为“请稍候” currentEvent 变量用于保存当前事件的值(单击或聚焦) 如果currentEvent = focus并且文件值为null,则表示单击“取消”按钮。

Javascript

var currentEvent = "focus";

function onFileBrowse() {    
    var vtbFile = $('#uploadFile')[0].files[0];

    if (vtbFile != undefined) {
        var extension = vtbFile.name.split('.').pop().toLowerCase();
        var valError = "";

        if (extension === 'xlsx' || extension === 'xlsb' || extension === 'csv') {
            if (vtbFile.size === 0)
                valError = "File '" + vtbFile.name + "' is empty";
        }
        else
            valError = "Extension '" + extension + "' is not supported.";

        if (valError !== "") {            
            alert("There was an issue validating the file. " + valError, 20000);
        }        
    }
    //hide Indicator
    var buttonUpload = document.getElementById('btnUploadTB');
    buttonUpload.innerText = "Submit";
};


function fileClick() {
    //show Indicator
    var buttonUpload = document.getElementById('btnUploadTB');
    buttonUpload.innerText = "Please wait..";
    
    document.getElementById('uploadFile').value = null;   
    currentEvent = "click";
}
function fileFocus() {
    currentEvent = "focus";
}

function fileBlur() {
    
    if (!document.getElementById('uploadFile').value && currentEvent == "focus") {
        console.log('blur' + 'change to submit');
        //hide Indicator
        var buttonUpload = document.getElementById('btnUploadTB');
        buttonUpload.innerText = "Submit";
    }
}
HTML

<input class="k-button k-upload-button" type="file" id="uploadFile" name="uploadFile"
    accept=".csv,.xlsx,.xlsb" onChange='onFileBrowse()' onclick="fileClick()" onfocus="fileFocus()" onblur="fileBlur()" />

<button id="btnUploadTB" type="button" class="btn btn-default" onclick="uploadTBFile()" style="width:28%;margin-left: 3px;">Submit</button>

答案 3 :(得分:0)

在使用 jQuery 实现图像上传表单的自动提交后,我遇到了类似的问题。如果用户取消对话,它会发送一个空白。所需要做的就是在同一个脚本中检测这个空值:

for

答案 4 :(得分:-1)

我遇到了输入类型=&#34;文件&#34;上单击取消按钮的问题。元素,并希望功能什么都不做。如果选择了某些东西并且我点击了打开按钮,那么我希望我的功能可以做一些事情。该示例仅显示了该方法,我在打开后删除了对其执行的操作。我输入了警报,这样您就可以看到在单击取消时没有从对话框返回的文件名。 这是我使用的方法,它很简单但有效。

&#13;
&#13;
 function openFileOnClick(){
    document.getElementById("fileSelector").value = "";
    document.getElementById("fileSelector").files.length = 0;            
    document.getElementById("fileSelector").click();
    if(document.getElementById("fileSelector").files.length >= 1){
        alert(document.getElementById("fileSelector").value);
        //Do something 
    }
    else{
        alert(document.getElementById("fileSelector").value);
        //Cancel button has been called.
    }
}
&#13;
<html>
<head>
</head>
<body>
<input type="file" id="fileSelector" name="fileSelector" value="" style="display:none;"  />
<input type="button" value="Open File" name="openFile" onclick="openFileOnClick();" />
</body>
</html>
&#13;
&#13;
&#13;