编程开发 > ASP > 文章内容

简便无刷新文件上传系统(二)

2010-11-3编辑:dan

【form】

程序使用_setForm函数来创建用来提交数据的form。

要实现无刷新上传,要对form进行特殊的处理:

以下为引用的内容:
$$.extend(form, {
    target: this._iframe.name, method: "post", encoding: "multipart/form-data"
});

ps:详细看这里的无刷新上传部分。

由于form是手动插入的,为了不影响原来页面布局还要设置一下form样式,使它“隐形”起来:

以下为引用的内容:
$$D.setStyle(form, {
    padding: 0, margin: 0, border: 0,
    backgroundColor: "transparent", display: "inline"
});

还要注意的是,同一个表单控件只能对应一个form。如果file控件本身已经有一个form的话,必须在提交前移除:

以下为引用的内容:
file.form && $$E.addEvent(file.form, "submit", $$F.bind(this.remove, this));

remove方法是用来移除程序的,包括移除form。ps:如果提交前submit被覆盖的话要手动执行一次remove程序。

最后把form插入到dom: 

以下为引用的内容:
file.parentNode.insertBefore(form, file).appendChild(file);

先把form插入到file控件之前,然后把file插入到form,这样就能保证file在原来的位置上了。

【input】

如果有其他参数要传递,程序会使用_setInput函数来创建传递数据的表单控件。

由于生成的form里面只有file控件,要传递其他参数只能用程序生成了。程序用一个_inputs集合来保存当前在form中生成的表单控件。

首先根据自定义的parameter属性创建表单控件:

以下为引用的内容:
for ( name in this.parameter ) {
    var input = form[name];
    if ( !input ) {
        input = document.createElement("input");
        input.name = name; input.type = "hidden";
        form.appendChild(input);
    }
    input.value = this.parameter[name];
    newInputs[name] = input;
    delete oldInputs[name];
}

当form中没有对应name的控件时,会自动生成一个hidden控件插入到form中。其中newInputs是用来记录当前生成的控件的,而oldInputs就是_inputs集合。当设置过对应name的控件后,就从oldInputs中删除对应控件的关联。

然后移除oldInputs关联的控件:

以下为引用的内容:
for ( name in oldInputs ) { form.removeChild( oldInputs[name] ); }

这样就能移除上一次生成的无用的控件了。最后重新记录当前控件到_inputs方便下次使用。

【stop】

如果想停止当前上传操作,可以调用stop方法。

一般来说当iframe发生重载时,会取消上一次的载入,那么只要重新设置src就能取消上传了。测试以下代码:

以下为引用的内容:
<body>
<iframe id="ifr" name="ifr"></iframe>
<form action="http://cloudgamer.cnblogs.com/" target="ifr">
</form>
</body>
<script>
document.forms[0].submit();
document.getElementById("ifr").src = "";
</script>

结果都能取消加载,除了opera,未知什么原因。有两个方法解决,一个是通过form随便用一个action提交一次,还有就是直接移除iframe。后一个方法比较方便,程序中用_removeIframe方法直接移除iframe。ps:有更好方法的话记得告诉我。

【remove】

当使用结束或其他原因要清除程序时,可以调用remove方法。

remove里面主要做的是清除iframe和form。清除iframe用的是_removeIframe方法,首先把onload移除,再把iframe从body移除:

以下为引用的内容:
var iframe = this._iframe;
$$B.ie ? iframe.detachEvent( "onload", this._fFINISH ) : ( iframe.onload = null );
document.body.removeChild(iframe); this._iframe = null;

十分简单,但在ff有一个问题,测试以下代码:

以下为引用的内容:
<form target="ifr" action="x">
    <input id="btn" type="submit" value="click">
</form>
<iframe name="ifr" id="ifr"></iframe>
<script>
document.getElementById("btn").onclick = function(){
    document.getElementById("ifr").onload = function(){
        this.parentNode.removeChild(this);
    };
}
</script>

提交后都能移除iframe,但ff还一直显示“载入中”的状态。不过解决方法也很简单,用setTimeout设置一个延时,让iframe执行完整就可以了。所以在remove中是这样调用_removeIframe的:

以下为引用的内容:
if ( $$B.firefox ) {
    setTimeout($$F.bind(this._removeIframe, this), 0);
} else {
    this._removeIframe();
}

至于form的清除就比较简单,在_removeForm这样处理:

以下为引用的内容:
var form = this._form, parent = form.parentNode;
if ( parent ) {
    parent.insertBefore(this.file, form); parent.removeChild(form);
}
this._form = this._inputs = null;

要判断一下parentNode,否则如果parentNode不存在的话后面的会执行出错。
简便无刷新文件上传系统(一)

热点推荐

登录注册
触屏版电脑版网站地图