JavaScript事件和练习

事件对象

    //事件对象:
    //当事件的相应函数被触发时,浏览器每次都会将一个事件对象作为实参传递进相应函数
    //在事件对象中封装了当前事件相关的一切属性,比如:鼠标的坐标 键盘哪个按键被按下,鼠标滚轮的方向
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>事件对象</title>
    <style>
        #areaDiv{
    
    
            width: 200px;
            height: 100px;
            border: 1px solid;
        } 
        #showMsg{
    
    
            width: 200px;
            height: 30px;
            border: 1px solid;;
        }
    </style>
    <script type="text/javascript">
    window.onload=function(){
    
    
        var areaDiv = document.getElementById("areaDiv");
        var showMsg = document.getElementById("showMsg");

        //事件对象:
        //当事件的相应函数被触发时,浏览器每次都会将一个事件对象作为实参传递进相应函数
        //在事件对象中封装了当前事件相关的一切属性,比如:鼠标的坐标 键盘哪个按键被按下,鼠标滚轮的方向

       areaDiv.onmousemove=function(event){
    
    

            //解决事件对象的兼容性问题
            event = event||window.event;

            //在showMsg中显示鼠标坐标
            var x = event.clientX;
            var y = event.clientY;

            showMsg.innerHTML="x="+x+"  ,y="+y;
        }
    }
    </script>
</head>
<body>
    <div id="areaDiv"></div>
    <div id="showMsg"></div>
</body>
</html>

div跟随鼠标移动

  //clientX,clientY是相对于当前可见窗口的左上角的坐标
                //而绝对定位样式中,left,top是根据页面的左上角的坐标
                //如果有滚动条向下或者向右滚动,则它们两方相对应的坐标位置会不一致
                //所以需要给left,top加上滚动条滚动的距离
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>div跟随鼠标移动</title>
    <style>
        #box1{
    
    
            width: 100px;
            height: 100px;
            background-color: blueviolet;

            /* 开启绝对定位 */
            position: absolute;
        }
    </style>
    <script type="text/javascript">
        window.onload=function(){
    
    
            document.onmousemove= function(event){
    
    
                //获取鼠标坐标,div跟随盒子移动
                var left = event.clientX;
                var top = event.clientY;

                var box1 = document.getElementById("box1");

                //clientX,clientY是相对于当前可见窗口的左上角的坐标
                //而绝对定位样式中,left,top是根据页面的左上角的坐标
                //如果有滚动条向下或者向右滚动,则它们两方相对应的坐标位置会不一致
                //所以需要给left,top加上滚动条滚动的距离

                //获取滚动条滚动的距离
                //Chrome认为浏览器的滚动条是body的,可以通过body.scrollTop来获取
                //火狐浏览器认为浏览器的滚动条是html的,可以通过documentElement.scrollTop来获取
                var x = document.documentElement.scrollLeft;
                var y = document.documentElement.scrollTop;

                box1.style.left = left+x+"px";
                box1.style.top = top+y+"px";
            }
        }
    </script>

</head>
<body style="height: 1000px; width: 2000px;">
    <div id="box1"></div>
</body>
</html>

冒泡

//事件冒泡(Buddle)
            //事件冒泡就是指事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>冒泡</title>
    <style>
        #box1{
    
    
            background-color: chartreuse;
            width: 300px;
            height: 200px;
        }
        #s1{
    
    
            width: 100px;
            height: 30px;
            background-color: coral;
        }
    </style>
    <script type="text/javascript">
        window.onload=function(){
    
    
            //事件冒泡(Buddle)
            //事件冒泡就是指事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发
            var box1 = document.getElementById("box1");
            box1.onclick=function(event){
    
    
                event= event||window.event;
                //取消事件的冒泡
                //不往其祖先元素传递了
                event.cancelBubble=true;
                alert("我是box1的单击响应函数");
            }

            var s1 = document.getElementById("s1");
            s1.onclick = function(){
    
    
                alert("我是s1的单击响应函数");
            }

            document.body.onclick = function(){
    
    
                alert("我是body的单击相应函数");
            }
        }
    </script>
</head>
<body>
    <div id="box1">
        我是box1
        <span id="s1">我是s1</span>
    </div>
</body>
</html>

事件委派

        //事件的委派:
            //将事件统一绑定给元素的共同祖先元素,这样当后代元素的事件触发时,会一直冒泡到祖先元素
            //事件委派是利用了冒泡,通过委派可以减少事件的绑定次数,提高程序的性能
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>委派</title>
    <script type="text/javascript">
        window.onload=function(){
    
    
            var btn = document.getElementById("btn");
            btn.onclick = function(){
    
    
                //创建新的超链接
                var newlink = document.createElement("li");
                newlink.innerHTML = "<a href='javascript:;' class='link'>新建超链接</a>"
                u1.appendChild(newlink);
            }

            /*
            事件的委派:
                将事件统一绑定给元素的共同祖先元素,这样当后代元素的事件触发时,会一直冒泡到祖先元素
                事件委派是利用了冒泡,通过委派可以减少事件的绑定次数,提高程序的性能
            */
            var u1 = document.getElementById("u1");
            u1.onclick=function(event){
    
    
                //只希望点击li标签时触发事件,而不是ul标签全部
                //event.target是返回触发此事件的元素(事件的目标节点)
                if(event.target.className=="link"){
    
    
                    alert("hh");
                }
            }
        }
    </script>
</head>
<body>
    <button id="btn">新建超链接</button>
    <ul id="u1">
        <li><a href="javascript:;" class="link">超链接1</a></li>
        <li><a href="javascript:;" class="link">超链接2</a></li>
        <li><a href="javascript:;" class="link">超链接3</a></li>
    </ul>
</body>
</html>

绑定事件

        //所以用 增添事件监听器(可以添加多个事件)
        //参数1:事件的字符串名 不要on
        //参数2:回调函数,当事件触发时该函数会调用
        //参数3:是否在捕获阶段触发事件,一般都传false
        btn.addEventListener(,,)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>绑定事件</title>
    <script type="text/javascript">
        window.onload=function(){
    
    
            var btn = document.getElementById("btn");
            // btn.onclick = function(){
    
    
            //     alert(1);
            // };           
            // btn.onclick = function(){
    
    
            //     alert(2);
            // };            
            // btn.onclick = function(){
    
    
            //     alert(3);
            // };
            //上面的只会执行alert(3),因为按照执行顺序,前面的两个相应函数被覆盖了

            //所以用 增添事件监听器(可以添加多个事件)
            //参数1:事件的字符串名 不要on
            //参数2:回调函数,当事件触发时该函数会调用
            //参数3:是否在捕获阶段触发事件,一般都传false
            btn.addEventListener("click",function(){
    
    
                alert(1);  
            },false);
            btn.addEventListener("click",function(){
    
    
                alert(2);  
            },false);
            btn.addEventListener("click",function(){
    
    
                alert(3);  
            },false);

        }

    </script>
</head>
<body>
    <button id="btn">点我一下</button>
</body>
</html>

事件的传播

        /*
        事件的传播
            -关于事件的传播网景公司和微软公司有不同的理解
                –微软公司认为事件应该是由内向外传播,也就是当事件触发时,应该先触发当前元素上的事件,
                然后再向当前元素的祖先元素上传播,也就说事件应该在冒泡阶段执行。
                -网景公司认为事件应该是由外向内传播的,也就是当前事件触发时,应该先触发当前元素的最外层的祖先元素的事件,
                然后在向内传播给后代元素
                - w3C综合了两个公司的方案,将事件传播分成了三个阶段
                1.捕获阶段
                -在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件
                2.目标阶段
                -事件捕获到目标元素,捕获结束开始在目标元素上触发事件
                3.冒泡阶段
                -事件从目标元素向他的祖先元素传递,依次触发祖先元素上的事件

                -如果希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true
                一般情况下我们不会希望在捕获阶段触发事件,所以这个参数一般都是false
        */
 btn.addEventListener("click",callback,false);

BOM对象

    <script type="text/javascript">
        /*BOM
        浏览器对象模型
        BOM可以是我们通过JS来操作浏览器
        在BOM中为我们提供了一组对象
        1 Window
            代表整个浏览器的窗口,同时window也是网页中的全局对象
        2 Navigator
            代表的当前浏览器的信息,通过该对象可以来识别不同浏览器
        3 Location
            代表浏览器的地址栏信息,可以操作浏览器跳转页面
        4 History
            代表浏览器的历史记录,可以操作浏览器的历史记录
            由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页
            而且该操作只在当次访问时有效
        5 Screen
            代表用户屏幕的信息
        */
    </script>

判断浏览器的类型(Navigator)

    <script type="text/javascript">
        //虽然Navigator是浏览器的信息,但是不能用它来判断浏览器的类型

        //一般我们用userAgent来判断浏览器的信息
        
        //Chrome浏览器
        //Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
        
        //火狐浏览器
        //Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0
        
        //IE 8-10浏览器
        //Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)

        //但是IE 11 很孙子,隐藏了userAgent,我们不能用userAgent来标识IE11 所以用那个 "ActiveXObject" in window来判断
        

        //获取浏览器的userAgent
        var userA = navigator.userAgent;

        //用正则表达式来判断(i忽略大小写)
        if(/firefox/i.test(userA)){
    
    
            alert("你是火狐");
        }else if(/chrome/i.test(userA)){
    
    
            alert("你是Chrome");
        }else if(/msie/i.test(userA)){
    
    
            alert("你是IE");
        }else if("ActiveXObject" in window){
    
    
            alert("抓住你了,IE11");
        }
    </script>

History

    <title>test02</title>
    <script type="text/javascript">
        window.onload = function(){
    
    
            var btn01 = document.getElementById("btn01");
            var btn02 = document.getElementById("btn02");

            btn02.onclick = function(){
    
    
                //跳往下一个页面
                history.forward();
            }

            btn01.onclick=function(){
    
    
                //跳往上一个页面
                history.back();
            }
        
        //history.go() 表示跳转多个页面
        //参数是一个整数值
        //1 代表向前跳转1个页面
        //2 代表向前跳转2个页面
        //-1 代表向后跳转1个页面
        }
    </script>
</head>
<body>
    <h1>这里是test02页面</h1>
    <a href="test01.html">跳往test01</a>
    <button id="btn01">向前跳转</button>
    <button id="btn02">向后跳转</button>
    <a href="test03.html">跳往test03</a>
</body>

定时器

    <script type="text/javascript">
        //setInterval()
        // 将一个函数每隔一段时间执行一次
        // 参数: 1 回调函数 2 间隔时间(单位毫秒)
        //返回值:
        //  返回一个Number类型的数据
        //  这个数字作为定时器的唯一标识

        window.onload = function(){
    
    

            var count = document.getElementById("count");

            var num = 1;

            var timer = setInterval(function(){
    
    
                count.innerHTML = num++;
                if(num==11){
    
    
                    //关闭定时器
                    clearInterval(timer);
                }
            },500);
        }
    </script>
</head>
<body>
    <h1 id="count"></h1>
</body>

定时切换图片

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>定时切换图片练习</title>
    <style>
        img{
    
    
            width: 500px;
        }
    </style>
    <script type="text/javascript">
        window.onload = function(){
    
    
            var btn01 = document.getElementById("btn01");
            var btn02 = document.getElementById("btn02");
            var img = document.getElementById("imges");

            var timer ;
            var imgArray =["images/1.jpg","images/2.jpg","images/3.jpg","images/4.jpg","images/5.jpg","images/6.jpg","images/7.jpg"];
            var index = 0;
            //开启定时播放
            btn01.onclick = function(){
    
    
                //目前,我们每点击一次,就会开启一个定时器
                //所以在开启新的定时器之前,需要关闭之前已经开启的定时器
                clearInterval(timer);

                //开启新的定时器
                timer = setInterval(function(){
    
    
                    index++;
                    index = index % imgArray.length;
                    img.src = imgArray[index];
                },500);
            };

            btn02.onclick = function(){
    
    
                clearInterval(timer);
            };

        }
    </script>
</head>
<body>
        <img src="images/1.jpg" id="imges">
        <br><br>
        <button id="btn01">开始</button>
        <button id="btn02">停止</button>
</body>
</html>

延时调用

    <script type="text/javascript">
        window.onload = function(){
    
    
            var num=0;
            //延时调用
            //延时调用就是一个函数不马上执行,而是隔一段函数再执行,只会执行一次
            var timer = setTimeout(function(){
    
    
                console.log(num++);
            },3000);

            //关闭延时调用
            clearTimeout(timer);

        }
    </script>

轮播图

js工具文件

            /*
                obj:要执行动画的对象
                attr:要改变的属性
                target:执行动画的目标位置
                speed:移动的速度(传入正值,下面会判断)
                callback:回调函数,动画执行完毕之后执行
            */
           function move(obj,attr,target,speed,callback){
    
    
            //开启新的定时器之前,要把之前开启的定时器关闭,要不然就会越来越快
            clearInterval(obj.timer);

            //获取元素当前位置(只需要获取一次,只是为了判断开始的位置在何处用来调整speed的正负)
            var current = parseInt(getStyle(obj,attr));

            //如果当前位置大于target(目标位置),说明元素向左运动,将speed变为负值
            if(current>target){
    
    
                speed = -speed;
            }

            //开启一个定时器
            //向执行动画的对象中添加一个timer属性,让每个对象拥有自己的定时器
            obj.timer = setInterval(function(){
    
    

                var oldStyle = getStyle(obj,attr);//有单位的px
                var oldVlaue = parseInt(oldStyle);//转化成数字

                var newValue = oldVlaue + speed;
                //可能speed不一样,所以不一定能达到整数目标位置的值
                //所以判断大于或者小于目标位置时,让它等于目标位置
                if(speed>0 && newValue>target || speed<0 && newValue<target){
    
    
                    newValue=target;
                }

                obj.style[attr] = newValue+"px";

                //等于target(目标位置)时,动画执行完毕,让它关闭定时器
                if(newValue===target){
    
    
                    clearInterval(obj.timer);

                    //当没有传回调函数的时候,callback的值为false,下面的语句就不会往下执行了,也就是callback()不会执行
                    //当传了回调函数,callback的值为true,语句就会继续执行
                    callback && callback();
                }
            },50);
        }

        function getStyle(obj,name){
    
    
            if(window.getComputedStyle){
    
    
                //正常浏览器的方式,具有getComputedStyle()方法
                return getComputedStyle(obj,null)[name];
            }else{
    
    
                //IE8的方式,没有getComputedStyle()方法
                return obj.currentStyle[name];
            }
        }
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>轮播图</title>
    <style>
        *{
    
    
            margin: 0 0;
            padding: 0 0;
        }
        #outer{
    
    
            width: 420px;
            height: 270px;
            background-color: greenyellow;
            margin: 100px auto;
            position: relative;
            /* 裁剪益出的内容 */
            overflow: hidden;
        }
        #imgList{
    
    
            list-style: none;
            /* 图片的个数不确定,所以要动态获取ul的宽度 */
            /* width: 2940px; */
            position: absolute;
            left: -840px;
        }
        #nav{
    
    
            position: absolute;
            bottom: 12px;
            /* 设置nav水平居中 */
            left: 210px;
            /*  (16+3+3)*7/2  */
            /* 当图片的个数不确定时,margin-left的值就会变化,我们用JS动态计算 */
            /* margin-left: -77px; */
        }
        #nav a{
    
    
            float: left;
            background-color: red;
            height: 16px;
            width: 16px;
            /* 分开导航,分块 */
            margin: 0 3px;
            /* 设置透明 */
            opacity: 0.5;
        }
        #nav a:hover{
    
    
            background-color: black;
        }
        #imgList li{
    
    
            float: left;
            margin: 10px 10px;
        }
        #imgList li img{
    
    
            width: 400px;
            height: 250px;
        }
    </style>

    <!-- 链接外部位置 -->
    <script src="tools.js" type="text/javascript"></script>
    <script type="text/javascript">
        window.onload = function(){
    
    
            //获取imgList
            var imgList = document.getElementById("imgList");
            //获取页面中的轮播图片
            var imgArr = document.getElementsByTagName("img");
            //设置imgList的width宽度
            imgList.style.width = imgArr.length*420+"px";

            //获取nav
            var nav = document.getElementById("nav");
            //获取nav下的a
            var navA = document.getElementsByTagName("a");
            //设置nav的margin-left
            //注意margin-left要用驼峰法哦
            nav.style.marginLeft = -(navA.length*23/2)+"px";

            //设置默认显示的nav为黑色
            var index = 0;
            navA[index].style.backgroundColor="black"; 

            for(var i=0;i<navA.length;i++){
    
    
                //为每一个超链接添加一个num属性,作为标记
                navA[i].num = i;
                
                //为每一个超链接绑定单击响应函数
                navA[i].onclick = function(){
    
    
                    //获取点击超链接的索引,并将其设置为index
                    index = this.num;

                    //切换图片
                    // imgList.style.left = -420*index+"px"
                    //修改正在点击的a的颜色
                    setA();

                    //轮播图片
                    move(imgList,"left",-420*index,40,function(){
    
    });
                }
            }

            //点击导航的时候 ,设置a的颜色
            function setA(){
    
    
                //判断当前是否是最后一张
                if(index>=imgArr.length-1){
    
    
                    index=0;

                    //此时显示的是最后一张图片,快速切换到第一张
                    imgList.style.left = 0;
                }

                for(var i=0; i<navA.length;i++){
    
    
                    //当你直接设置了red,就会出现点击之后,当鼠标移上去,hover效果没有了
                    //这是因为下面设置的内联样式,优先级高于表头式的样式,所以hover失效了
                    // navA[i].style.backgroundColor="red";
                    //当你设置为空的时候,内联样式失效,就会显示表头式的样式
                    navA[i].style.backgroundColor = "";
                }
                navA[index].style.backgroundColor = "black"
            }

            //创建一个函数,用来开启自动切换函数
            function autoChange(){
    
    
                //开启一个定时器,用来定时切换图片
                setInterval(function(){
    
    
                    //索引自增,切换图片
                    index++;
                    //循环自动播放
                    index = index % imgArr.length;

                    //执行动画,切换图片
                    move(imgList,"left",-420*index,50,function(){
    
    
                        //修改导航按钮
                        setA();
                    });

                },3000);
            }

            autoChange();
        }; 
    </script>
</head>
<body>
    <!-- 创建一个外部的容器,存放ul -->
    <div id="outer">
        <ul id="imgList">
            <li><img src="images/1.jpg"></li>
            <li><img src="images/2.jpg"></li>
            <li><img src="images/3.jpg"></li>
            <li><img src="images/4.jpg"></li>
            <li><img src="images/5.jpg"></li>
            <li><img src="images/6.jpg"></li>
            <li><img src="images/7.jpg"></li>
            <!-- 与第一张相同 -->
            <li><img src="images/1.jpg"></li>
        </ul>
        <div id="nav">
            <a href="#"></a>
            <a href="#"></a>
            <a href="#"></a>
            <a href="#"></a>
            <a href="#"></a>
            <a href="#"></a>
            <a href="#"></a>
        </div>
    </div>
</body>
</html>

类样式的操作

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>类的操作</title>
    <style type="text/css">
        .b1{
    
    
            height: 100px;
            width: 100px;
            background-color: blueviolet;
        }
        .b2{
    
    
            height: 200px;
            width: 200px;
            background-color: chartreuse;
        }
    </style>
    <script type="text/javascript">
        window.onload = function(){
    
    
            var btn = document.getElementById("btn");
            var box = document.getElementById("box");

            // btn.onclick = function(){
    
    
            //     box.style.width = "200px";
            //     box.style.height = "200px";
            //     box.style.backgroundColor = "chartreuse";
            // }
            //这种方式通过style属性来修改元素的样式,每修改一个样式,浏览器就需要重新渲染一次页面
            //这种执行的性能比较差

            //我们可以直接改class的属性对应样式,b2
            //同时修改多个样式,浏览器只需要重新渲染页面一次,性能高
            btn.onclick = function(){
    
    
                toggleClass(box,"b2")
            }

            //定义一个函数,用来增加样式
            function addClass(obj,cn){
    
    
                //检查obj中是否含有cn样式
                if(!hasClass(obj,cn)){
    
    
                    obj.className += " "+cn;
                }
            }

            //定义一个函数,判断有没有一个样式
            function hasClass(obj,cn){
    
    
                //正则表达式,、存在cn样式名的
                //\b \b是单词边界,cn是单独的一个单词
                var reg = new RegExp("\\b"+cn+"\\b")
                return reg.test(obj.className);
            }

            //定义一个函数,删除class属性
            function removeClass(obj,cn){
    
    
                //匹配到有cn的字符串
                var reg = new RegExp("\\b"+cn+"\\b")
                obj.className = obj.className.replace(reg,"");
            }

            //用来切换一个类样式
            //有就删除,没有就添加
            function toggleClass(obj,cn){
    
    
                //判断obj中是否含有cn
                if(hasClass(obj,cn)){
    
    
                    removeClass(obj,cn);
                }else{
    
    
                    addClass(obj,cn);
                }
            }
        }

    </script>
</head>
<body>
    <button id="btn">点击修改box的样式</button>
    <br><br>
    <div class="b1" id="box"></div>
</body>
</html>

二级菜单

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>二级菜单</title>
    <style>
        .sdmenu{
    
    
            margin: 0 auto;
        }
        .sdmenu div{
    
    
            /* 当点击折叠时,div的class属性变为collapsed
                就是减小了div的高度,让div只能显示上面的span内容
                下面的内容会溢出,所以需要设置当元素溢出时的状况
             */
             /* 
                visible	默认值。内容不会被修剪,会呈现在元素框之外。
                hidden	内容会被修剪,并且其余内容是不可见的。
                scroll	内容会被修剪,但是浏览器会显示滚动条以便查看其余的内容。
                auto	如果内容被修剪,则浏览器会显示滚动条以便查看其余的内容。
                inherit	规定应该从父元素继承 overflow 属性的值
            */
            overflow: hidden;
        }
        .sdmenu span{
    
    
            background-color: turquoise;
            display: block;
            width: 150px;
            color: red;
            font-size: 20px;
            line-height: 25px;
            height: 25px;
            overflow: hidden;
            cursor: pointer;
        }
        .sdmenu div a{
    
    
            text-decoration: none;
            border: 1px solid black;
            display: block;
            color: white;
            background-color: teal;
            width: 150px;
            text-align: center;
            font-size: 15px;
        }
        .collapsed{
    
    
            height: 25px;
        }
    </style>
    <script src="tools.js"></script>
    <script src="tool.js"></script>
    <script type="text/javascript">
        window.onload = function(){
    
    
            //我们每一个菜单就是一个div
            //当div具有collapsed这个类样式时,div就是折叠状态
            //当div没有这个类时,div就是展开状态

            //获取所有class为menuSpan的元素
            var menuSpan = document.querySelectorAll(".menuSpan")
        
            //定义一个变量,用来保存当前打开的菜单
            //当前是页面开始时默认打开的菜单(第一个)
            var openDiv = menuSpan[0].parentNode;

            //为span绑定单击相应函数
            for(var i=0;i<menuSpan.length;i++){
    
    
                menuSpan[i].onclick = function(){
    
    
                    //this代表当前点击的span
                    //获取当前span的父元素
                    var parentDiv = this.parentNode;

                    //切换类之前,获取元素的高度
                    var begin = parentDiv.offsetHeight;

                    //切换parentDiv
                    toggleClass(parentDiv,"collapsed");
                    
                    //切换类之后,获取元素的高度
                    var end = parentDiv.offsetHeight;

                    //console.log("begin="+begin+",end="+end);
                    //动画效果就是将高度从begin向end过渡
                    //所以需要将元素的高度重置为begin
                    parentDiv.style.height = begin + "px";

                    //执行动画,从begin向end过渡
                    move(parentDiv,"height",end,20,function(){
    
    
                        //设置回调函数将上面的内联样式高度改为""
                        parentDiv.style.height="";
                    })


                    //parentDiv!=openDiv:原因
                    //当开始默认打开的菜单被关闭之后 parentDiv等于openDiv
                    //又一次想要打开它时,执行toggleClass后就不用再执行addClass了
                    if(parentDiv!=openDiv && !hasClass(openDiv,"collapsed")){
    
    
                        //打开菜单之后,关闭其他已经打开的菜单
                        // addClass(openDiv,"collapsed");

                        //!hasClass(openDiv,"collapsed"):原因
                        //为了统一处理动画过渡效果,我们希望在这里将addClass改为toggleClass
                        //并且toggleClass不需要有移除的功能
                        toggleClass(openDiv,"collapsed");
                    }

                    //设置当前打开的菜单
                    openDiv = parentDiv
                };
            }
        
        }  

    </script>
</head>
<body>
    <div id="my_menu" class="sdmenu">
        <div>
            <span class="menuSpan">在线工具</span>
            <a href="#">图像优化</a>
            <a href="#">收藏夹</a>
            <a href="#">邮件</a>
            <a href="#">梯度图像</a>
            <a href="#">按钮生成器</a>
        </div>
        <div class="collapsed">
            <span class="menuSpan">支持我们</span>
            <a href="#">推荐我们</a>
            <a href="#">链接我们</a>
            <a href="#">网络资源</a>
        </div>
        <div class="collapsed">
            <span class="menuSpan">合作伙伴</span>
            <a href="#">javaScript工具包</a>
            <a href="#">CSS驱动</a>
            <a href="#">CodingForums</a>
            <a href="#">CSS例子</a>
        </div>
        <div class="collapsed">
            <span class="menuSpan">测试电流</span>
            <a href="#">Current or not</a>
            <a href="#">Current or not</a>
        </div>
    </div>
</body>
</html>

JSON

    <script type="text/javascript">
        /*
        JSON就是一个特殊的字符串,这个字符串可以被任意的语言的识别
            并且可以转化为任意语言中的对象,JSON在开发中主要用来做数据的交互

            JavaScript Object Notation JS对象表示法
            JSON和JS对象的格式一样,只不过JSON字符串中的属性名必须加双引号

            JSON分类:
                1 对象{}
                    '{"name":"孙悟空","age":18}'
                2 数组[]
                    '["王五","菲菲","程度"]'
            
            JSON中允许的值:
                1 字符串
                2 数值
                3 布尔值
                4 null
                5 对象
                6 数组
        */

        var obj = {
    
    "name":"孙悟空","age":18};
        var arr =["王五","菲菲","程度"];

        // 将JSON字符串转化成JS中的对象
        // 提供了一个工具类: JSON

        var json = '{"name":"孙悟空","age":18}';

        //json-->js对象
        //  JSON.parse()
        var obj1 = JSON.parse(json);
        console.log(obj1.age);

        //js对象-->json字符串
        //  JSON.stringify()
        var str = JSON.stringify(obj);
        console.log(str);
        
    </script>

猜你喜欢

转载自blog.csdn.net/weixin_46250447/article/details/111965959