通过控件来实现目标:点击一个按钮,然后弹出对话框让你选择文件,选择文件完成之后就自动上传,而无需再点击一个额外的按钮(例如命名为“上传”的按钮)。
说明:(1)input(file)控件的onchange事件处理函数貌似只能用javascript函数处理,而不能通过像asp:button控件一样用服务器端处理函数来处理。具体例子:,而这样是无效果的。
(2)input(file)控件是无法通过代码触发onchange事件的,必须用户手点才能触发。
(3)input(file)控件只能实现一次一个文件上传。
实现思路:
我的思路是这样的,先创建一个"浏览文件"的button,然后再创建的控件(不过让其透明不可见),最后再建立一个"上传"button(也是不可见的)。在“浏览文件”的button上,我们就它的onmouseover事件添加一个javascript响应函数叫做floatFile(),该函数将不可见的控件移动到我们鼠标下面,然后,我们点击鼠标的时候,其实是点在控件上、从而跳出选择文件对话框。然后,我们就添加onchange事件响应(οnchange="fireEvent(node, event)")。fireEvent(node, event)方法用来触发一个特定控件的特定事件,我们这里具体是用来触发“上传”button(不可见)的onclick事件,然后再跳到该button的onclick“服务器端处理函数”。
总结起来,流程是这样的:onchange->(call)->fireEvent("上传按钮", click)->(call)“上传按钮”的onclick“服务器端处理函数”。通过这样的流程,我们就可以实现给input(file)控件的onchange事件"添加了""服务器端处理函数"。
我发个参考代码:(仅供参考,不保证该代码无错,因为这代码是我自己可以运行的代码经过我粗糙修改再上传的),全文关键在于我提供的思路。
test one key upload filefunction fireEvent(node, eventName) {
// Make sure we use the ownerDocument from the provided node to avoid cross-window problems
var doc;
if (node.ownerDocument) {
doc = node.ownerDocument;
}
else if (node.nodeType == 9) {
// the node may be the document itself, nodeType 9 = DOCUMENT_NODE
doc = node;
}
else {
throw new Error("Invalid node passed to fireEvent: " + node.id);
}
if (node.fireEvent) {
// IE-style
var event = doc.createEventObject();
event.synthetic = true; // allow detection of synthetic events
node.fireEvent("on" + eventName, event);
}
else if (node.dispatchEvent) {
// Gecko-style approach is much more difficult.
var eventClass = "";
// Different events have different event classes.
// If this switch statement can't map an eventName to an eventClass,
// the event firing is going to fail.
switch (eventName) {
case "click": // Dispatching of 'click' appears to not work correctly in Safari. Use 'mousedown' or 'mouseup' instead.
case "mousedown":
case "mouseup":
eventClass = "MouseEvents";
break;
case "focus":
case "change":
case "blur":
case "select":
eventClass = "HTMLEvents";
break;
default:
throw "fireEvent: Couldn't find an event class for event '" + eventName + "'.";
break;
}
var event = doc.createEvent(eventClass);
var bubbles = eventName == "change" ? false : true;
event.initEvent(eventName, bubbles, true); // All events created as bubbling and cancelable.
event.synthetic = true; // allow detection of synthetic events
node.dispatchEvent(event);
}
}
function $(id) {
return document.getElementById(id);
}
//全局变量,记录文件数;
var fileNum = 1;
//mouseover时,把input file移到按扭上,保证点击的是file,
function floatFile() {
$("file" + fileNum).style.posTop = event.srcElement.offsetTop;
$("file" + fileNum).style.posLeft = event.x - $("file" + fileNum).offsetWidth / 2;
}
//选择完一个文件之后,自动创建一个新的div 和 file表单,用于下回使用,hidden刚用过的file
function showText(obj) {
$("file" + fileNum).style.display = 'none';
fileNum = fileNum + 1;
//set input(text) showing the file name
getFileName(obj.value);
//fire event
//click the button "上传"
fireEvent($("uploadFileButton"), "click");
//直接追加innerHTML(innerHTML+=)会清空原来file中的内容
$("div" + (fileNum - 1)).insertAdjacentHTML('afterend', '
}
function getFileName(path) {
var _fileName = path.substring(path.lastIndexOf('\\') + 1, path.size);
$("selectedFileName").value = _fileName;
}
代码是为了加深对于思路的理解或者说是吸收。代码也许有错。至于再服务器端保存、修改上传上来的文件,在此不再多述,请谷歌之。
仅以此文献给和我一样为了一键上传文件而纠结了好久的新手们,大神一笑而过即可。(本文仅试验过input(file)控件,也许有其他控件能轻易实现,请大神不吝赐教)