喜悦国际村 
» 游客:  注册 | 登录 | 搜索 | 统计 | 帮助

RSS 订阅当前论坛  

喜悦证交所已经关闭

上一主题 下一主题
     
标题: [原创] 简单剖析google的首页自动完成功能  
 
sunceenjoy
中级会员
Rank: 3Rank: 3
初级会员


UID 68584
精华 0
积分 262
帖子 249
金钱 262 喜悦币
威望 0
人脉 0
阅读权限 30
注册 2006-2-13
状态 离线
[广告]: q m
简单剖析google的首页自动完成功能

发现google的首页突然多出了可以自动完成的功能,今天闲着,边看了下代码,
发现该功能主要由这个js来完成该功能。http://www.google.cn/ac.js
搞不懂google为什么非要把个js代码写的那么难看。

大体分为以下几步
1)  InstallAC(document.f,document.f.q,document.f.btnG,"search","zh-CN")  // 在首页末尾,初始化
2) 当keypress后触发含有 httprequest的函数 hb(),发送请求。
数据来源地址:http://www.google.cn/complete/se ... js=true&qu=love
注意了,最后一个参数就是我们输入的查询内容,如果中文要进行编码(encodeURIComponent/escape  见首页)
获取的内容如下:
sendRPCDone(frameElement, "love", new Array("love story", "love21cn", "loveinhere", "love actually", "love poem", "loveless", "love love love", "love letter", "love21cn.com", "love21"), new Array("350,000,000 结果", "357,000 结果", "64,900 结果", "146,000,000 结果", "18,300,000 结果", "5,580,000 结果", "907,000,000 结果", "98,200,000 结果", "178,000 结果", "177,000 结果"), new Array(""));

是不是发觉有点跟自动完成的东西有点类似了呀。呵呵,ac.js里面正好有个sendRPCDone函数,难怪google直接把返回的东西eval了一下。if(b.charAt(0)!="<"&&b.indexOf("sendRPCDone")!=-1)   eval(b); // b当然就是responseText了
3) 之后就是如何把这些数据显示在一个div里面了。代码如下,意思是先把里面的子项删除,再添加新的子项
function Sa(a,b,c){while(a.childNodes.length>0)a.removeChild(a.childNodes[0]);
for(var e=0;
e<b.length;
++e){var f=document.createElement("DIV");
q(f,"aAutoComplete");
f.onmousedown=$a;
f.onmousemove=ab;
f.onmouseout=bb;
var i=document.createElement("SPAN");
q(i,"lAutoComplete");
if(J.substring(0,2)=="zh")i.style.height=d.offsetHeight-
4;
else i.style.height=d.offsetHeight-6;
var h=document.createElement("SPAN");
h.innerHTML=b[e];
var l=document.createElement("SPAN");
q(l,"dAutoComplete");
q(h,"cAutoComplete");
f.displaySpan=l;
if(!ha)l.innerHTML=c[e];
i.appendChild(h);
i.appendChild(l);
f.appendChild(i);
a.appendChild(f)}}

//其中这个形参 a 是div对象

下面列出一写相关的js函数
function Xa(){if(Ca()){L=true}else{L=false}if(Ta)B="complete";
else B="/complete/"+Ia;
la=B+"?hl="+J+"&client=suggest";
if(!L){na("qu","",0,B,null,null)}D.onsubmit=fa;
d.autocomplete="off";
d.onblur=Za;
d.onfocus=db;
if(d.createTextRange)d.onkeyup=new Function("return okuh(event);
");
else d.onkeyup=okuh;
d.onsubmit=fa;
k=d.value;
ka=k;
g=document.createElement("DIV");
g.id="completeDiv";
Q=1;
ca=1;
g.style.borderRight="black "+Q+"px solid";
g.style.borderLeft="black "+Q+"px solid";
g.style.borderTop="black "+ca+"px solid";

g.style.borderBottom="black "+ca+"px solid";
g.style.zIndex="2";
g.style.paddingRight="0";
g.style.paddingLeft="0";
g.style.paddingTop="0";
g.style.paddingBottom="0";
g.style.visibility="hidden";
g.style.position="absolute";
g.style.backgroundColor="white";
m=document.createElement("IFRAME");
m.id="completeIFrame";
m.style.zIndex="1";
m.style.position="absolute";
if(window.opera&&(!window.opera.version||window.opera.version()<="8.54"))m.style.display="none";
else m.style.display="block";
m.style.visibility="hidden";

m.style.borderRightWidth="0";
m.style.borderLeftWidth="0";
m.style.borderTopWidth="0";
m.style.borderBottomWidth="0";
Y();
document.body.appendChild(g);
document.body.appendChild(m);
ta("",[],[]);
Wa(g);
var a=document.createElement("DIV");
a.style.visibility="hidden";
a.style.position="absolute";
a.style.left="-10000";
a.style.top="-10000";
a.style.width="0";
a.style.height="0";
var b=document.createElement("IFRAME");
b.completeDiv=g;
b.name="completionFrame";
b.id="completionFrame";
b.src=la;
a.appendChild(b);
document.body.appendChild(a);

if(frames&&frames["completionFrame"]&&frames["completionFrame"].frameElement)G=frames["completionFrame"].frameElement;
else G=document.getElementById("completionFrame");
if(w=="url"){Ka();
Y()}window.onresize=eb;
document.onkeydown=cb;
gb();
if(W){setTimeout("idkc()",10);
if(d.attachEvent){d.attachEvent("onpropertychange",Ua)}}p=document.createElement("INPUT");
p.type="hidden";
p.name="aq";
p.value=null;
p.disabled=true;
D.appendChild(p);
s=document.createElement("INPUT");
s.type="hidden";
s.name="oq";
s.value=null;

s.disabled=true;
D.appendChild(s)}
-------------------------------------
function hb(a){
        if(r&&r.readyState!=0){r.abort()}
        r        = Ca();//取httprequest对象
        if(r){
                r.open("GET",la+"&js=true&qu="+a,true);
        r.onreadystatechange=function(){
                if(r.readyState==4&&r.responseText){
                        switch(r.status){
                                case 403:E=1000;        break;
                                case 500:
                                case 502:
                                case 503:E++;       break;
                                case 200:var b=r.responseText;
                                if(b.charAt(0)!="<"&&b.indexOf("sendRPCDone")!=-1)
                                        eval(b);
                                else A--;
                                default:E=0;                break
                        }
                }
        };
                r.send(null)
        }
}
------------------------------
//替换查询内容
function Sa(a,b,c){while(a.childNodes.length>0)a.removeChild(a.childNodes[0]);
for(var e=0;
e<b.length;
++e){var f=document.createElement("DIV");
q(f,"aAutoComplete");
f.onmousedown=$a;
f.onmousemove=ab;
f.onmouseout=bb;
var i=document.createElement("SPAN");
q(i,"lAutoComplete");
if(J.substring(0,2)=="zh")i.style.height=d.offsetHeight-
4;
else i.style.height=d.offsetHeight-6;
var h=document.createElement("SPAN");
h.innerHTML=b[e];
var l=document.createElement("SPAN");
q(l,"dAutoComplete");
q(h,"cAutoComplete");
f.displaySpan=l;
if(!ha)l.innerHTML=c[e];
i.appendChild(h);
i.appendChild(l);
f.appendChild(i);
a.appendChild(f)}}

大体就是这样,有好多地方我也没有去仔细看,初始化的时候会创建一个iframe,先执行个一下
sendRPCDone(frameElement, "", new Array(), new Array(), new Array(""));
这跟http://www.google.cn/complete/se ... amp;js=true&qu=返回的结果如出一辙,另外还创建了好几个iframe,div等等,很有很多细节呢,有空大家去看看吧。
2007-1-24 05:42 PM#1
查看资料  Blog  发短消息  顶部
 
fcicq
新手上路
Rank: 1
初级会员



UID 24467
精华 0
积分 21
帖子 587
金钱 20 喜悦币
威望 0
人脉 1
阅读权限 10
注册 2003-11-8
来自 fcicq.net
状态 离线
[推荐阅读] 请教mysql两个表union查询怎么排出重复?
google内部的代码写的应该是很好的,但是就因为有了压缩器...




2007-1-24 07:58 PM#2
查看资料  访问主页  Blog  发短消息  顶部
 
奶瓶 (NP博士)
版主
Rank: 7Rank: 7Rank: 7
老仙


UID 52707
精华 4
积分 27777
帖子 6463
金钱 27727 喜悦币
威望 50
人脉 0
阅读权限 100
注册 2004-11-22
来自 北大中文系
状态 离线
[推荐阅读] 请教数据库的问题!
Suggest
这个最早是在英文站上做测试的





图片包子,注册送100包子!
域名抢注
2007-1-24 09:23 PM#3
查看资料  访问主页  Blog  发短消息  QQ  ICQ 状态  Yahoo!  顶部
     


  可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题 | 开通个人空间  


 




Powered by Discuz! 6.1.0  © 2001-2010 Comsenz Inc.
Processed in 0.029358 second(s), 6 queries

(冀ICP备05009913号) 管理员:sadly 邮箱/MSN: sadly@phpx.com QQ:824008(长隐) 清除 Cookies - - Archiver - WAP