• 一个网站的诞生 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/


  • 相关阅读:
    【codevs1227】方格取数2(最大流费最大流-模板
    【ZJOI2008】【BZOJ1033】杀蚂蚁(占坑待填
    python基础学习1-流程控制和判断
    python基础学习1-变量定义赋值,屏幕输入输出
    Jzoj5237 最长公共子序列
    Jzoj5236 利普希茨
    [置顶] 欢迎使用CSDN-markdown编辑器
    Jzoj5235 好的排列
    Jzoj5234 外星人的路径
    Jzoj5231 序列问题
  • 原文地址:https://www.cnblogs.com/TextEditor/p/2063172.html
Copyright © 2020-2023  润新知