原生js —— 节流 & 百度搜索 & 阻止事件的默认行为

写在前面

参考文章:
http://caibaojian.com/javascript-stoppropagation-preventdefault.html#comments
https://www.cnblogs.com/qiuyuntao/p/3703578.html

阻止事件的默认行为

① 在用addEventListener绑定事件时阻止事件的默认行为:e.preventDefault(),用return false无效
② 在用非addEventListener绑定事件时阻止事件的默认行为:return false/e.preventDefault()
③ 在jQueryreturn false = e.preventDefault()+event.stopPropagation()
④ IE使用的阻止事件默认行为为:e.returnValue = false,IE使用的阻止冒泡:event.cancelBubble = true
⑤ 当Event 对象的 cancelablefalse时,表示没有默认行为.

1. 节流

要求:在用户输入内容后要向服务器请求内容,为了节省带宽,可通过节流来限制请求次数,既不让用户感觉到疑惑,也能节省带宽。当用户输入两个字符的间隔时间超过500ms时,请求内容;当输入两个字符的间隔时间小于500ms时,不请求内容。

注意:① 在每次请求内容前都应该先清除上一次的计时器(若两次输入间隔时间大于500ms,上一次请求也已经完成。若小于,则将上一次计时器清除,这样上一次的请求便失效)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="text"/>
</body>
<script>
    var ipt = document.getElementsByTagName("input")[0];
    var timer;
    function request(method,url,async,data,cb) {
        var obj = new XMLHttpRequest();
        if(method=="get"){
            if(data){
                url +=data
            }
            obj.open(method,url,async)
        }else{
            if(data){
                obj.open(method,url,async);
                obj.send(data);
            }else{
                obj.open(method,url,async);
                obj.send();
            }
        }
        obj.onreadystatechange = function (ev) {
            if(obj.readyState==4 && obj.status==200){
                cb(obj.response);
            }
        }

    }
    ipt.onkeydown = function (ev) {
        clearInterval(timer);
        timer = setTimeout(function () {
            request("post","data.txt",true,"",function (response) {
                console.log(response)
            })
        },550)
    }
</script>
</html>
2. 百度搜索

功能:实现百度搜索的功能:
① 调用百度的两个api,从而可获取到与用户输入的内容匹配的所有内容集合以及可跳转到某一个内容对应的网页。
② 在按键盘的上下左右键时,不发送请求。在该搜索中,为了减小带宽,加入了节流。 当按键盘的上下键时会进行选择内容切换。(给bodyonkeyup事件,这样才可选中元素)
③ 点击百度一下按钮时,会跳转到当前文本框内容对应的网页。
④ 当进行上下键切换选中某一元素并按回车后会重新请求,直到没有返回内容,此时再按下回车,会直接跳转到当前文本框内容对应的网页
⑤ 当按上下键切换,文本框的onkeyup事件也会被触发,由于按文本框的上下键的作用是光标在最后or最前(因为文本框没有上一个元素,故按上键光标会跳到最前面,当将选中内容赋值给文本框的value时,光标又会跳到最后)。故为了防止光标来回切换,需要在文本框的onkeydown事件中阻止文本框的默认行为。

注意:① 当动态创建script标签时,动态修改其src值是不能再次请求到内容集合的!必须要将之前的script标签移除后再重新动态创建
② 为了防止ul中li的长度不够,故每次请求内容为空或者用户输入为空时,remove之前创建的ul。在重新请求时重新创建!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .all{
            position: absolute;
            margin: auto;
            left: 0;
            right: 0;
            top: 0;
            bottom: 0;
            width: 660px;
            height: 300px;
        }
        .inputAll{
            position: absolute;
            width: 660px;
            height: 38px;
            border:1px solid black;
        }
        .left{
            float: left;
            width: 82%;
            height: 100%;
            border: none;
            outline: none;
            padding-left: 10px;
        }
        .right{
            float: right;
            height: 100%;
            width: 15%;
            background: #15a0ff;
            color: #fff;
            text-align: center;
            line-height: 38px;
        }
        .ulEle{
            position:absolute ;
            top:39px;
            width:85%;
            border:1px solid #aaa;
        }
        ul,li{
            list-style-type: none;
        }
        .choose{
            background: #eee;
        }
        a{
            text-decoration:none;
            color: black;
        }
    </style>
</head>
<body>
<div class="all">
    <div class="inputAll">
        <input class="left" type="text"/>
        <div class="right">百度一下</div>
    </div>
</div>
</body>
<script>
    /*
    * https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=
    * https://www.baidu.com/s?wd=
    *
    * */
    var left = document.getElementsByClassName("left")[0];
    var right = document.getElementsByClassName("right")[0];
    var all = document.getElementsByClassName("all")[0];
    var ulEle = document.getElementsByClassName("ulEle")[0];
    var liList;
    var s;
    var count = -1;
    var api = "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su";
    right.onclick = function(){
        console.log(left.innerHTML)
        location.href="https://www.baidu.com/s?wd="+left.value;
    };
    left.addEventListener("keyup",getContent(api));
    left.addEventListener("keydown",function (e) {
        if(e.keyCode == 38 || e.keyCode==40){
            e.preventDefault();//阻止默认事件
        }
    });
    document.body.addEventListener("keyup",function (e) {
        if(liList){
            if(e.keyCode==40){
                if(count==liList.children.length-1){
                    count=0;
                }else{
                    count++;
                }
                if(count>0){
                    liList.children[count-1].className="";
                }else{
                    liList.children[liList.children.length-1].className="";
                }
                liList.children[count].className = "choose";
                left.value = liList.children[count].innerText;
            }
            else if(e.keyCode==38){
                count--;
                if(count<0){
                    count = liList.children.length-1;
                    liList.children[0].className=""
                }else{
                    liList.children[count+1].className=""
                }
                liList.children[count].className = "choose";
                left.value = liList.children[count].innerText;
            }
            // if()
        }
    });

    function getContent() {
        var arg = arguments[0];
        var timer;
        return function (e) {
            console.log(e.keyCode)
            var that = this;
            if(e.keyCode==38 || e.keyCode==40 || e.keyCode == 39 || e.keyCode==37){
                return;
            }
            if(e.keyCode==13 && !liList.children.length){
                location.href="https://www.baidu.com/s?wd="+left.value;
            }
           if(timer){
               clearTimeout(timer)
           }
           timer =  setTimeout(function () {
               console.log(that)
                if(!that.value &&  liList){
                    liList.remove();
                }
                JSONP.apply(that,[arg])
            },500)

        }
    }
    function JSONP() {
        if(s){//重新给script标签的src赋值不可!
            s.remove();
        }
        if(this.value){
            var js = document.createElement("script");
            js.src = arguments[0]+"?wd="+this.value+"&cb=getData";
            console.log(js.src)
            document.body.appendChild(js);
            s = js
        }

    }
    function getData(res) {
        if(liList){//先将ul移除,再重新创建,将父元素移除时已经将子元素移除
            liList.remove();
        }
        var ul = document.createElement("ul");
        ul.className="ulEle";
        for(var i=0;i<res.s.length;i++){
            var li = document.createElement("li");
            li.innerHTML = "<a href='https://www.baidu.com/s?wd="+res.s[i]+"'>"+res.s[i]+"</a>";
            ul.appendChild(li);
        }
        all.appendChild(ul);
        liList = ul;
    }
</script>
</html>

发布了72 篇原创文章 · 获赞 72 · 访问量 6336

猜你喜欢

转载自blog.csdn.net/weixin_43314846/article/details/100980186