提示的实现(及Hack Google)

Anonymous 2010-04-03 08:18:39
在Google/百度的搜索输入框输入内容时, 只要你的网速够快, 那么你就会看到, 在输入内容的同时, 输入框下方会弹出一个提示框, 内有n条关联内容, 所谓关联, 就是你正在输入的内容的相关信息. 比如, 你输入"香港"二字后, 还未输入后继内容, 提示框就会自动弹出并包含诸如"香港旅游" "香港酒店"这些信息.

这些信息从何而来? 简单的说, 来自搜索服务商的数据库, 它首先拿取你正在输入的内容, 然后在自己的数据库内查找这些内容, 将其中人气最旺, 数量最多的那些记录返回给你, 这么做的理由是, 既然这些记录受到较多关注, 那么自然地也很可能受到你的关注, 因此推荐给你, 反之, 冷门的,相关记录数量少的, 就不会推荐给你.

假设你是一位站长, 为网站用户提供某一项服务, 其中, 需要用户输入某些内容, 而你就打算实现上述的自动提示功能, 即, 在用户在输入过程中提供相关的提示.

现在要做的, 就是如何实现这一个功能.

过程并不复杂, 四个部分:
检测用户当前输入的内容.
将用户输入的内容发送给服务商.
将服务商提供的数据返回给用户.
如果用户激活(比如点击或者按下回车键)其中某一条关联, 则将其作为用户的输入内容.

先说其中第二项: 如何向服务商发出内容 ? 我推荐Google Suggest, 它的使用很简单: 发出一个JavaScript调用请求, 如下:
<script type='text/javascript' src=...></script>
其中的src地址是:
http://www.google.com/complete/search?client=suggest&hl=zh-CN&js=true&qu=
请注意, 其中参数qu的值就是用户输入的内容.

因此, 动态地创建一个Script , 将当前用户输入的内容捆绑到上述网址, 这就可以了.

再来处理第三项, 如何将服务商返回的数据返回到用户? 显然, 处理包括了两部分:解析数据, 提交给用户. 这里只讲解解析数据.
Google Suggest 返回的是一个数组, 结构如下:
[
(数组第一项元素)<用户输入的内容>,
(数组第二项元素, 也是一个数组)[
[第一条关联结果的文本, 第一条关联结果的相关记录数, 序号],
[第二条关联结果...],
[...]
],
(数组第三项元素)<空白项>
]
显然, 只处理第二个元素就可以了.

这个数组元素, 也是一个数组, 它包含了n条关联结果, 而每一条关联结果, 也是一个数组, 晕...它包含3项, 第一项是这条关联结果的文本, 也就是用来显示给用户看的, 第二项, 是这条关联结果所对应的相关记录的数量.

以"香港"二字为例, 服务商返回的关联结果有10条, 整个数组就是这样:
[ "香港",
[ ["香港旅游", "123,000条结果", 0],
["香港酒店", "9,000条结果", 1],
...
],
]
具体解析代码就不给出了, 基本上就是分析数组、提数组元素的操作.

再来说第四项: 当用户点击其中一条关联时, 它就被复制到输入框, 成为用户的输入内容, 也就是做到一触即发, 一旦点击, 立即启动, 具体内容此处也不详述了.

最后, 来处理第一部分: 如何监测用户的输入? 网上很多教程都使用监测用户击键这种方式, 我认为有几点不妥:
第一, 对中文输入的支持不好. 动手测试一下就知道了, 在一个<input type='text'>里面, 分别输入中文和英文, 所触发的JavaScript事件是不同的, 更令人头痛的是, 不同的浏览器又有各自不同的事件响应, 十分麻烦.
第二, 如果没有击键动作的话, 比如, 用户从记事本复制一段文本, 然后粘贴到搜索输入框内, 再点击搜索按钮, 整个过程都没有击键动作, 这样就不会触发搜索关联了.
第三, 每打入一个字符就触发一次关联查询, 这会造成较大的系统负担, 事实并不需要一定如此, 为何不采用更轻巧的方式呢?

我使用的方式(据说也是Google 采用的方式, 但未经证实), 是通过定时器对输入框进行检查, 即大家都应该熟悉的 setTimeout .

一般而言, 大多数人的中文输入速度大约是 60字/分钟(这里不考虑诸如词组输入之类的便捷方式, 因为关键不在于输出多少个字, 而在于键入的速度), 因此, 可以将定时器的时间间隔设为稍大一点, 这样, 在保证监测效果的前提下, 不会对系统造成较大的负担.
更进一步地, 根据实际情况进行优化: 仅当用户在输入框内输入内容时才进行监测, 换言之, 如果用户不在输入框内输入内容, 那就关闭定时器, 这就更加减少了系统负担.

怎样判断用户正在输入内容呢? 很简单, 将输入框的onfocus事件(获得焦点事件)捆绑到指定的监视过程上, 同理, 将onblur(失去焦点事件)也捆绑到指定监视过程上, 这样就可以了! 道理很简单: 用户要在输入框内输入内容, 自然首先要将输入焦点转移到输入框(例如,用鼠标在输入框内点击一下), 这样, onfocus事件被激发, 被捆绑的监视过程也就被激活了, 而这个监视过程的任务就是启动定时器, 按照一定的时间间隔对输入框进行检查, 一旦发现有输入内容则立即向服务商发出一个关联查询请求, 同理, 当用户点击页面上其他元素, 例如, 点击某一条链接, 打开一份网页, 输入焦点也就从输入框转移走了, onblur事件也就被激发了, 捆绑的监视过程也就被激活了, 执行关闭定时器的操作.

不同的服务商, 所返回的应答是不同格式的, 即使是同一服务商, 比如Google, 它也不是一成不变的, 因此, 要注意检查应答内容.
现在, Google 返回的应答是一个类方法(Class Method)调用, 换言之, 如果当前页面没有加载这个类, 那就不能正确解析它所包含的数据了, 因此, Hack 也就派上用场了.
Google返回的script 内容:
window.google.ac.h([关联内容])

很简单, 在页面内创建一个google类, 再在该类内部创建一个ac类, 并为它添加一个名为h 的类方法就可以了, 即:
MyGoogleAC = function()
{ this.h = function(Content) { ... } }

MyGoogle = function()
{ this.ac = new MyGoogleAC; }

var google = new MyGoogle;

总结一下:
1. 做好接口, 也就是实现google类实例, 这样才可以正确地接收及处理 Google Suggest返回的数据,
2. 做好监视过程, 即输入框的onfocus事件响应过程和onblur事件响应过程. 监视的目的, 就是为了及时向Google Suggest发出当前用户输入的内容.
3. 做好用户选择响应过程, 即, 一旦用户选择某一条关联时, 应及时地作出相应的处理.

...全文
105 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
街头小贩 2010-04-04
  • 打赏
  • 举报
回复
不错!学习一下
Anonymous 2010-04-03
  • 打赏
  • 举报
回复
Hack的核心, 就在于动态添加类成员. 如下:
MyClass = function()
{
this.Name;
this.Init = function(TheName){ this.Name = TheName; }
this.Show = function(){ alert(this.Name); }
}

这个类很简单, 一目了然, 只包含一个类属性和两个类方法.

由于Javascript允许动态添加类成员, 这就为Hack提供了途径, 如下:
... // (MyClass类的定义代码)
var AClass = new MyClass;

if (typeof(AClass.Hacker) != "object") AClass.Hacker=new HackClass;
AClass.Hacker.Haha();
...

HackClass = function()
{
this.Haha = function(){ alert("Haha! I Hack!"); }
...
}

本站就是按上述模式实现了搜索文本提示功能, 欢迎浏览
http://Openpry.com

2,100

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧