• 贡献个网址搜索提示框


      前段时间在找一个网址搜索提示的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>';
    }
  • 相关阅读:
    标签的讲解
    属性分类
    LeetCode 003. 无重复字符的最长子串 双指针
    Leetcode 136. 只出现一次的数字 异或性质
    Leetcode 231. 2的幂 数学
    LeetCode 21. 合并两个有序链表
    象棋博弈资源
    acwing 343. 排序 topsort floyd 传播闭包
    Leetcode 945 使数组唯一的最小增量 贪心
    Leetcode 785 判断二分图 BFS 二分染色
  • 原文地址:https://www.cnblogs.com/luguo3000/p/3795573.html
Copyright © 2020-2023  润新知