JS 事件 轮播图 0402

news/2024/7/6 6:31:34

1. tab切换

<style>
        *{
            margin: 0;
            padding:0;
        }

        ul,ol,li{
            list-style: none;
        }

        .cont{
            width: 800px;
            height: 600px;
            border: 5px solid #333;
            margin: 0 auto;
            display: flex;
            flex-direction: column;
        }

        .cont ul{
            width: 100%;
            height: 60px;
            display: flex;
        }

        .cont ul li{
            flex:1;
            font-size: 35px;
            color: #fff;
            border-left: 2px solid blue;
            border-right: 2px solid blue;
            background: hotpink;
            display: flex;
            justify-content: center;
            align-items: center;

        }

        .cont ol{
            flex:1;
            position: relative;
        }

        .cont ol li{
            width: 100%;
            height: 100%;
            font-size: 150px;
            display: flex;
            justify-content: center;
            align-items: center;
            position: absolute;
            top:0;
            left:0;
            background: burlywood;
            display: none;
        }

        /* 按钮标签 哪个标签有这个属性,哪个就显示特殊背景颜色 */
        .cont ul li.active{
            background: skyblue;
            color: black;
        }

        /* 内容标签 哪个标签有这个属性,哪个就显示 */
        .cont ol li.active{
            display: flex;
        }

    </style>
</head>
<body>
    <div class="cont">
        <ul>
            <li class="active">按钮1</li>
            <li>按钮2</li>
            <li>按钮3</li>
        </ul>
        <ol>
            <li class="active">内容1</li>
            <li >内容2</li>
            <li>内容3</li>
        </ol>
    </div>

    <script>
        // 1,核心思想:
        //   利用 按钮标签 与 内容标签 标签数量是一一对应的关系
        //   通过点击 按钮标签 同时操作 对应的内容标签
        // 2,基本步骤:
        //   点击 按钮标签 时
        //     1,给所有的li标签,包括ul,ol中的所有li标签,清除class样式
        //     2,给当前点击的 按钮标签 添加样式
        //     3,给对应的 内容标签 添加样式

        // 方法1: 两个forEach循环

        // 获取标签对象
        var ullis = document.querySelectorAll('ul li');
        var ollis = document.querySelectorAll('ol li');

        // 通过第一层循环,给所有的ul中的li,添加点击事件
        ullis.forEach(function(item1 , key1){
            // item1,是ul中的li标签,key1是这个ul标签,对应的索引下标
            item1.onclick = function(){
                // 1,点击时,给所有的li标签,清除class样式
                // 需要点击时,循环遍历所有的li标签,设定class样式为 ''

                // 可以通过两个循环完成
                // ullis.forEach(function(item2,key2){
                //     item2.className = '';
                // })

                // ollis.forEach(function(item3,key3){
                //     item3.className = '';
                // })

                // 利用ul>li,ol>li索引下标完全下同的原理
                // 利用循环ul时生成的索引下标,从ol中,获取li标签,进行操作
                ullis.forEach(function(item2,key2){
                    item2.className = '';
                    ollis[key2].className = '';
                })

                // 2,给当前的点击标签,添加css样式
                item1.className = 'active';

                // 3,给索引相同的,ol中的li标签,添加样式
                ollis[key1].className = 'active';
            }
        })

2. tab切换之事件的委托

<style>
        *{
            margin: 0;
            padding:0;
        }

        ul,ol,li{
            list-style: none;
        }

        .cont{
            width: 800px;
            height: 600px;
            border: 5px solid #333;
            margin: 0 auto;
            display: flex;
            flex-direction: column;
        }

        .cont ul{
            width: 100%;
            height: 60px;
            display: flex;
        }

        .cont ul li{
            flex:1;
            font-size: 35px;
            color: #fff;
            border-left: 2px solid blue;
            border-right: 2px solid blue;
            background: hotpink;
            display: flex;
            justify-content: center;
            align-items: center;

        }

        .cont ol{
            flex:1;
            position: relative;
        }

        .cont ol li{
            width: 100%;
            height: 100%;
            font-size: 150px;
            display: flex;
            justify-content: center;
            align-items: center;
            position: absolute;
            top:0;
            left:0;
            background: burlywood;
            display: none;
        }

        /* 按钮标签 哪个标签有这个属性,哪个就显示特殊背景颜色 */
        .cont ul li.active{
            background: skyblue;
            color: black;
        }

        /* 内容标签 哪个标签有这个属性,哪个就显示 */
        .cont ol li.active{
            display: flex;
        }

    </style>
</head>
<body>
    <div class="cont">
        <ul>
            <li name="ulli"  class="active">按钮1</li>
            <li name="ulli" >按钮2</li>
            <li name="ulli" >按钮3</li>
        </ul>
        <ol>
            <li name="olli"  class="active">内容1</li>
            <li name="olli" >内容2</li>
            <li name="olli" >内容3</li>
        </ol>
    </div>

    <script>
        // 1,核心思想:
        //   利用 按钮标签 与 内容标签 标签数量是一一对应的关系
        //   通过点击 按钮标签 同时操作 对应的内容标签
        // 2,基本步骤:
        //   点击 按钮标签 时
        //     1,给所有的li标签,包括ul,ol中的所有li标签,清除class样式
        //     2,给当前点击的 按钮标签 添加样式
        //     3,给对应的 内容标签 添加样式

        // 事件委托
        //     1,给父级div,添加事件委托
        //     2,判断点击 ul中的li时,执行程序
        //           1,给所有的li清除class样式标签
        //           2,给点击的li添加class样式
        //           3,给点击的li对应的ol中的li,添加class样式

        // 区别:
        //     1,获取父级div标签对象,添加点击事件
        //     2,给li添加属性,做区别
        //     3,没有循环:当前标签是 e.target
        //     4,没有循环,无法获取到当前标签的索引下标
        //       必须要在标签中,定义属性来存储索引下标
        //       方法1,直接写在标签中
        //       方法2,通过循环遍历,给ul中的li,setAttribute

        // 总结:事件委托方式,代码更麻烦但是,少了一层循环,执行效率更高

        // 方法2: 事件委托

        // 获取父级div标签对象
        var oDiv = document.querySelector('div');

        // 获取标签对象
        var ullis = document.querySelectorAll('ul li');
        var ollis = document.querySelectorAll('ol li');

        // 给父级div添加点击事件
        // 获取事件对象,我偷懒,不写兼容了
        oDiv.onclick = function(e){
            // 判断,点击的是ul中的li标签
            // e.target,就是触发点击事件的标签对象
            // 如果点击的标签对象,name是ulli,表示点击的是ul中的li标签
            if(e.target.getAttribute('name') === 'ulli'){
                // 1,给所有的li标签,清除样式
                ullis.forEach(function(item,key){
                    item.className = '';
                    ollis[key].className = '';
                    // 给item,也就是ul中的li标签,定义属性
                    item.setAttribute('index',key);
                })

                // 2,给当前ul中的li,添加样式
                // 没有循环 当前的li是 e.target
                e.target.className = 'active';

                // 3,给对应的ol中的li,添加样式
                // 没有forEach循环,没有索引下标,获取标签中定义的属性的属性值
                ollis[e.target.getAttribute('index')].className = 'active';
            }         
        } 
    </script>

3. 拖拽效果边界值

<style>
        * {
            padding: 0;
            margin: 0;
        }

        body {
            height: 5000px;
        }

        .box {
            width: 800px;
            height: 800px;
            border: 10px solid #000;
            margin: 40px auto;
            position: relative;
            background: skyblue;
        }

        .inner {
            width: 100px;
            height: 100px;
            background: pink;
            position: absolute;
            top: 0;
            left: 0;
        }
    </style>
</head> 
<body>
    <div class="box">
        <div class="inner"></div>
    </div> 
    <script> 
        // 1,获取标签对象
        var oBox = document.querySelector('.box');
        var oInner = document.querySelector('.inner'); 
        
        // 2,获取相应的数据 
        // 获取父级标签的---占位---不包括边框线
        var oBoxWidth = oBox.clientWidth;
        var oBoxHeight = oBox.clientHeight;

        // 获取子级标签的---占位---包括边框线
        var oInnerWidth = oInner.offsetWidth;
        var oInnerHeight = oInner.offsetHeight;

        // 给父级标签添加事件
        oInner.onmousedown = function () {

            document.onmousemove = function (e) {

                // 获取计算,设定子级标签定位的数值

                // page坐标 - 外边距 - 边框线 - 子级宽度的一半
                var x = e.pageX - oBox.offsetLeft - oBox.clientLeft - oInnerWidth / 2;
                var y = e.pageY - oBox.offsetTop - oBox.clientTop - oInnerHeight / 2;

                // 设定极限值

                // 最小值是0
                if (x < 0) {
                    x = 0;
                }

                if (y < 0) {
                    y = 0;
                }

                // 最大值 
                // 父级标签占位(没有border) - 移动标签占位(计算border)
                if (x > oBoxWidth - oInnerWidth) {
                    x = oBoxWidth - oInnerWidth;
                }

                if (y > oBoxHeight - oInnerHeight) {
                    y = oBoxHeight - oInnerHeight
                }

                // 将设定好的数值,作为子级标签的定位
                oInner.style.left = x + 'px';
                oInner.style.top = y + 'px';
            }
        }

        window.onmouseup = function () {
            document.onmousemove = null;
        } 
    </script>

在这里插入图片描述

思路步骤和问题

  1. 事件,到底是绑定给 父级,子级,还是document,还是window
    事件,取消,到底是通过谁取消
    没有固定的写法,看你需要的效果
    还是document和window效果相同,没有区别

    鼠标按下
    oInner.onmousedown 鼠标在粉色div上,按下鼠标,并且移动鼠标,才会有效果
    oBox.onmousedown 鼠标在蓝色div上,按下鼠标,并且移动鼠标,才会有效果
    window.onmousedown 鼠标在全屏上,按下鼠标,并且移动鼠标,都会有效果

    鼠标移动
    最好写成 document.onmousemove / window.onmousemove
    鼠标可以快速移动,不怕移出粉色div

鼠标抬起
oInner.onmouseup 鼠标在粉色div上抬起,才会执行,标签不跟随移动
oBox.onmouseup 鼠标在蓝色div上抬起,才会执行,标签不跟随移动
window.onmouseup 鼠标在整个页面上抬起,都会执行,标签不跟随移动

  1. 闪烁问题
    原因: 相对于标签内容的左上角的定位
    会因为鼠标经过不同的标签对象,获取不同的数据
    而且JavaScript执行时,有时还会有bug产生
    offsetX offsetY 我们是不推荐使用的
    解决: 使用 pageX 和 pageY
    定位: page距离 - 父级标签外边距 - 父级border - 移动标签占位/2(标签中心点和鼠标重合)
    极值1: 左 上 都是 0
    极值2: 右 下 父级标签占位(不算border) - 移动标签占位(计算border)

4. 事件的监听

事件的监听

作用:
如果是普通的事件绑定,相同事件类型,只能绑定一个事件处理函数
如果同一个类型,绑定多个事件处理函数,后绑定的事件会覆盖之前绑定的事件
语法:
标签对象.addEventListener(事件类型 , 事件处理函数)
第三个参数: true / false(默认值)

事件的获取方式
冒泡 : 从子级开始,向父级执行
捕获 : 从父级开始,向子级执行

浏览器默认都是冒泡的执行方式
可以通过 addEventListener 第三个参数来设定获取方式
默认值 false 是 冒泡方式 true是捕获方式
一般实际项目中,不定义第三个参数,就使用默认方式
低版本IE,只支持冒泡,不支持捕获,不会报错,只会按照冒泡的顺序执行

今后给标签,绑定事件,推荐都使用 事件监听方式

        var oDiv1 = document.querySelectorAll('div')[0];
        var oDiv2 = document.querySelectorAll('div')[1];
        var oDiv3 = document.querySelectorAll('div')[2];

        // 普通事件绑定方式,只会执行最后一个绑定的事件处理函数
        // oDiv1.onclick = function(){
        //     console.log(123)
        // }
        // oDiv1.onclick = function(){
        //     console.log(456)
        // }
        // oDiv1.onclick = function(){
        //     console.log(789)
        // }

        // 事件监听方式

        // oDiv1.addEventListener('click' , function(){
        //     console.log(123);
        // })

        // oDiv1.addEventListener('click' , function(){
        //     console.log(456);
        // })

        // oDiv1.addEventListener('click' , function(){
        //     console.log(789);
        // })

        // 使用事件监听的方式,给父子级关系的标签,绑定事件
        oDiv1.addEventListener('click' , function(){
            console.log(1111)
        } , true)

        oDiv2.addEventListener('click' , function(){
            console.log(2222)
        } , true)

        oDiv3.addEventListener('click' , function(){
            console.log(3333)
        } , true)

5. 事件监听的兼容方式

兼容方式

普通浏览器
标签对象.addEventListener(‘事件类型’ , 事件处理函数)
事件类型必须是字符串形式,直接写事件类型名称,不能有on

低版本IE浏览器
标签对象.attachEvent(‘on事件类型’ , 事件处理函数)

<div id="div">123</div>
    <script>
        // 兼容方式

        // 普通浏览器
        // 标签对象.addEventListener('事件类型' , 事件处理函数)
        // 事件类型必须是字符串形式,直接写事件类型名称,不能有on

        // 低版本IE浏览器
        // 标签对象.attachEvent('on事件类型' , 事件处理函数)

         var oDiv = document.getElementById('div');

        // 一般的监听方式
        oDiv.addEventListener('click' , function(){
            console.log(123);
        })

        // 低版本IE浏览器
         oDiv.attachEvent('onclick' , function(){
             console.log(456);
         })   

        // 使用函数的方式,来做兼容处理
        // 参数1,要绑定的事件对象
        // 参数2,要绑定的事件类型
        // 参数3,要绑定的事件处理函数

        // 如果是特殊的事件类型,需要绑定,可以再单独写判断

        var oDiv = document.getElementById('div');
        
        myAddEvent(oDiv , 'click' , function(){console.log(123) } );

        function myAddEvent(ele,type,fun){
            if(ele.addEventListener){
                ele.addEventListener(type,fun)
            }else{
                ele.attachEvent( 'on'+type , fun)
            }
        }

6.事件监听的删除

 <div>123</div>
    <script>
        var oDiv = document.querySelector('div');
        var fun4 = function(){
            console.log('abc');
        }

        oDiv.addEventListener('click' , fun1);
        oDiv.addEventListener('click' , fun2);
        oDiv.addEventListener('click' , fun3);
        oDiv.addEventListener('click' , fun4);
        oDiv.addEventListener('click' , function(){console.log('别想删我')});

        // 可以删除
        oDiv.removeEventListener('click' , fun1);
        oDiv.removeEventListener('click' , fun4);
        // 不能删除
        oDiv.removeEventListener('click' , function(){console.log('别想删我')});

        // 注意:
        // 绑定时,必须是函数名称,或者存储函数的变量名称
        //         才能删除
        // 绑定时,如果直接定义函数,是不能删除的
        // 原因: 两个函数,程序相同,但是地址不同

        function fun1(){
            console.log(123);
        }

        function fun2(){
            console.log(456);
        }

        function fun3(){
            console.log(789);
        } 
    </script>

7.轮播图之运动函数1

运动函数
轮播图中,图片的切换,不是瞬间切换完成的
而是以类似于动画/运动的方式,逐步切换完成
将位移/定位效果,分多次,逐步完成

transition 虽然可以实现类似的效果
但是对于复杂的运动,复杂的设定,是不方便支持的
而且,transition过渡的兼容性,有待提高

通过JavaScript,配合 定时器 来逐步完成 运动效果

<style>
        *{
            margin: 0;
            padding: 0;
        }
        div{
            width: 100px;
            height: 100px;
            background: pink;
            position: fixed;
            top: 100px;
            left: 0px;
        } 
    </style>
</head>
<body>
    <button>点击</button>
    <div></div> 
	<script>  
        var oBtn = document.querySelector('button');
        var oDiv = document.querySelector('div');

        oBtn.addEventListener('click' , function(){
            // 定义的初始值
            var speed = 0;
            // 定时器
            var time = setInterval(function(){
                // 每次初始值,增加一个数值
                speed += 10;
                // 将这个数值定义为定位的数值
                oDiv.style.left = speed + 'px';
                // 当数值达到规定的数值时,清除定时器,终止执行
                // 运动也就终止了
                if(speed == 500){
                    clearInterval(time);
                }                
            } , 30)

        })

    </script>

8.轮播图之事件函数2

<style>
        * {
            margin: 0;
            padding: 0;
        }

        div {
            width: 100px;
            height: 100px;
            background: pink;
            position: fixed;
            top: 100px;
            left: 200px;
            transition: all 3s;
        }
    </style>
</head> 
<body>
    <button>点击</button>
    <div></div> 
    <script>
        // 解决第一个问题
        // 封装成一个函数的形式
        // 如果有初始位置,怎么办?

        // 参数1,要运动的标签
        // 参数2,要运动的方向/方式 以及 目标位置
        //       一般,目标位置与运动方式是相关的,定义对象的形式
        //       { 方式 : 位置 }  {left : 500}

        // 获取标签对象
        var oDiv = document.querySelector('div');
        var oBtn = document.querySelector('button');

        // 不愿意写点击事件,直接执行也可以
        // move(oDiv,{left:500});

        // 执行函数
        // 给按钮绑定点击事件
        // 执行的函数,是调用move()函数,并且赋值参数

        // 注意:不能在 addEventListener 参数2的位置上,直接定义move()
        oBtn.addEventListener('click', function(){ move(oDiv,{left:500}) });
        // 直接写move函数,是直接调用move函数,不是绑定move函数
        // oBtn.addEventListener('click', move() );

        function move(ele, obj) {
            // 先通过for...in循环,来调用参数2,获取其中的执行属性和目标位置的数值
            // 目前是有obj中,有一个单元,会循环一次,生成left对应的定时器
            // 如果有obj中,有多个单元,会循环多次,生成每一个属性对应的定时器
            // 这样,每一个属性都有自己对应的定时器,便于控制和观察运动状态

            // type中存储的是,obj对象的键名,也就是left
            for(var type in obj) {
                // 初始位置,需要获取标签原始定位的数值
                // 参数2中,定义的运动属性,是谁,现在对应的就获取谁的初始数值
                // {left:500},就获取left属性对应的初始值
         
                // window.getComputedStyle 获取标签的css样式的属性值
                // 语法: window.getComputedStyle(标签对象).属性
                // 这里的属性是存储在type自定义变量中的,必须要用[]语法来解析
                var speed = parseInt(window.getComputedStyle(ele)[type]) ;
                // 定时器,每次循环都会生成一个新的定时器
                var time = setInterval(function(){
                    // 初始值,加上数值
                    speed += 20;
                    // 将数值作为定位的数据
                    // 点语法,不能解析变量,必须使用[]语法,解析存储的变量
                    // 设定 标签 css , 语法是 标签对象.style[属性] = 属性值
                    // type是for...in循环中,自定义的变量,用来存储对象的键名
                    // 要使用时,type是变量, 对象.变量,不能解析,只能使用对象[变量]才能解析变量
                    ele.style[type] = speed + 'px';

                    // 当数值,达到目标值的时候,来停止定时器
                    // obj是参数2,{left:500}
                    // 这个500使我们的目标数值
                    // 获取500这个数值,语法是 对象[属性]
                    // 属性存储在变量type中,必须要[]语法才能及解析
                    if (speed == obj[type]) {
                        clearInterval(time);
                    }
                }, 100);
            }
        } 
        // 对象的操作
        // 点语法只能直接写属性
        // var obj = {name:'张三'};

        // console.log(obj.name);

        // []语法,可以写属性,要有引号
        //        也可以写变量,能解析变量,不用写引号
        // var str = 'name'
        // console.log(obj[str]);

http://www.niftyadmin.cn/n/4827478.html

相关文章

[改善Java代码]推荐在复杂字符串操作中使用正则表达式

一、分析 字符串的操作&#xff0c;诸如追加、合并、替换、倒序、分隔等&#xff0c;都是在编码过程中经常用到的&#xff0c;而且Java也提供了append、replace、reverse、split等方法来完成这些操作&#xff0c;它们使用起来确实方便&#xff0c;但是更多的时候&#xff0c;需…

Python3的time模块的使用

import time# 1.time() print( python诞生总时间&#xff08;1970&#xff09;&#xff1a;, time.time())# 2.asctime() print(当前时间&#xff1a;, time.asctime()) # 当前时间# 3.ctime() print(当前时间&#xff1a;, time.ctime())# 4.gmtime() print(接收时间戳(格林威…

JS 动画

纵向展开 <style>*{margin: 0;padding: 0;}div{width: 100px;height: 100px;background: rgb(9, 175, 9);position: fixed;top: 100px;left: 0px;overflow: hidden;} button{height: 30px;width: 50px;margin: 30px;}</style> </head> <body><butt…

JS 运动函数 轮播图

1. 复制标签的语法 <ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul><script>// 复制标签的方式// clone 方式var ul document.querySelector(ul);// 获取标签var li1 document…

Python3的re模块的使用

import re# 2元字符 . ^ $ * ? { } [ ] | ( ) \ # 作用&#xff1a;匹配字符串s hello world # 返回开始位置 下标 print(s.find(llo))# 找到 并替换 print(s.replace(ll, xx))# . 代指一位字符&#xff0c;代指所有字符 除了换行符 \n ci re.findall(w\w{2}l, hello world…

如何在Linux下环境下快速切换工作目录

为什么80%的码农都做不了架构师&#xff1f;>>> 在Linux命令行下&#xff0c;我们经常需要在一个目录下执行某些操作在跳转到另外的目录下&#xff0c;也就是使用我们熟悉的cd命令&#xff0c;基本上接触过命令行的人&#xff0c;第一个认识的命令都是cd&#xff0…

JS 节点 正则表达式

1. 节点操作 基本概念 复制标签,会使用克隆方法 写入标签时,会使用节点操作方法 什么是节点? 整个的HTML文件,其中的所有内容,都视为HTML文件的一个节点对象 可以通过操作这些节点对象,来操作HTML文件 DOM节点:DOM 就是我们 html 结构中一个一个的节点构成的 不光我们的标签…

Python3的random模块的使用

import randomprint(random.random()) # 默认限制在0-1的小数print(random.randint(1, 8)) # 1-8的整数 包含1和8print(random.choice(joe smith)) # 随机选择一个字符print(random.choice([joe, smith])) # 元组中随机选择print(random.randrange(1, 3)) # 1-3的整数&…