• 贡献个网址搜索提示框


      前段时间在找一个网址搜索提示的API,也没发现有公开的API。得,公开的没找到,找个没公开的吧。看看hao123、360等网址导航都有自定义网址,在添加网址时都有网址提示,打开浏览器调试工具,查看一下网络请求吧。

      先看hao123,假设搜索bokeyuan这几个字母,从网络监视里得到的请求url是http://nssug.baidu.com/su?cb=jQuery172002392077026888728_1403322091978 &prod=superpage &sc=hao123 &wd=bokeyuan &_=1403324515020

      把不需要的参数去掉,剩下的url是:http://nssug.baidu.com/su?wd=bokeyuan &prod=superpage。在浏览器中请求一下,返回的内容是window.baidu.sug({q:"bokeyuan", p:false, s:["博客园0{#S+_}[1928,"http:\/\/www.cnblogs.com\/",1,1,"\u535a\u5ba2\u56ed"]"]});。内容还是比较乱的,具体参数对应的含义也不是很清楚,用起来稳定性也不能得到保证。

      再看看360导航,搜索bokeyuan,得到的url是http://suggest.h.qhimg.com/index.php? biz=websitename &word=bokeyuan &fmt=jsonp &cnt=8 &cb=__jsonp14__ &t=2338874

      把多余的参数去掉,剩下的url是:http://suggest.h.qhimg.com/index.php? biz=websitename& word=bokeyuan& fmt=json。在浏览器中请求一下,返回的内容是["u535au5ba2u56ed,www.cnblogs.com"],这个就比hao123的简洁多了,直接返回一个json数组,每项都是被一个逗号隔开的网站名和网址,这个使用起来就方便的多了。

      从获取网站图标的方式到网址搜索提示API,可以看出hao123更注重数据的保护,请求流程及其繁琐,外人不宜用。而360导航就感觉比较直白,丝毫不对外隐藏什么,也比较适合外人使用。

      下边是用了360导航的网站搜索提示API并仿照360的网址添加样式的一个网站搜索提示框。试用一下,看看还有没有什么问题,存在bug请及时反馈给我。 

    网站名称:
    网址:

    一. 实现过程  

      大概地介绍一下它的实现吧。html布局如下,css样式就不说了,可以自己查看一下。添加按钮和回车的事件是写在页面里的,也可以自己查看。

    <div id="mysite">
            <div class="txt">网站名称:</div>
            <div class="site-input site-name">
                <input type="text" id="mysite-name-add" placeholder="如:Simple" />
            </div>
            <div class="txt txt-url">网址:</div>
            <div class="site-input site-url">
                <input type="text" id="mysite-url-add"
                    placeholder="如:www.haosimple.com" />
            </div>
            <button onclick="add()" id="btn-site-add" >添加</button>
    </div> 

      重点说一下提示功能,js提示的功能单独封装在了一个js文件中,注释都比较清楚,看起来比较简单。代码流程如下:

    var hoverIndex = -1;
    var ajaxDelay;
    
    $(document)
            .ready(
                    function() {
                        applyCSSAndEvent();
                        addSug();
                        var sugContainer = $(".mysite-suggest");
    
                        //监听文本框的按键抬起事件
                        $("#mysite-name-add,#mysite-url-add")
                                .keyup(
                                        function(event) {
                                            // 若上次间隔时间未到,先取消上次提交
                                            window.clearTimeout(ajaxDelay);
                                            
                                            var e = event || window.event;
                                            var keyCode = e.keyCode;
                                            // 数字字母退格删除空格
                                            if (keyCode >= 48
                                                    && keyCode <= 57
                                                    || (keyCode >= 65 && keyCode <= 90)
                                                    || keyCode == 8
                                                    || keyCode == 46
                                                    || keyCode == 32) {
    
                                                // 获得搜索地址和搜索内容
                                                var word;
                                                var sugApiUrl;
                                                if ("mysite-name-add" == document.activeElement.id) {
                                                    word = $("#mysite-name-add")
                                                            .val();
                                                    sugApiUrl = "http://suggest.h.qhimg.com/index.php?biz=websitename&fmt=jsonp&word=";
                                                } else {
                                                    word = $("#mysite-url-add")
                                                            .val();
                                                    sugApiUrl = "http://suggest.h.qhimg.com/index.php?biz=websiteurl&fmt=jsonp&word=";
                                                }
    
                                                // 没有内容就没必要搜索了
                                                if (word.trim() == "") {
                                                    clearSug();
                                                    return;
                                                }
    
                                                // 500毫秒后进行搜索,500毫秒未到又触发了下次,本次搜索会被取消
                                                ajaxDelay = window.setTimeout(
                                                        'getSite("' + word + '","'
                                                                + sugApiUrl + '")',
                                                        400);
                                                return;
                                            }
    
                                            // 获得提示框中的项
                                            var sitelis = $(sugContainer).children(
                                                    "li");
                                            // 响应向上键
                                            if (keyCode == 38 && sitelis.length > 0) {
                                                if (hoverIndex > 0) {
                                                    hoverIndex--;
                                                } else {
                                                    hoverIndex = sitelis.length - 1;
                                                }
                                                setContent($(sitelis)[hoverIndex]);
                                                changeHoverClass($(sitelis)[hoverIndex]);
                                            }
                                            // 响应向下键
                                            if (keyCode == 40 && sitelis.length > 0) {
                                                if (hoverIndex < sitelis.length - 1) {
                                                    hoverIndex++;
                                                } else {
                                                    hoverIndex = 0;
                                                }
                                                setContent($(sitelis)[hoverIndex]);
                                                changeHoverClass($(sitelis)[hoverIndex]);
                                            }
                                        });
                    });

      第一步,先利用applyCSSAndEvent()函数加载css样式和绑定冒泡事件。样式主要是针对动态生成的提示框及提示项的样式,以这种方式设置css只需要加载一次即可,避免提示项改变重复设置css的做法。然后绑定mouseover事件,当鼠标扫过提示项时,要高亮显示。提示项的mousedown事件响应用户点击时将内容放置到文本框中。还绑定了文本框的键盘向上键事件,因为默认情况下在文本框中按向上键会使光标移到文字前边。如果不这样做的话,在按向上键切换提示项时,光标总会先到文本框前边然后再到文本框后边,体验不好。最后是绑定文本框失去焦点事件,清空并隐藏提示框。

    function applyCSSAndEvent() {
        $(document.body)
                .append(
                        '<style type="text/css">.mysite-suggest{display:none;position:absolute;border:1px solid #707a86;background-color:#fff}.mysite-suggest li{overflow:hidden;height:30px;cursor:pointer}.mysite-suggest .sug-url,.mysite-suggest .sug-name{display:inline;overflow:hidden;float:left;padding-left:6px;font-size:14px;height:30px;line-height:30px;text-overflow:ellipsis;white-space:nowrap}.mysite-suggest .sug-url{margin-right:12px;206px}.mysite-suggest .sug-name{margin-right:80px;188px}.mysite-suggest .hover{background-color:#f2f8ff}</style>');
    
        $(document).on("mouseover", ".mysite-suggest li", function() {
            changeHoverClass(this);
        });
        $(document).on("mousedown", ".mysite-suggest li", function() {
            setContent(this);
        });
        $(document).on("keydown", "#mysite-name-add,#mysite-url-add", function(e) {
            if (e.keyCode == 38)// 将文本框向上键的响应取消
                return false;
        });
        // 当文本框失去焦点时隐藏提示框
        $(document).on("blur", "#mysite-name-add,#mysite-url-add", function() {
            clearSug();
        });
    }
    // 改变提示项的高亮属性
    function changeHoverClass(li) {
        $(".mysite-suggest .hover").removeClass();
        $(li).addClass("hover");
    }
    // 设置网站名、网址文本框的内容
    function setContent(li) {
        $("#mysite-name-add").val($(li).children(":first-child").text());
        $("#mysite-url-add").val($(li).children(":last-child").text());
    }
    // 清空提示框
    function clearSug() {
        $(".mysite-suggest").html(" ");
        $(".mysite-suggest").hide();
    }

      第二步,利用addSug()函数添加提示框,在body最后添加一个ul标签,设置其位置在文本框下边,并使其宽度覆盖两个文本框,代码如下:

    function addSug() {
        var name_container = $(".site-name");
        var url_container = $(".site-url");
        var name_container_offset = name_container.offset();
        var url_container_offset = url_container.offset();
        $(document.body).append('<ul class="mysite-suggest"></ul>');
        $(".mysite-suggest").css("top",(name_container_offset.top + name_container.height())).css("left",
                name_container_offset.left).width(
                url_container_offset.left - name_container_offset.left
                        + url_container.width());
    }

      最后,监听文本框的键盘键入事件,如果是数字字母空格删除退格按键,则根据在不同文本框键入的内容切换请求地址和搜索内容,因为网站名搜索和url搜索的API是不一样的。然后定义一个超时发送的ajax,超时时间为400ms。同时文本框还响应向上向下按键,根据选中的列表项替换文本框的内容。其中ajax请求的代码如下:

    function getSite(word, sugApiUrl) {
        $.ajax({
            type : "get",
            url : sugApiUrl + word,
            dataType : "jsonp",// 数据类型为jsonp
            jsonp : "cb",// 服务端用于接收callback调用的function名的参数,360导航必须是cb
            jsonpCallback : "callback",// 不能采用默认的函数名,360导航对回调名称有限制
            success : function(data) {
                clearSug();// 先清除上一次的列表
    
                var sugContainer = $(".mysite-suggest");
                $(data).each(function() {
                    sugContainer.append(generateSiteList(this));
                });
                // 当返回的数据长度大于0才显示
                if ($(sugContainer).children("li").length > 0) {
                    sugContainer.show();
                    hoverIndex = -1;
                }
            }
        });
    }

      由于这是跨域名请求,所以需要用到jsonp请求方式,请求到内容之后,把内容加载到提示框中并显示。生成列表项的代码如下所示,构建了一个li标签,里边有两个div分别显示网站名和网址,其中css样式就是在开始时js加载过的样式。

    function generateSiteList(data) {
        var name = data.split(',')[0];
        var url = data.split(',')[1];
        return '<li><div class="sug-name">' + name + '</div>    <div class="sug-url">'
                + url + '</div></li>';
    }
  • 相关阅读:
    简单多线程创建
    ajax 实现局部页面更新
    基础分页查询解题思路
    cookie实现登录时间记录
    servlet过滤器
    jstl标签 URL智能寻找路径
    taglib遍历foreach循环list集合
    python之内置高阶函数
    python之lambda的使用
    python中的函数
  • 原文地址:https://www.cnblogs.com/luguo3000/p/3795573.html
Copyright © 2020-2023  润新知