zoukankan      html  css  js  c++  java
  • 一个网站的诞生 MagicDict开发总结5 [检索候补列表的生成]

    一边输入检索词语的同时,一边能够在网页的下拉列表中显示候补词语,作为一个日语单词检索网站,这个是必须的。

    至于使用什么技术,Ajax以外似乎没有其他选择了。以前是手工写Ajax的代码的,现在有Jquery了,我也随大流了,用JQuery写Ajax。。。
    //检索建议词语
    function GetSug(ReadyToSearch) {
        
    if (ReadyToSearch == searchKey) {
            $.get(
    "ASHX/GetWordList.ashx",
                     { SearchKey: searchKey },
                      
    function(data) {
                          
    if (!(data.toString()=="" | data.toString()== "[object XMLDocument]")) {
                              
    //列表框表示
                              document.getElementById("jp_wordlist").innerHTML = data;
                              document.getElementById(
    "jp_wordlist").style.display = "block";
                              _wListInited 
    = true;
                          } 
    else {
                              document.getElementById(
    "jp_wordlist").style.display = "none";
                              _wListInited 
    = false;
                          }
                      }
                    );

        }
    }

     这段代码非常简单,其核心就是一个Jquery的$.get传入现在用户已经输入完成的词语。然后交给后台去检索出可以使用的候补词语(其结果是一个HTML的TABLE),如果有结果的话,将结果表示出来。

    原理就这么简单了,但是,3个问题是必须要注意的

    1.检索效率问题。

       用户在不停的输入内容,是不是客户端输入任何东西都要第一时间去访问服务器端,获取候补词语呢? 当然不是咯,首先,你的服务器承受不了这样的检索操作,一般用户的打字速度,1秒里面打4,5个字母是完全没有问题的,单用户1秒钟做4-5次检索,这个不是一件有趣的事情。再者,没有必要,候补列表只是辅助作用的,一般在用户记忆比较模糊的时候,才会从列表里面来选择检索关键字。

        综上所述,我的策略是,当用户没有任何输入动作2-3秒后,才去做Ajax的检索操作。【其实,一般考虑都是这样的】

    2.列表中关键字的选取方法。

        列表中关键字的选取方法,牵涉到用户体验的问题。我的解决方案是鼠标和键盘同时能选择关键字。用户可以使用键盘的箭头符号来定位候补词语,用回车来选取关键词语。同时也支持鼠标来选择关键词语。

    这些功能可以需要很多JS的代码,但是对于一个认真制作,用心为用户着想的负责任的网站来说,是不能马虎的。

    下面从网站的JS里面截取了一些相关的代码的片段,第一次写JS,可能不是写得很好,请大家多多帮忙指教。

    //是否建议词语列表生成了
    var _wListInited = false;
    //建议词语列表的选中项目
    var ItemSelected = -1;
    //检索建议词
    var searchKey;
    //上次的检索词
    var PreSearchKey = "";
    var InputText = "输入日文汉字,假名,罗马字,中文,或者拼音";
    //onChange:检索词文本框的KeyUp事件
    function onChange(aevent) {
        searchKey 
    = document.getElementById("ctl00_txtSearchWord").value;
        
    if (searchKey == "") {
            document.getElementById(
    "jp_wordlist").style.display = "none";
            _wListInited 
    = false;
            ItemSelected 
    = -1;
            
    return false;
        }
        
    if (navigator.userAgent.indexOf('Opera'> -1 && aevent.keyCode == 13) {
            
    //Write Something Here
            //Opera浏览器
        }
        
    if (!aevent) {
            
    //IE,FF浏览器对应
            aevent = window.event;
        }
        
    if (aevent.keyCode == 13 && ItemSelected != -1) {
            document.getElementById(
    "sug_item_" + ItemSelected).onclick();
            
    return false;
        }
        
    if (aevent.keyCode != 40 && aevent.keyCode != 38) {
            
    //上下箭头以外,1500ms之内没有操作,则调用AJAX
            document.getElementById("jp_wordlist").style.display = "none";
            _wListInited 
    = false;
            ItemSelected 
    = -1;
            
    if (searchKey != PreSearchKey) {
                PreSearchKey 
    = searchKey;
                setTimeout(
    "GetSug('" + searchKey + "')"1500);
            }

        }
        
    if (aevent.keyCode == 40 && _wListInited) {
            
    //向下箭头    
            if (document.getElementById("sug_item_" + (ItemSelected + 1)) != null) {
                
    //还有下一个项目时候
                if (ItemSelected != -1) {
                    document.getElementById(
    "sug_item_" + ItemSelected).className = "itemNormal";
                }
                ItemSelected 
    += 1;
                document.getElementById(
    "sug_item_" + ItemSelected).className = "itemHighlight";
            }
        }
        
    if (aevent.keyCode == 38 && _wListInited) {
            
    //向上箭头
            if (ItemSelected != -1) {
                document.getElementById(
    "sug_item_" + ItemSelected).className = "itemNormal";
                ItemSelected 
    -= 1;
            }
            
    if (ItemSelected != -1) {
                document.getElementById(
    "sug_item_" + ItemSelected).className = "itemHighlight";
            }
        }

    }
    //检索建议词语
    function GetSug(ReadyToSearch) {
        
    if (ReadyToSearch == searchKey) {
            $.get(
    "ASHX/GetWordList.ashx",
                     { SearchKey: searchKey },
                      
    function(data) {
                          
    if (!(data.toString()=="" | data.toString()== "[object XMLDocument]")) {
                              
    //列表框表示
                              document.getElementById("jp_wordlist").innerHTML = data;
                              document.getElementById(
    "jp_wordlist").style.display = "block";
                              _wListInited 
    = true;
                          } 
    else {
                              document.getElementById(
    "jp_wordlist").style.display = "none";
                              _wListInited 
    = false;
                          }
                      }
                    );

        }
    }

     3.关于那个候选词语列表,怎么才能完美的出现在文本框的正下方,这个有的时候也是一个很头痛的问题。

        特别是当今各种浏览器混乱的局面下,相同的HTML在不同浏览器中的表现各不相同,IE下面完美的出现在文本框下面的列表框,FF下面可能位置就不对了,有偏差了。这个问题的解决因人而异的,我也是调试了很久很久才搞定的(HTML比较菜)。

    以上只是前台的代码的一些片段,如果想要完整的代码,直接到网站上看源代码和JS文件吧。。。。

    既然前台的代码介绍了,最后就介绍一下后台的代码吧:

    第一次使用ASHX这种代码,据说这个是专门用来做简单文字交互的。(有高手来说明一下这种代码吗,ASPX很菜)

    <%@ WebHandler Language="C#" Class="GetWordList" %>

    using System;
    using System.Web;
    public class GetWordList : IHttpHandler {
        
        
    public void ProcessRequest (HttpContext context) {
            context.Response.ContentType 
    = "text/plain";
            
    if (context.Request["SearchKey"!= null)
            {
                String SearchKey;
                SearchKey 
    = context.Request["SearchKey"];
                
    if (SearchKey == string.Empty) {
                    
    return;           
                }
                
    if (!((SearchKey.IndexOf("%"> -1 | SearchKey.IndexOf("?"> -1))) {
                    SearchKey 
    = clsJpHelper.ConvertRomaToKana(SearchKey);
                    System.Diagnostics.Debug.WriteLine(
    "T=" + context.Request["SearchKey"]);
                    context.Response.Write(Core.GetWordListHTMLByMainIndex((SearchKey)));
                }
            }
            context.Response.End();
        }
     
        
    public bool IsReusable {
            
    get {
                
    return false;
            }
        }

    }

            这样的代码估计人人都会写,这个文件就作为前台和后台的一个联络人了,由这个文件从后台检索数据,交还给前台。没有什么奇技淫巧。。。

    总结一下:

         1.网站用户体验是最重要的,有些功能用户使用不使用是一回事情,尽可能给用户多提供一些辅助功能是王道。同质化的网站竞争中,一个小细节决定成败。

         2.技术尽量用简单的成熟的。不需要黑客才能写出来的代码。简单,简约,强壮就可以了。

    有兴趣的写信给我 root#magicdict.com   [convert # to @ ]

    或者加MSN mynightelfplayer@hotmail.com

    网站地址 http://www.magicdict.com/


  • 相关阅读:
    二分+RMQ/双端队列/尺取法 HDOJ 5289 Assignment
    思维题 HDOJ 5288 OO’s Sequence
    树形DP Codeforces Round #135 (Div. 2) D. Choosing Capital for Treeland
    最大流增广路(KM算法) HDOJ 1853 Cyclic Tour
    最大流增广路(KM算法) HDOJ 1533 Going Home
    最大流增广路(KM算法) HDOJ 2255 奔小康赚大钱
    Complete the Word CodeForces
    Gadgets for dollars and pounds CodeForces
    Vasya and Basketball CodeForces
    Carries SCU
  • 原文地址:https://www.cnblogs.com/TextEditor/p/2063172.html
Copyright © 2011-2022 走看看