简单剖析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等等,很有很多细节呢,有空大家去看看吧。

此文章由 www.phpgz.com 收集整理 ,地址为: http://www.phpgz.com/htmls/29977.html

大屏阅读,大屏评论.