当前位置: 首页 > news >正文

Google Suggest .net 实现

 

Google Suggest Autcomplete 的实现

前台:

HTML

Default.aspx

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

 

<!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>

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

<title>Using Google Search</title>

<script type="text/JavaScript" src="fun.js">

</script>

</head>

<body>

<h1>Google Suggest</h1>

<input type="text" id="tb_kw" name="textField" onkeyup="connectGoogleSuggest()" style="width: 270px"/>

 <div id="targetDiv" style="position:absolute;border:solid 1px black; z-index:20000; background-color:White; display:none;"></div>

</body>

</html>

func.js:

function $(i) { return document.getElementById(i);}

function getPosition(ele){

    var overflown = [];

    var el = ele, left = 0, top = 0;

    do {

       left += el.offsetLeft || 0;

       top += el.offsetTop || 0;

       el = el.offsetParent;

    } while (el);

    return {'x': left, 'y': top};

}

function connectGoogleSuggest() {

    var input = $("tb_kw");

    var h=$("targetDiv");

    //h._i=-1000;

    if (!input.value||!input.value.length||event.keyCode=='27')

    {

        h.style.display="none";

        return;

    }

    if (event.keyCode=='38' || event.keyCode=='40')

    {

       // alert(h.style.display);

        if (h.style.display=="none")

        {

            return;

        }

        if (event.keyCode=='38')

        {

        //alert(event.keyCode);

            if (h._i==-1)

            {

                h._i=h.firstChild.rows.length-1;

            }

            else

            {

                h._i--;

            }

        }

        else

        {

        //alert(h._i);

           h._i++;

        }

        for(var i=0; i<h.firstChild.rows.length; i++)

        {

            h.firstChild.rows[i].style.backgroundColor="#FFFFFF";

        }

        if(h._i >= 0 && h._i < h.firstChild.rows.length)

            with(h.firstChild.rows[h._i])

            {

                style.backgroundColor="#D0ECF9";

                input.value=cells[0].innerText;

            }

        else

        {

            input.value=h._kw;

            h._i=-1;

        }

    }

   else if(input.value!="") {

        h._i=-1;

        h._kw=input.value;

        getData("google.aspx?qu="+input.value);

        var pos=getPosition($("tb_kw"));

        with(h.style)

        {

          left=pos.x;

          top=pos.y+$("tb_kw").offsetHeight;

          width=$("tb_kw").offsetWidth-4;

          display="block";

        }

    }

    else {

        $("targetDiv").innerHTML= "";

    }

}

function getData(source){

    var xmlHttp = false;

    if (window.XMLHttpRequest)

        xmlHttp = new XMLHttpRequest();

    else if (window.ActiveXObject)

        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

    if (xmlHttp){

        xmlHttp.open("GET",source);

        xmlHttp.onreadystatechange=function(){

            if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {

                var message=xmlHttp.responseText;

                var callBack = message.substring("window.google.ac.".length, message.length);

                eval(callBack);

            }

        }

        xmlHttp.send(null);

    }

}

function Suggest_apply(unusedVariable, searchWord, results,unusedArray){

    if(!results || results.length<3)

        return;

    var ihtml="";

    for(var j=1;j<results.length;j+=2)

        ihtml+='<tr style="cursor:hand" οnmοuseοver="MouseOver(this);$(\'tb_kw\').value=\'' +results[j] +'\';" οnmοuseοut="MouseOut(this);" οnclick="ResultOnClick();"><td style="color:#000" align="left">' +results[j] +'</td><td style="color:#090" align="right">' +results[j+1] +'</td></tr>';

     $("targetDiv").innerHTML="<table width='100%' border='0' cellpadding='0' cellspacing='0' style='font-size:12px;'>"+ihtml+"</table>";

     $("targetDiv").style.display="block";

}

function MouseOver(Tr){

    Tr.bgColor="#D0ECF9";

    Tr.childNodes[0].style.color="#00cc00";

    Tr.childNodes[1].style.color="#00cc00";

}

function MouseOut(Tr){

    Tr.bgColor="";

    Tr.childNodes[0].style.color="#000000";

    Tr.childNodes[1].style.color="#009900";

}

function ResultOnClick()

{

    $("targetDiv").style.display="none";

}

后台:

google.aspx

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

记住:一定要只保留这一句话,其他的就去掉

google.aspx.cs

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;

using System.Text;

using System.IO;

using System.Net;

 

public partial class google : System.Web.UI.Page

{

    protected void Page_Load(object sender, EventArgs e)

    {

        string ret = GetPageHtml("http://www.google.cn/complete/search?hl=zh-CN&client=suggest&js=true&qu=" + Request.QueryString["qu"]);

        Response.Write(ret);

    }

    protected string GetPageHtml(string url)

    {

        string pageinfo;

        try

        {

            WebRequest myreq = WebRequest.Create(url);

            WebResponse myrep = myreq.GetResponse();

            StreamReader reader = new StreamReader(myrep.GetResponseStream(), Encoding.GetEncoding("UTF-8"));

            pageinfo = reader.ReadToEnd();

        }

        catch

        {

            pageinfo = "";

        }

        return pageinfo;

    }

}

上面把代码全部贴出来了,下面我就简单讲解一下。

我们用的是Google SuggestAPI,即这个页面

http://www.google.cn/complete/search?hl=zh-CN&client=suggest&js=true&qu=" + Request.QueryString["qu"])

这里我们将我们的搜索词作为QueryString传了过去,在google.aspx.cs页面进行分析

如下:

string ret = GetPageHtml("http://www.google.cn/complete/search?hl=zh-CN&client=suggest&js=true&qu=" + Request.QueryString["qu"]);

        Response.Write(ret);

GetPageHtml()方法源码如下:

protected string GetPageHtml(string url)

    {

        string pageinfo;

        try

        {

            WebRequest myreq = WebRequest.Create(url);

            WebResponse myrep = myreq.GetResponse();

            StreamReader reader = new StreamReader(myrep.GetResponseStream(), Encoding.GetEncoding("UTF-8"));

            pageinfo = reader.ReadToEnd();

        }

        catch

        {

            pageinfo = "";

        }

        return pageinfo;

    }

}

GetPageHtml()的主要功能就是获得请求的web页的内容。

Ret就是我们要的结果,就是我们回调函数的返回结果,返回一个数组,比如搜索词为AJAX,则有

window.google.ac.Suggest_apply(frameElement, "AJAX", new Array(2 , "ajax技术", "2,400,000 结果" , "ajax基础教程", "444,000 结果" , "ajax 框架", "860,000 结果" , "ajax教程", "1,210,000 结果" , "ajaxcontroltoolkit", "297,000 结果" , "ajaxpro", "89,200 结果" , "ajax .net", "2,060,000 结果" , "ajax中国", "2,550,000 结果" , "ajax 实例", "884,000 结果" , "ajax post", "18,700,000 结果" ), new Array(""));

所以我们得出结论:回调函数是window.google.ac.Suggest_apply(a, b, c, d), c就是我们要的结果,所以我们在回调函数中只需要使用c这个数组就得了。

另外就是AJAX的套路,xmlHttp请求,这里我们用一个函数function getData(source)实现

function getData(source){

    var xmlHttp = false;

    if (window.XMLHttpRequest)

        xmlHttp = new XMLHttpRequest();

    else if (window.ActiveXObject)

        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

    if (xmlHttp){

        xmlHttp.open("GET",source);

        xmlHttp.onreadystatechange=function(){

            if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {

                var message=xmlHttp.responseText;

                var callBack = message.substring("window.google.ac.".length, message.length);

                eval(callBack);

            }

        }

        xmlHttp.send(null);

    }

}

为什么我们要在google.aspx.cs中进行处理呢?原因是这样的,大多数的浏览器都不支持跨域的JS访问,从而我们要从后台进行处理后再请求,就不是跨域访问了。

接下来解决的问题是我们的autocomplete的结果接收的DIV的位置了,位置可以这样实现:

function getPosition(ele){

    var overflown = [];

    var el = ele, left = 0, top = 0;

    do {

       left += el.offsetLeft || 0;

       top += el.offsetTop || 0;

       el = el.offsetParent;

    } while (el);

    return {'x': left, 'y': top};

}

参数ele代表的是文本框,所以文本框在哪里,结果接收DIV就相应的在该在的地方出现,以下为效果图:

 

接下来是实现回调函数

function Suggest_apply(unusedVariable, searchWord, results,unusedArray){

    if(!results || results.length<3)

        return;

    var ihtml="";

    for(var j=1;j<results.length;j+=2)

        ihtml+='<tr style="cursor:hand" οnmοuseοver="MouseOver(this);$(\'tb_kw\').value=\'' +results[j] +'\';" οnmοuseοut="MouseOut(this);" οnclick="ResultOnClick();"><td style="color:#000" align="left">' +results[j] +'</td><td style="color:#090" align="right">' +results[j+1] +'</td></tr>';

     $("targetDiv").innerHTML="<table width='100%' border='0' cellpadding='0' cellspacing='0' style='font-size:12px;'>"+ihtml+"</table>";

     $("targetDiv").style.display="block";

}

$(i)是函数function $(i) { return document.getElementById(i);}

主要是为了节省codes。我们实际上是生成了一个<table></table>,里面就是我回调的结果,我们把鼠标时间一通加在了拼接的字符串里面,就是鼠标放到某一个结果上之后,字体颜色改变,背景色改变,然后该项的关键字成为搜索框里面的内容。

一下就是鼠标触发事件函数

function MouseOver(Tr){

    Tr.bgColor="#D0ECF9";

    Tr.childNodes[0].style.color="#00cc00";

    Tr.childNodes[1].style.color="#00cc00";

}

function MouseOut(Tr){

    Tr.bgColor="";

    Tr.childNodes[0].style.color="#000000";

    Tr.childNodes[1].style.color="#009900";

}

function ResultOnClick()

{

    $("targetDiv").style.display="none";

}

有鼠标移到结果上,鼠标移开,鼠标点击等。

 

接下来就是事件函数的主体及其键盘操作

function connectGoogleSuggest() {

    var input = $("tb_kw");

    var h=$("targetDiv");

    //h._i=-1000;

    if (!input.value||!input.value.length||event.keyCode=='27')

    {

        h.style.display="none";

        return;

    }

    if (event.keyCode=='38' || event.keyCode=='40')

    {

       // alert(h.style.display);

        if (h.style.display=="none")

        {

            return;

        }

        if (event.keyCode=='38')

        {

        //alert(event.keyCode);

            if (h._i==-1)

            {

                h._i=h.firstChild.rows.length-1;

            }

            else

            {

                h._i--;

            }

        }

        else

        {

        //alert(h._i);

           h._i++;

        }

        for(var i=0; i<h.firstChild.rows.length; i++)

        {

            h.firstChild.rows[i].style.backgroundColor="#FFFFFF";

        }

        if(h._i >= 0 && h._i < h.firstChild.rows.length)

            with(h.firstChild.rows[h._i])

            {

                style.backgroundColor="#D0ECF9";

                input.value=cells[0].innerText;

            }

        else

        {

            input.value=h._kw;

            h._i=-1;

        }

    }

   else if(input.value!="") {

        h._i=-1;

        h._kw=input.value;

        getData("google.aspx?qu="+input.value);

        var pos=getPosition($("tb_kw"));

        with(h.style)

        {

          left=pos.x;

          top=pos.y+$("tb_kw").offsetHeight;

          width=$("tb_kw").offsetWidth-4;

          display="block";

        }

    }

    else {

        $("targetDiv").innerHTML= "";

    }

}

记住,js很宽松,当你给一个对象随便赋值一个属性时,该属性就是该对象的属性了,比如本来objA没有pro1属性,但是当执行运算objA.pro1后,pro1就是它的属性了。基于上述观点,我们有里面的h._i出现,不然一般人还看半天还摸不着头。

主要处理了上下键的操作和控制接收结果的DIVtargetDiv”的某一些样式。然后把这个主要事件函数作为输入框的onkeyup触发事件,当每发生一次按键事件时,便执行一次。实现了实时改变结果的功能。

一个地道的Google Suggest就做好了,大家鼓掌!

                 马劲 lkmmmj@gmail.com 2008-11-30 于华中科技大学东七楼607

转载于:https://www.cnblogs.com/lkmmmj/archive/2008/11/30/1344089.html

相关文章:

  • 一个比赛的题目,大家出出主意看,我请他吃饭
  • 请高手帮助,网站被黑了,数据库中出现kill_kk表.不知道怎么解决!
  • 用 MapFileAndCheckSum 函数检测 exe 或 dll 是否被修改 - 回复 Joe Lo 的问题
  • 执行sql函数
  • 调试分布式 Web 应用程序
  • flex gumbo实例:重复填充BitmapGraphic对象
  • 一些Javascript的IE和Firefox(火狐)兼容性的问题总结及常用例子
  • 浅谈数据库设计技巧(上)技巧设计数据库类别商品允许数据类型
  • Pku1163
  • 不做作坊人——《走出软件作坊》书评
  • C++ Exercises(十七)---网际校验和算法
  • 《Asp.Net 2.0 揭秘》读书笔记(十七)
  • 简单说说FreeBSD的软件管理[转]
  • IE 和 firefox js 兼容问题
  • 产品与产品经理【人人都是产品经理:9003】
  • JavaScript-如何实现克隆(clone)函数
  • 【5+】跨webview多页面 触发事件(二)
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • JavaScript 奇技淫巧
  • Laravel Telescope:优雅的应用调试工具
  • quasar-framework cnodejs社区
  • RedisSerializer之JdkSerializationRedisSerializer分析
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • Unix命令
  • vue+element后台管理系统,从后端获取路由表,并正常渲染
  • Web设计流程优化:网页效果图设计新思路
  • yii2权限控制rbac之rule详细讲解
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 互联网大裁员:Java程序员失工作,焉知不能进ali?
  • 前端面试题总结
  • 巧用 TypeScript (一)
  • 如何抓住下一波零售风口?看RPA玩转零售自动化
  • 线性表及其算法(java实现)
  • 用Python写一份独特的元宵节祝福
  • ​水经微图Web1.5.0版即将上线
  • %3cli%3e连接html页面,html+canvas实现屏幕截取
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (day 12)JavaScript学习笔记(数组3)
  • (HAL)STM32F103C6T8——软件模拟I2C驱动0.96寸OLED屏幕
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (二)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (九)信息融合方式简介
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (没学懂,待填坑)【动态规划】数位动态规划
  • (一)基于IDEA的JAVA基础12
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • ./configure,make,make install的作用(转)
  • .net core Swagger 过滤部分Api
  • .NET/C# 使窗口永不获得焦点
  • .net使用excel的cells对象没有value方法——学习.net的Excel工作表问题
  • .Net组件程序设计之线程、并发管理(一)
  • /etc/motd and /etc/issue