• 网易邮箱添加附件功能原理浅析转


    本文转自http://blog.csdn.net/whwqs/article/details/2458628

    个人觉得网易邮箱的添加附件功能是比较酷的,这两天网上网下研究了下。有些心得写出来,免得遗忘。

    一切起源于type为file的input,这是没话可多说的(这个东西很神秘)。为什么网易页面上却没有看见这个东西?看下面:

    <html>
    <head>
    <title>上传控件演示</title>
    </head>
    <body>
    <input type="file" id="f1" style="display:none;" />
    <input type="button" onclick="f1.click();" value="文件浏览" />
    </body>
    </html>

    正如上面看到的:看不见它,却也能够打开文件浏览框。

    做成网易效果了吗?

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="test.aspx.cs" Inherits="mytest_test" %>
    <!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>
    <title>上传控件演示</title>
    </head>
    <body>
    <form id="form1" runat="server">
    <input type="file" name="f1" id="f1" runat="server" />
    <input type="button" value="浏览文件" name="cbtn" onclick="f1.click();" />
    <asp:Button ID="submit" runat="server"  OnClick="Button1_Click1" Text="保存" />
    </form>
    </body>
    </html>
    using System;
    using System.Data;
    using System.Configuration;
    using System.Collections;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;

    public partial class mytest_test : System.Web.UI.Page
    {
        
    protected void Page_Load(object sender, EventArgs e)
        
    {
        }

        
    protected void Button1_Click1(object sender, EventArgs e)
        
    {
            Response.Write(
    "上传文件数目:"+Request.Files.Count.ToString());
        }

    }

    如上:点击f1后点击submit,有一个文件上传到服务端。点击cbtn后点击submit,连提交动作都没有。

    在客户端看来:点击f1后或点击cbtn后页面表现没有区别。

    网上的解释:浏览器的安全机制。

    上传文件要点:(1)必须要有鼠标点击;(2)必须点击在上传控件的浏览按钮上。

    类似163的实现:

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="test.aspx.cs" Inherits="mytest_test" %>
    <!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 id="Head1" runat="server">
    <title>163上传</title>
    <style type="text/css"> 
    a.addfile   
    { 
        background-image
    :url(http://p.mail.163.com/js31style/lib/0703131650/163blue/f1.gif); 
        background-repeat
    :no-repeat; 
        background-position
    :-915px   -17px; 
        display
    :block; 
        float
    :left; 
        height
    :20px; 
        margin-top
    :-1px; 
        position
    :relative; 
        text-decoration
    :none; 
        top
    :0pt; 
        width
    :80px; 
    }
     
     input.addfile   
    { 
        cursor
    :pointer   !important; 
        height
    :18px; 
        left
    :-13px; 
        filter
    :alpha(opacity=0);   
        position
    :absolute; 
        top
    :5px; 
        width
    :1px; 
        z-index
    :-1; 
    }
         
    </style>
    </head>
    <body>
    <form id="form1" runat="server">
    <div>
    <id="container1" class="addfile">
    <input id="file_0" name="file_0" type="file" class="addfile" runat="server" />
    </a>
    </div>        
    <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
    </form>
    </body>
    </html>
    using System;
    using System.Data;
    using System.Configuration;
    using System.Collections;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;

    public partial class mytest_test : System.Web.UI.Page
    {
        
    protected void Page_Load(object sender, EventArgs e)
        
    {
        }
        
        
    protected void Button1_Click(object sender, EventArgs e)
        
    {
            Response.Write(
    "上传文件数目:" + Request.Files.Count.ToString());
        }

    }

    要点:(1)把上传控件放在a标签中;(2)上传控件透明(不是display:none);(3)a标签衬背景。

    接下来,做批量的效果:

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="test.aspx.cs" Inherits="mytest_test" %>
    <!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 id="Head1" runat="server">
    <title>163上传</title>
    <style type="text/css"> 
    a.addfile   
    { 
        background-image
    :url(http://p.mail.163.com/js31style/lib/0703131650/163blue/f1.gif); 
        background-repeat
    :no-repeat; 
        background-position
    :-915px   -17px; 
        display
    :block; 
        float
    :left; 
        height
    :20px; 
        margin-top
    :-1px; 
        position
    :relative; 
        text-decoration
    :none; 
        top
    :0pt; 
        width
    :80px; 
    }
     
    input.addfile   
    { 
        cursor
    :pointer   !important; 
        height
    :18px; 
        left
    :-13px; 
        filter
    :alpha(opacity=0);   
        position
    :absolute; 
        top
    :5px; 
        width
    :1px; 
        z-index
    : -1; 
    }
     
    img.addfile 
    {
        background-image
    :url(http://p.mail.163.com/js31style/lib/0703131650/163blue/f1.gif); 
        background-repeat
    :no-repeat; 
        background-position
    :-802px   -36px; 
        width
    :13px;
        height
    :13px;
    }

    </style>
    <script type="text/javascript">
    window.$ 
    = document.getElementById;
    var fileNumber = 0;
    function createnew()
    {
        
    var c_a = $('container1');// 找到上传控件的a容器
        var c_div = $('container2');// 放置文件的容器
        var fileCtr = c_a.firstChild;// 上传控件
        
        
    var subDiv = document.createElement("div");// 将放置到c_div中的容器
        var span1 = document.createElement("span");// 上传的文件
        span1.innerText = fileCtr.value;
        
        
    var img2 = document.createElement("img");// 删除图片按钮
        img2.className = "addfile";
        img2.onclick 
    = function(){this.parentNode.parentNode.removeChild(this.parentNode)}
        
        subDiv.appendChild(span1);
        subDiv.appendChild(img2);    
        subDiv.appendChild(fileCtr);    
        
        
        c_div.appendChild(subDiv);
        
        fileNumber
    ++;
        
        
    var newFileCtr = document.createElement("input");
        newFileCtr.type 
    = "file";
        newFileCtr.className 
    = "addfile";
        newFileCtr.runat 
    = "server";
        newFileCtr.name 
    = "file_"+fileNumber;
        newFileCtr.onchange 
    = createnew;
        
    while(c_a.firstChild)
        
    {
            c_a.removeChild(c_a.firstChild);
        }

        
        c_a.appendChild(newFileCtr);
    }
        
    </script>

    </head>
    <body>
    <form id="form1" runat="server">
    <div>
    <id="container1" class="addfile">
    <input id="File1" name="file_0" type="file" class="addfile" onchange="createnew();" runat="server" />
    </a>
    </div>
    <div id="container2" style="position:relative; float:left; ">
    </div>
    <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
    </form>
    </body>
    </html>
    using System;
    using System.Data;
    using System.Configuration;
    using System.Collections;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;

    public partial class mytest_test : System.Web.UI.Page
    {
        
    protected void Page_Load(object sender, EventArgs e)
        
    {
        }
        
        
    protected void Button1_Click(object sender, EventArgs e)
        
    {
            
    string s = "";
            
    for (int i = 0; i < Request.Files.Count; i++)
            
    {
                s 
    += Request.Files[i].FileName + "<br/>";
            }

            Response.Write(s);
        }

    }

    差不多实现了163的添加附件效果,但未判断相同文件上传情况。

    要点:上传控件的onchange事件。这个事件在选择文件之后。在这个事件中移走旧的上传控件,创建新的上传控件。创建上传控件时一定别忘了name和runat这两个属性。

  • 相关阅读:
    FastMM、FastCode、FastMove的使用(图文并茂)
    12种JavaScript MVC框架之比较
    十款最佳Node.js MVC框架
    Couchbase 服务器
    C#程序员阅读的书籍
    ORM的实现
    Linux内核策略介绍
    ASP.NET MVC + EF 利用存储过程读取大数据
    面向.Net程序员的dump分析
    动态加载与插件化
  • 原文地址:https://www.cnblogs.com/sheseido/p/2252979.html
Copyright © 2020-2023  润新知