注意问题:
1. 使用document.createElement动态创建HTML元素,name属性在IE下无法直接设置,需要使用以下方法(参见http://www.thunderguy.com/semicolon/2005/05/23/setting-the-name-attribute-in-internet-explorer/)
设置name属性
function createNamedElement(type, name) {
var element = null;
// Try the IE way; this fails on standards-compliant browsers
try {
element = document.createElement('<'+type+' name="'+name+'">');
} catch (e) {
}
if (!element || element.nodeName != type.toUpperCase()) {
// Non-IE browser; use canonical method to create named element
element = document.createElement(type);
element.name = name;
}
return element;
}
var element = null;
// Try the IE way; this fails on standards-compliant browsers
try {
element = document.createElement('<'+type+' name="'+name+'">');
} catch (e) {
}
if (!element || element.nodeName != type.toUpperCase()) {
// Non-IE browser; use canonical method to create named element
element = document.createElement(type);
element.name = name;
}
return element;
}
2. 使用appendChild方法加入的元素,如果此元素有事件,有时事件无法响应;所以代码中使用了insertHtml(where, el, html)函数,此函数对IE和Firefox都兼容
以下是代码部分(样式、图片等可能丢了,需要你自己修改下)
JScript.js
//Get attachment file count by control id
function GetFileCount(ctrlId) {
var container = document.getElementById(ctrlId + '_pnHd');
var count = 0;
for (var i = 0; i < container.childNodes.length; i++) {
if (container.childNodes[i].nodeName == 'INPUT') {
count = count + 1;
}
}
return count;
}
//get next file serial number
function GetCurFileNo(ctrlId) {
var count = 0;
var hd = document.getElementById(ctrlId + '_fileCount');
if (hd != null && hd.value != '') {
return parseInt(hd.value);
}
}
//get next file serial number
function IncreaseFileNo(ctrlId) {
var hd = document.getElementById(ctrlId + '_fileCount');
if (hd != null && hd.value != '') {
var num = parseInt(hd.value);
hd.value = num + 1;
}
}
//prepare upload a file
function UploadBtn_OnMounseOver(ctrlId, eventSrc, e) {
var container = document.getElementById(ctrlId + '_pnHd');
var lastFileCtrl = null;
//get last file control (find from end to begin for performance reason)
for (var index = container.childNodes.length - 1; index > -1; index--) {
lastFileCtrl = container.childNodes[index];
if (lastFileCtrl.nodeName == 'INPUT') {
break;
}
}
var top = eventSrc.style.top == '' ? eventSrc.offsetTop : eventSrc.style.top;
var left = e.clientX - lastFileCtrl.offsetWidth / 2; //obj.style.width.replace('px', '')
//if document.body set margin, enable below two lines
var topM = 0; //document.body.topMargin;
var leftM = 0; //document.body.leftMargin;
lastFileCtrl.style.top = parseInt(top) + parseInt(topM);
lastFileCtrl.style.left = parseInt(left) + parseInt(leftM);
}
//File content change event
function File_Change(ctrlId, obj) {
if (obj.value != '') {
CreateFileNameListElement(ctrlId, obj);
}
obj.style.top = '';
obj.style.left = '';
CreateFileElement(ctrlId);
IncreaseFileNo(ctrlId);
}
//Remove attachment file
function Attach_Delete(ctrlId, fileNo) {
var fileContainer = document.getElementById(ctrlId + '_pnHd');
var nameListContainer = document.getElementById(ctrlId + '_pnNameList');
var file = document.getElementById(ctrlId + '_file' + fileNo);
var fileName = document.getElementById(ctrlId + '_fileName' + fileNo);
if (fileContainer != null && file != null) {
fileContainer.removeChild(file);
}
if (nameListContainer != null && fileName != null) {
nameListContainer.removeChild(fileName);
}
}
//add file name
function CreateFileNameListElement(ctrlId, obj) {
var pnNameList = document.getElementById(ctrlId + '_pnNameList');
if (pnNameList != null) {
var fileName = obj.value.substr(obj.value.lastIndexOf('\\') + 1, obj.value.length);
var fileExt = fileName.substr(fileName.lastIndexOf('.') + 1, fileName.length);
var div = document.createElement('div');
var divId = ctrlId + '_fileName' + GetCurFileNo(ctrlId);
div.id = divId;
div.className = 'attached-file';
var span = document.createElement('span');
span.innerText = fileName;
switch (fileExt) {
case 'doc':
span.className = 'attached-doc';
break;
case 'pdf':
span.className = 'attached-pdf';
break;
case 'xls':
case 'xlsx':
span.className = 'attached-excel';
break;
default:
span.className = 'attached-other';
break;
}
var a = document.createElement('a');
a.href = '###';
a.className = 'attached-del';
a.innerHTML = ' ';
a.onclick = 'Attach_Delete("' + ctrlId + '", "' + GetCurFileNo(ctrlId) + '");';
insertHtml('beforeEnd', div, span.outerHTML);
insertHtml('beforeEnd', div, a.outerHTML);
insertHtml('beforeEnd', pnNameList, div.outerHTML);
}
}
//add file element
function CreateFileElement(ctrlId) {
var fileId = ctrlId + '_file' + (GetCurFileNo(ctrlId) + 1);
var container = document.getElementById(ctrlId + '_pnHd');
if (container != null) {
var file = null;
// Try the IE way; this fails on standards-compliant browsers
try {
file = document.createElement('<input name="' + fileId + '">');
} catch (e) {
}
if (!file || file.nodeName != 'INPUT') {
// Non-IE browser; use canonical method to create named element
file = document.createElement('input');
file.name = fileId;
}
file.type = 'file';
file.id = fileId;
file.name = fileId;
file.className = 'attach';
file.onchange = 'File_Change("' + ctrlId + '",this);';
insertHtml('beforeEnd', container, file.outerHTML);
}
}
//compatiable with IE & Firefox
function insertHtml(where, el, html) {
where = where.toLowerCase();
if (el.insertAdjacentHTML) {
switch (where) {
case "beforebegin":
el.insertAdjacentHTML('BeforeBegin', html);
return el.previousSibling;
case "afterbegin":
el.insertAdjacentHTML('AfterBegin', html);
return el.firstChild;
case "beforeend":
el.insertAdjacentHTML('BeforeEnd', html);
return el.lastChild;
case "afterend":
el.insertAdjacentHTML('AfterEnd', html);
return el.nextSibling;
}
throw 'Illegal insertion point -> "' + where + '"';
}
var range = el.ownerDocument.createRange();
var frag;
switch (where) {
case "beforebegin":
range.setStartBefore(el);
frag = range.createContextualFragment(html);
el.parentNode.insertBefore(frag, el);
return el.previousSibling;
case "afterbegin":
if (el.firstChild) {
range.setStartBefore(el.firstChild);
frag = range.createContextualFragment(html);
el.insertBefore(frag, el.firstChild);
return el.firstChild;
} else {
el.innerHTML = html;
return el.firstChild;
}
case "beforeend":
if (el.lastChild) {
range.setStartAfter(el.lastChild);
frag = range.createContextualFragment(html);
el.appendChild(frag);
return el.lastChild;
} else {
el.innerHTML = html;
return el.lastChild;
}
case "afterend":
range.setStartAfter(el);
frag = range.createContextualFragment(html);
el.parentNode.insertBefore(frag, el.nextSibling);
return el.nextSibling;
}
throw 'Illegal insertion point -> "' + where + '"';
}
function GetFileCount(ctrlId) {
var container = document.getElementById(ctrlId + '_pnHd');
var count = 0;
for (var i = 0; i < container.childNodes.length; i++) {
if (container.childNodes[i].nodeName == 'INPUT') {
count = count + 1;
}
}
return count;
}
//get next file serial number
function GetCurFileNo(ctrlId) {
var count = 0;
var hd = document.getElementById(ctrlId + '_fileCount');
if (hd != null && hd.value != '') {
return parseInt(hd.value);
}
}
//get next file serial number
function IncreaseFileNo(ctrlId) {
var hd = document.getElementById(ctrlId + '_fileCount');
if (hd != null && hd.value != '') {
var num = parseInt(hd.value);
hd.value = num + 1;
}
}
//prepare upload a file
function UploadBtn_OnMounseOver(ctrlId, eventSrc, e) {
var container = document.getElementById(ctrlId + '_pnHd');
var lastFileCtrl = null;
//get last file control (find from end to begin for performance reason)
for (var index = container.childNodes.length - 1; index > -1; index--) {
lastFileCtrl = container.childNodes[index];
if (lastFileCtrl.nodeName == 'INPUT') {
break;
}
}
var top = eventSrc.style.top == '' ? eventSrc.offsetTop : eventSrc.style.top;
var left = e.clientX - lastFileCtrl.offsetWidth / 2; //obj.style.width.replace('px', '')
//if document.body set margin, enable below two lines
var topM = 0; //document.body.topMargin;
var leftM = 0; //document.body.leftMargin;
lastFileCtrl.style.top = parseInt(top) + parseInt(topM);
lastFileCtrl.style.left = parseInt(left) + parseInt(leftM);
}
//File content change event
function File_Change(ctrlId, obj) {
if (obj.value != '') {
CreateFileNameListElement(ctrlId, obj);
}
obj.style.top = '';
obj.style.left = '';
CreateFileElement(ctrlId);
IncreaseFileNo(ctrlId);
}
//Remove attachment file
function Attach_Delete(ctrlId, fileNo) {
var fileContainer = document.getElementById(ctrlId + '_pnHd');
var nameListContainer = document.getElementById(ctrlId + '_pnNameList');
var file = document.getElementById(ctrlId + '_file' + fileNo);
var fileName = document.getElementById(ctrlId + '_fileName' + fileNo);
if (fileContainer != null && file != null) {
fileContainer.removeChild(file);
}
if (nameListContainer != null && fileName != null) {
nameListContainer.removeChild(fileName);
}
}
//add file name
function CreateFileNameListElement(ctrlId, obj) {
var pnNameList = document.getElementById(ctrlId + '_pnNameList');
if (pnNameList != null) {
var fileName = obj.value.substr(obj.value.lastIndexOf('\\') + 1, obj.value.length);
var fileExt = fileName.substr(fileName.lastIndexOf('.') + 1, fileName.length);
var div = document.createElement('div');
var divId = ctrlId + '_fileName' + GetCurFileNo(ctrlId);
div.id = divId;
div.className = 'attached-file';
var span = document.createElement('span');
span.innerText = fileName;
switch (fileExt) {
case 'doc':
span.className = 'attached-doc';
break;
case 'pdf':
span.className = 'attached-pdf';
break;
case 'xls':
case 'xlsx':
span.className = 'attached-excel';
break;
default:
span.className = 'attached-other';
break;
}
var a = document.createElement('a');
a.href = '###';
a.className = 'attached-del';
a.innerHTML = ' ';
a.onclick = 'Attach_Delete("' + ctrlId + '", "' + GetCurFileNo(ctrlId) + '");';
insertHtml('beforeEnd', div, span.outerHTML);
insertHtml('beforeEnd', div, a.outerHTML);
insertHtml('beforeEnd', pnNameList, div.outerHTML);
}
}
//add file element
function CreateFileElement(ctrlId) {
var fileId = ctrlId + '_file' + (GetCurFileNo(ctrlId) + 1);
var container = document.getElementById(ctrlId + '_pnHd');
if (container != null) {
var file = null;
// Try the IE way; this fails on standards-compliant browsers
try {
file = document.createElement('<input name="' + fileId + '">');
} catch (e) {
}
if (!file || file.nodeName != 'INPUT') {
// Non-IE browser; use canonical method to create named element
file = document.createElement('input');
file.name = fileId;
}
file.type = 'file';
file.id = fileId;
file.name = fileId;
file.className = 'attach';
file.onchange = 'File_Change("' + ctrlId + '",this);';
insertHtml('beforeEnd', container, file.outerHTML);
}
}
//compatiable with IE & Firefox
function insertHtml(where, el, html) {
where = where.toLowerCase();
if (el.insertAdjacentHTML) {
switch (where) {
case "beforebegin":
el.insertAdjacentHTML('BeforeBegin', html);
return el.previousSibling;
case "afterbegin":
el.insertAdjacentHTML('AfterBegin', html);
return el.firstChild;
case "beforeend":
el.insertAdjacentHTML('BeforeEnd', html);
return el.lastChild;
case "afterend":
el.insertAdjacentHTML('AfterEnd', html);
return el.nextSibling;
}
throw 'Illegal insertion point -> "' + where + '"';
}
var range = el.ownerDocument.createRange();
var frag;
switch (where) {
case "beforebegin":
range.setStartBefore(el);
frag = range.createContextualFragment(html);
el.parentNode.insertBefore(frag, el);
return el.previousSibling;
case "afterbegin":
if (el.firstChild) {
range.setStartBefore(el.firstChild);
frag = range.createContextualFragment(html);
el.insertBefore(frag, el.firstChild);
return el.firstChild;
} else {
el.innerHTML = html;
return el.firstChild;
}
case "beforeend":
if (el.lastChild) {
range.setStartAfter(el.lastChild);
frag = range.createContextualFragment(html);
el.appendChild(frag);
return el.lastChild;
} else {
el.innerHTML = html;
return el.lastChild;
}
case "afterend":
range.setStartAfter(el);
frag = range.createContextualFragment(html);
el.parentNode.insertBefore(frag, el.nextSibling);
return el.nextSibling;
}
throw 'Illegal insertion point -> "' + where + '"';
}
代码
<%@ page language="C#" autoeventwireup="true" codefile="Default.aspx.cs" inherits="_Default" %>
<%@ register assembly="ClassLibrary1" namespace="ClassLibrary1" tagprefix="uc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link rel="Stylesheet" href="css/CommonStyle.css" />
<script type="text/javascript" src="JScript.js"></script>
<style type="text/css">
.imgUpload
{
width: 100px;
height: 20px;
background: url(images/icon_calendar.gif) left top no-repeat;
background-color: Blue;
}
.attach
{
position: absolute;
overflow:hidden;
width: 72px;
height: 26px;
filter: alpha(opacity=30);
}
.AddFile
{
width: 91px;
height: 26px;
background: url(images/Add_File.png);
}
</style>
</head>
<body>
<form id="form1" method="post" runat="server" enctype="multipart/form-data">
<div>
<uc1:wmcfileupload id="upload1" runat="server" />
<div class="clr">
</div>
<div class="clr">
</div>
<asp:button runat="server" text="上传" id="Button1"></asp:button>
</div>
</form>
</body>
</html>
<%@ register assembly="ClassLibrary1" namespace="ClassLibrary1" tagprefix="uc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link rel="Stylesheet" href="css/CommonStyle.css" />
<script type="text/javascript" src="JScript.js"></script>
<style type="text/css">
.imgUpload
{
width: 100px;
height: 20px;
background: url(images/icon_calendar.gif) left top no-repeat;
background-color: Blue;
}
.attach
{
position: absolute;
overflow:hidden;
width: 72px;
height: 26px;
filter: alpha(opacity=30);
}
.AddFile
{
width: 91px;
height: 26px;
background: url(images/Add_File.png);
}
</style>
</head>
<body>
<form id="form1" method="post" runat="server" enctype="multipart/form-data">
<div>
<uc1:wmcfileupload id="upload1" runat="server" />
<div class="clr">
</div>
<div class="clr">
</div>
<asp:button runat="server" text="上传" id="Button1"></asp:button>
</div>
</form>
</body>
</html>
实现方式已经封装成了控件
代码
using System;
using System.Web.UI.WebControls;
namespace ClassLibrary1
{
public class WmcFileUpload : WebControl
{
Panel pnContainer = new Panel();
Panel pnHidden = new Panel();
Panel pnNameList = new Panel();
FileUpload upload1 = new FileUpload();
Panel pnTip = new Panel();
HiddenField hdFileCount = new HiddenField();
public WmcFileUpload()
{
//upload1.ID = this.ID + "_file1";
}
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
//Init
upload1.ID = this.ID + "_file1";
upload1.CssClass = "attach";
upload1.Attributes.Add("onchange", "File_Change('" + this.ID + "', this)");
hdFileCount.ID = this.ID + "_fileCount";
hdFileCount.Value = "1";
pnContainer.ID = this.ID;
pnContainer.RenderBeginTag(writer);//div begin tag
//add file image button control
Panel pnAddFile = new Panel();
pnAddFile.CssClass = "left AddFile";
pnAddFile.Attributes.Add("onmouseover", "UploadBtn_OnMounseOver('" +this.ID + "', this, event)");
pnAddFile.RenderControl(writer);
//tip
pnTip.CssClass="left left5 grey";
pnTip.RenderBeginTag(writer);
writer.Write("附件最大限制为10M,最小10K");
pnTip.RenderEndTag(writer);
//hidden div
pnHidden.ID = this.ID + "_pnHd";
pnHidden.RenderBeginTag(writer);
upload1.RenderControl(writer); //fileupload control
pnHidden.RenderEndTag(writer);
writer.Write("<div class=\"clr\"></div>");
//NameList div
pnNameList.ID = this.ID + "_pnNameList";
pnNameList.CssClass = "attached";
pnNameList.RenderControl(writer);
hdFileCount.RenderControl(writer);
pnContainer.RenderEndTag(writer);//div end tag
}
}
}
using System.Web.UI.WebControls;
namespace ClassLibrary1
{
public class WmcFileUpload : WebControl
{
Panel pnContainer = new Panel();
Panel pnHidden = new Panel();
Panel pnNameList = new Panel();
FileUpload upload1 = new FileUpload();
Panel pnTip = new Panel();
HiddenField hdFileCount = new HiddenField();
public WmcFileUpload()
{
//upload1.ID = this.ID + "_file1";
}
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
//Init
upload1.ID = this.ID + "_file1";
upload1.CssClass = "attach";
upload1.Attributes.Add("onchange", "File_Change('" + this.ID + "', this)");
hdFileCount.ID = this.ID + "_fileCount";
hdFileCount.Value = "1";
pnContainer.ID = this.ID;
pnContainer.RenderBeginTag(writer);//div begin tag
//add file image button control
Panel pnAddFile = new Panel();
pnAddFile.CssClass = "left AddFile";
pnAddFile.Attributes.Add("onmouseover", "UploadBtn_OnMounseOver('" +this.ID + "', this, event)");
pnAddFile.RenderControl(writer);
//tip
pnTip.CssClass="left left5 grey";
pnTip.RenderBeginTag(writer);
writer.Write("附件最大限制为10M,最小10K");
pnTip.RenderEndTag(writer);
//hidden div
pnHidden.ID = this.ID + "_pnHd";
pnHidden.RenderBeginTag(writer);
upload1.RenderControl(writer); //fileupload control
pnHidden.RenderEndTag(writer);
writer.Write("<div class=\"clr\"></div>");
//NameList div
pnNameList.ID = this.ID + "_pnNameList";
pnNameList.CssClass = "attached";
pnNameList.RenderControl(writer);
hdFileCount.RenderControl(writer);
pnContainer.RenderEndTag(writer);//div end tag
}
}
}