Ajax 仿照百度即时下拉框

28 篇文章 0 订阅
23 篇文章 0 订阅

哎呦,累死我我了,当我完成这个小功能的时候,我的手指真的痛得不行了。

最近在学习Ajax 当我知道百度啊,谷歌啊他们的搜索网站上,那个即时的下拉框就是用Ajax来写的,我就心动了。然后花了一晚上时间来写这个功能;

好先说明一下程序开发的流程,截几张图过来看看。

第一步:建立好数据库

use MyBookShop
-----------------------------------------------------------------------------
drop table books
create table books
(
id int  primary key identity(1,1),
Title varchar(100) not null,
Author varchar(50) not null,
UnitPrice money,
Clicks int
)

drop table searchkeywords
create table SearchKeyWords   ----关键字的搜索统计
(
id int primary key  identity(1,1),
keyword varchar(50),
searchcount int
)
-----------------------------------------------------------------------------
insert into books values('C++Primer中文版','(美)李普曼 等著,陈硕评 注',50,0)
insert into books values('C++ Primer 中文版(C++Primer 3 Edition)第3版附带随书源码[压缩包]','(美)李普曼 等著,陈硕评 注',50,0)
insert into books values('C++Primer练习题中文版','(美)李普曼 等著,陈硕评 注',50,0)
insert into books values('C++数据结构中文版','(美)李普曼 等著,陈硕评 注',50,0)
insert into books values('C++设计模式中文版','(美)李普曼 等著,陈硕评 注',50,0)

insert into books values('C语言数据结构中文版','(美)李普曼 等著,陈硕评 注',50,0)
insert into books values('大话c语言中文版','(美)李普曼 等著,陈硕评 注',50,0)
insert into books values('C语言与设计模式中文版','(美)李普曼 等著,陈硕评 注',50,0)
insert into books values('C语言与数据库中文版','(美)李普曼 等著,陈硕评 注',50,0)

insert into books values('C# 中文版','(美)李普曼 等著,陈硕评 注',50,0)
insert into books values('深入浅出C# 中文版','(美)李普曼 等著,陈硕评 注',50,0)
insert into books values('C#控件大全 中文版','(美)李普曼 等著,陈硕评 注',50,0)
insert into books values('C#代码之路 中文版','(美)李普曼 等著,陈硕评 注',50,0)

insert into books values('css','(美)李普曼 等著,陈硕评 注',50,0)
insert into books values('css禅意花园 ','(美)李普曼 等著,陈硕评 注',50,0)
insert into books values('css星月神话 ','(美)李普曼 等著,陈硕评 注',50,0)
insert into books values('css学习方案','(美)李普曼 等著,陈硕评 注',50,0)

insert into books values('a','(美)李普曼 等著,陈硕评 注',50,0)
insert into books values('a禅意花园 ','(美)李普曼 等著,陈硕评 注',50,0)

-----------------------------------------------------------------------------




select * from books
select * from SearchKeyWords
insert into SearchKeyWords values('c++',0)
update SearchKeyWords set searchcount=searchcount+1 where keyword='c++'

select count(*) from SearchKeyWords where keyword = 'c++'

MyBookShop

select * from dbo.SearchKeyWords
select * from dbo.books
---搜查出点击率最高的10个书
select  top  10 * from  dbo.books where Title like '% %'  order by Clicks desc
select  top  10 * from  dbo.books where Title like '%c++%'  order by Clicks desc


第二步:用vs新建一个页面

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <script>
        //创建异步请求对象
        var xmlhttp;

        //创建异步请求的函数
        function createXmlHttpRequest()
        {
            //这个函数的作用是,如果当前的浏览器是不是IE或者火狐浏览器
            if (window.ActiveXObject) {
                //如果是,则新建一个IE的异步请求对象
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
            else {
                //否则,创建一个新的异步请求对象
                xml = new XMLHttpRequest();
            }
        }
        //建立文本框 键盘松开时的事件
        function myinput()
        {
            //创建异步请求对象
            createXmlHttpRequest();
            //当请求完成后,需要做的事情
            xmlhttp.onreadystatechange = mychange;
            //获得当前的文本框中的值
            var keyword = document.getElementById("txinput").value;

            //判断当前文本框中的值是否为空
            if (!is_blank(keyword)) {
                //这个三行代码的解析请看最下面
                xmlhttp.open("POST", "Handler.ashx?keyword=" + URLencode(trim(keyword)) + "", true);
                xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                xmlhttp.send();
            }
            else {
                //如果当期输入的为空,则清除所有的li
                myclear();
            }
           
        }
       

        function mychange()
        {
            //当异步传输成功时
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
            {
                //先清除上一次查询的东西
                myclear();
                //获得响应回来的xml
                var dom = xmlhttp.responseXML;
                //获得根节点
                var root = dom.documentElement;
                //获得根节点下面的子节点
                var childnode = root.childNodes;
                //循环加入
                for(var i=0;i<childnode.length;i++)
                {
                    //创建一个新的元素
                    var li = document.createElement("li");
                    //设置元素的值
                    li.innerText = childnode[i].text;
                    //往ul加入节点
                    myul.appendChild(li);
                }      
            }
        }

        //在url传输过程中,会屏蔽 加号 +  这样的字符,所以用正则表达式来对字符进行转换
        function URLencode(sStr) {
            return escape(sStr).replace(/\+/g, '%2B').replace(/\"/g, '%22').replace(/\'/g, '%27').replace(/\//g, '%2F');
        }

        //判断当期值是否为空
        function is_blank(str) {
            var reg = /^\s*$/;
            return reg.test(str);
        }

        //这里非常关键,让我搞了好久才成功
        //1.这里操作的是DOM,我每删除一次,在dom数中就会少一个节点,dom树的节点数目,动态减少。
        //2.所以这里不是一般的删除,每一次删除都删除第二个 下表为1
        //3.到后来,下标的数目会超出dom树的长度,所以每一次的删除都要减减 --
        function myclear() {
            var myul = document.getElementById("myul");
            var myli = myul.childNodes;
            for (var i = 0; i < myli.length; i++) {
                if (myli[1] != null) {
                    myul.removeChild(myli[1]);
                    i--;
                }
            }
        }

        //去掉字串左边的空格 
        function lTrim(str) {
            if (str.charAt(0) == " ") {
                //如果字串左边第一个字符为空格  

                str = str.slice(1); //将空格从字串中去掉 
                //这一句也可改成 str = str.substring(1, str.length); 
                str = lTrim(str); //递归调用 
            }
            return str;
        }

        //去掉字串右边的空格 
        function rTrim(str) {
            var iLength;

            iLength = str.length;
            if (str.charAt(iLength - 1) == " ") {
                //如果字串右边第一个字符为空格 
                str = str.slice(0, iLength - 1); //将空格从字串中去掉 
                //这一句也可改成 str = str.substring(0, iLength - 1); 
                str = rTrim(str); //递归调用 
            }
            return str;
        }

        //去掉字串两边的空格 
        function trim(str) {
            return lTrim(rTrim(str));
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        请输入您要查询的书籍:
        <input id="txinput" type="text" onkeyup ="myinput();" />
        <div id="mydiv">
            <ul id="myul" style="width:200px; background-color:pink; height:auto;">

            </ul>
        </div>
    </div>
    </form>
</body>
</html>

第三步:创建book的实体

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BookEntity
{
    public class Book
    {
        private int id;
        private string title;
        private string author;
        private decimal unitprice;
        private int clicks;

        public int Clicks
        {
            get { return clicks; }
            set { clicks = value; }
        }

        public decimal Unitprice
        {
            get { return unitprice; }
            set { unitprice = value; }
        }

        public string Author
        {
            get { return author; }
            set { author = value; }
        }

        public string Title
        {
            get { return title; }
            set { title = value; }
        }

        public int Id
        {
            get { return id; }
            set { id = value; }
        }
    }
}

第四步:创建一个类,用于查询在文本框中输入的值

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using BookEntity;
/// <summary>
/// BookManage 的摘要说明
/// </summary>
public class BookManage
{
	public BookManage()
	{
		//
		// TODO: 在此处添加构造函数逻辑
		//
	}
    public List<Book> QueryInstance(string keyword)
    {
        SqlConnection con = new SqlConnection("server=.;database=MyBookShop;uid=cgy;pwd=wass");
        string sql = "select  top  10 * from  dbo.books where Title like '%" + keyword + "%'  order by Clicks desc";
        SqlCommand cmd = new SqlCommand(sql, con);
        con.Open();
       SqlDataReader dr= cmd.ExecuteReader();
        List<Book> list = new List<Book>();
        while (dr.Read())
        {
            Book book = new Book();
            book.Id =Convert.ToInt32( dr["id"]);
            book.Title = dr["title"].ToString();
            book.Author = dr["author"].ToString();
            book.Unitprice = decimal.Parse(dr["unitprice"].ToString());
            book.Clicks = Convert.ToInt32(dr["clicks"].ToString());
            list.Add(book);
        }
        return list;
    }
}

第五步:新建一个handler.ashx

<%@ WebHandler Language="C#" Class="Handler" %>

using System;
using System.Web;
using BookEntity;
using System.Data;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.Xml;

public class Handler : IHttpHandler {
    
    public void ProcessRequest (HttpContext context) {
        //使用管理类来进行查询
        BookManage manage = new BookManage();
        //先要判断是否有值传过来
        if (context.Request.QueryString["keyword"] != null)
        {
            //获得值
            string keyword = context.Request.QueryString["keyword"];
            //新建一个书籍列表,获得数据
            List<Book> list = manage.QueryInstance(keyword);
            
            //以下为xml的操作
            //新建一个xml对象
            XmlDocument document = new XmlDocument();
            //新建根节点
            XmlElement root = document.CreateElement("Titles");   
            //循环       
            foreach (Book item in list)
            {
                //创建一个元素
                XmlElement title = document.CreateElement("title");
                //给元素赋值
                title.InnerText = item.Title;
                //把该元素加入到根节点中
                root.AppendChild(title);
            }
            //把根节点添加到dom中
            document.AppendChild(root);

            //设置返回时的数据类型, 格式为xml 编码为utf-8
            context.Response.ContentType = "text/xml;charset=utf-8";
            //响应输出
            context.Response.Write(document.InnerXml);
        }

    }
 
    public bool IsReusable {
        get {
            return false;
        }
    }

}


自此,AJAX 全部搞完,下面画一张图来说明一下执行顺序



最后:加入AJAX的部分解释

				 //以下为http.open的解析
                //创建一个新的http请求,并指定此请求的方法、URL以及验证信息  语法
               /* 语法
                oXMLHttpRequest.open(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword);

                参数

                bstrMethod
                http方法,例如:POST、GET、PUT及PROPFIND。大小写不敏感。

                bstrUrl
                请求的URL地址,可以为绝对地址也可以为相对地址。

                varAsync[可选]
                布尔型,指定此请求是否为异步方式,默认为true。如果为真,当状态改变时会调用onreadystatechange属性指定的回调函数。

                bstrUser[可选]
                如果服务器需要验证,此处指定用户名,如果未指定,当服务器需要验证时,会弹出验证窗口。

                bstrPassword[可选]
                验证信息中的密码部分,如果用户名为空,则此值将被忽略。
                */

               


                xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                //以下为   xmlhttp.setRequestHeader的解析
               /* 通常在HTTP协议里,客户端像服务器取得某个网页的时候,必须发送一个HTTP协议的头文件, 
                告诉服务器客户端要下载什么信息以及相关的参数.而 XMLHTTP 就是通过HTTP协议取得网站上
                的文件数据的,所以也要发送HTTP头给服务器。 
                但是 XMLHTTP 默认的情况下有些参数可能没有说明在HTTP头里,这是当我们需要修改或添加这
                些参数时就用到了setRequestHeader 方法。
                */
              

                xmlhttp.send();
                //以下为xmlhttp.send()的解析
                /*
                xmlhttp.send()方法
                send()                                                                                    
                发送请求到http服务器并接收回应                                                            
                                                                                          
                语法:                                                                                     
                oXMLHttpRequest.send(varBody);                                                            
                                                                                          
                参数:                                                                                     
                varBody                                                                                   
                欲通过此请求发送的数据。                                                                  
                                                                                          
                Example:                                                                                  
                xmlhttp = new ActiveXObject("Msxml2.XMLHTTP.3.0");                                        
                xmlhttp.open("GET", "http://localhost/sample.xml", false);                                
                xmlhttp.send();                                                                           
                alert(xmlhttp.responseXML.xml);                                                           
                                                                                          
                备注                                                                                      
                此方法的同步或异步方式取决于open()方法中的bAsync参数,                                    
                如果bAsync == False,此方法将会等待请求完成或者超时时才会返回,                           
                如果bAsync == True,此方法将立即返回。                                                    
                                                                                          
                                                                                          
                如果发送的数据为BSTR,则回应被编码为utf-8, 必须在适当位置设置一个包含charset的文档类型头。
                                                                                          
                如果发送的数据为XML DOM object,则回应将被编码为在xml文档中声明的编码,如果在xml文档中没有声明编码,则使用默认的UTF-8。
                */

最最后,附上运行时的具体效果

1.打开时的页面


2.输入一个 c  ,马上有个响应



3.再输入一个 s 变成 cs


4.删除一个s  重新变成 c


5.把c也删掉 文本框为空 



涉及技术:

1.ASP.NET
2.AJAX
3.Javascript
4.XML
5.XMLDOM
6.正则表达式
7.ADO.NET
8.SQL
9.HTML


总结:

这个效果还不是很完美,现在还只是显示了查询出来的东西在下一篇文章中,我会加入一下几个新功能:
1.动态的给DOM添加样式
2.动态添加事件
3.运用log4net,记录用户操作的时间
4.在数据库中,保存用户输入的关键字

以后的功能:
1.查询出书籍后,付费的时候,运用webservice 来调用付费业务
2.搞一个后台页面,书籍信息管理
3.错误处理,当请求没有的页面的时候,跳到指定的页面
4.用户权限管理,并不是每个人都可以进入到会员页面

暂时就写那么点好了,以后想到在写,如果当中有错误的地方,欢迎各位指正。


  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值