当前位置: 首页 > 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】
  • 【RocksDB】TransactionDB源码分析
  • 【从零开始安装kubernetes-1.7.3】2.flannel、docker以及Harbor的配置以及作用
  • Akka系列(七):Actor持久化之Akka persistence
  • Android单元测试 - 几个重要问题
  • Angular数据绑定机制
  • CEF与代理
  • CentOS 7 防火墙操作
  • flask接收请求并推入栈
  • Java知识点总结(JavaIO-打印流)
  • JS+CSS实现数字滚动
  • Laravel 中的一个后期静态绑定
  • MySQL Access denied for user 'root'@'localhost' 解决方法
  • node-glob通配符
  • Rancher如何对接Ceph-RBD块存储
  • Selenium实战教程系列(二)---元素定位
  • Vue2.0 实现互斥
  • 百度小程序遇到的问题
  • 高程读书笔记 第六章 面向对象程序设计
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 简单实现一个textarea自适应高度
  • MyCAT水平分库
  • 翻译 | The Principles of OOD 面向对象设计原则
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • ​如何在iOS手机上查看应用日志
  • # 数论-逆元
  • (10)ATF MMU转换表
  • (NSDate) 时间 (time )比较
  • (PHP)设置修改 Apache 文件根目录 (Document Root)(转帖)
  • (Pytorch框架)神经网络输出维度调试,做出我们自己的网络来!!(详细教程~)
  • (ros//EnvironmentVariables)ros环境变量
  • (二)PySpark3:SparkSQL编程
  • (篇九)MySQL常用内置函数
  • (三)elasticsearch 源码之启动流程分析
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (转) ns2/nam与nam实现相关的文件
  • .NET Core 2.1路线图
  • .net 前台table如何加一列下拉框_如何用Word编辑参考文献
  • .NET 使用配置文件
  • .net2005怎么读string形的xml,不是xml文件。
  • .NET3.5下用Lambda简化跨线程访问窗体控件,避免繁复的delegate,Invoke(转)