前端学习:js实现倒计时,拖拽事件,防抖,节流,懒加载,图片的onload事件,lazyload插件的使用,上传头像

1.倒计时:

        设置一个定时器,每秒执行一次函数(将改变倒计时的时间封装为一个函数),利用时间戳的差值得到剩余的总毫秒数对其运算得到对应剩余的天数,时,分,秒,对得到的数据用parseInt()取整,还有补零,最后将数据追加到相应的元素内容中

    <div>
        <h1>距离2023年春节: <span>xxx天  xx 时  xx 分 xx秒</span></h1>
    </div>

    <script>
        var yearOfDate = new Date("2023-1-22").getTime();

        setInterval(() => {
           
            distance();

        }, 1000);
        
        distance();

        function distance() {
            var now = Date.now();
            var offsetTime = (yearOfDate - now) / 1000;
            // 获取天数据
            var day = parseInt(offsetTime / (24 * 60 * 60));
            // 时
            // var hours = offsetTime % (24*60*60) / (60 * 60);

            var hours = parseInt((offsetTime / (60 * 60) ) % 24);
            // 分
            var minutes = parseInt(offsetTime / 60 % 60);
            // 秒
            var seconds =  parseInt(offsetTime % 60);

            document.querySelector('span').innerText = `${addZero(day)} 天${addZero(hours)} 时 ${addZero(minutes)} 分 ${addZero(seconds)} 秒`;
        }
        // 补零
        function addZero(num) {
            return num > 10 ? num : "0" + num;
        }

    </script>

2.拖拽事件

        指定了draggable属性的元素,才可以完成拖拽

                <div class="move" draggable="true"></div>

开始拖拽事件

document.querySelector('.move').ondragstart=function(){

        //可对拖拽的对象设置传输数据,方便在目标元素的丢事件中得到对应的对象,将

        //其添加到目标对象中

        //transfer 传输

        //p1:  key    p2:value

        event.dataTransfer.setData("tdata",this.classname);

}

持续拖拽事件

 move.ondragover = function () {

            console.log("持续拖拽中.....");

        }

结束拖拽事件:

        move.ondragend = function () {

            console.log("结束拖拽");

        }

目标元素的拖拽事件

进入:

document.querySelector('.box').ondragenter=funtion(){}

离开:

document.querySelector('.box').ondragleave=funtion(){}

drop丢进事件:

        ondrop事件要想执行,

                1.必须要给当前元素在ondragover事件中阻止默认事件

box.ondragover = function() {

            event.preventDefault();

        }

                2.或给html元素在ondragover事件中阻止默认事件

 document.documentElement.ondragover = function () {

            event.preventDefault();

        }

document.querySelector('.box').ondrop=funtion(){

        //阻止外部文件拖入该元素 会在新窗口中打开

        event.preventDefault();

        

        //可将拖拽元素直接追加到该目标元素中

        //this.appendChild(move);

        

        //利用拖拽元素在开始拖拽事件中传输的数据,将其用key获取到该元素再对其进行

        //追加操作

            let data = event.dataTransfer.getData("tdata");

            var el = document.querySelector('.'+data);

            this.appendChild(el);

}

3.表格的拖拽

首先找到表格中所有所要的拖拽的对象trs,对其进行遍历添加可拖拽属性 (el.draggable = true;);在开始拖拽事件中设置传输数据,方便下面找到拖拽对象,利用冒泡给tbody添加ondrop丢事件,首先根据event.dataTransfer.getData('key')找到拖拽对象再根据事件的触发者找到其父元素的下一个节点,再tbody的insertBefore()方法实现表格的插入( tbody.insertBefore(dragEl,targetEl);)。

 <script>

        var trs = document.querySelectorAll("tr:not(:first-child)");

        var tbody = document.querySelector('tbody');      

        trs.forEach((el,index) => {

            el.draggable = true;//遍历添加可拖拽属性

            el.className = "t" + index;

            el.ondragstart = function () {

                event.dataTransfer.setData("move",this.className);//通过设置传输数据(key-value),方便下面通过类名找到拖拽对象

            }

        });

        document.documentElement.ondragover = function () {

            event.preventDefault();//阻止html的ondragover的默认事件

        }

        tbody.ondrop = function () {

            // 1.获取拖动的元素

            var cname = event.dataTransfer.getData("move");

            var dragEl = document.querySelector("."+cname);

            console.log("dragEl  = ",dragEl);

           

            // 2.目标元素 (放在谁的身上)

            var targetEl = event.target.parentElement.nextElementSibling;

            console.log("targetEl  = ",targetEl);

            if(targetEl == dragEl){

                targetEl = event.target.parentElement;

            }


 

            // 把a插入在b的前面

            // 如果b元素为空  则把a添加在 tbody的末尾

            tbody.insertBefore(dragEl,targetEl);

        }    

    </script>

4.函数的防抖和节流-------优化浏览器的性能

        利用settimeout   降低事件的执行频率

4.1  防抖(debounce):当一个动作连续触发,只执行最后一次

连续的事件,只需触发一次回调的场景有:

搜索框搜索输入。只需用户最后一次输入完,再发送请求

手机号、邮箱验证输入检测

窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染

  <input type="text" id="input">
    <script>

        // 1.函数的防抖  多次触发 只执行最后一次
        // 先清除timer 再创建timer
        // var timer = null;
        // input.oninput = function () {
        //     clearTimeout(timer);
        //     // 会影响性能 每次都会执行发送网络请求
        //     // console.log("发起网络请求");
        //     timer = setTimeout(() => {
        //         console.log("发起网络请求");
        //     }, 1000);
        // }


        // 这样写是不可以的  因为debounce返回的是undefined  
        // 给input oniput 赋值undefined 
        // 后续的输入不会执行任何代码
        // var timer  = null;
        // input.oninput = debounce(function () {
        //     console.log("发起网络请求")
        // },1000)

        // function debounce(cb,wait) {
        //     clearTimeout(timer);
        //     timer = setTimeout(() => {
        //         if(typeof cb == "function"){
        //             cb();
        //         }
        //     }, wait);
        // }


        // 1.
        // var timer = null;
        // input.oninput = function () {
        //     debounce(function () {
        //         console.log("发起网络请求")
        //     }, 1000);
        // }
        // function debounce(cb, wait) {
        //     clearTimeout(timer);
        //     timer = setTimeout(() => {
        //         if (typeof cb == "function") {
        //             cb();
        //         }
        //     }, wait);
        // }

        

        // 2.debounce  返回时一个函数 赋值给我 oninput事件
        var timer = null;
        input.oninput = debounce(function () {
            console.log("发起网络请求")
        }, 1000)
        function debounce(cb, wait) {
            return function () {
                clearTimeout(timer);
                timer = setTimeout(() => {
                    if (typeof cb == "function") {
                        cb();
                    }
                }, wait);
            }
        }

    </script>

4.2  节流(throttle):限制函数在一定时间内只执行一次

函数节流的应用场景

间隔一段时间执行一次回调的场景有:

滚动加载,加载更多或滚到底部监听

高频点击提交,表单重复提交

下拉加载更多

    <input type="text" id="input">
    <script>
        // 节流  规定时间内只执行一次
        // 定义全局变量  bool

        // 1.
        // var isStart = true;

        // input.oninput = function () {
        //     if (isStart) {
        //         isStart = false;
        //         setTimeout(() => {
        //             console.log("发起网络请求");
        //             isStart = true;
        //         }, 2000)
        //     }
        // }


        // 2.
        // 
        // var timer = null;
        // input.oninput = function () {
        //     if (timer) return;
        //     timer = setTimeout(() => {
        //         console.log("发起网络请求");

        //         timer = null;
        //     }, 2000);
        // }


        // 3.通过时间戳

        input.oninput = fn(function () {
            console.log("发送网络请求");
        },2000);

        function fn(cb,wait) {
            // 记录第一次的时间
            var previous = Date.now();//3
            console.log(previous)
            return function () {
                var current  = Date.now();//6
                if(current - previous >= wait){
                    if(typeof cb === "function"){
                        cb();
                        previous = current;
                    }
                }
            }
        }

    </script>

5.懒加载--优化网页性能

懒加载是一种对网页性能优化的方式,比如当访问一个页面的时候,优先显示可视区域的图片而不一次性加载所有图片,当需要显示时,再发送图片请求,避免打开网页时加载过多资源。
当一个网站的加载图片过多时就需要懒加载的协助,页面图片多时,在首次载入时一次性加载会耗费时间长,使用懒加载可以使页面加载速度快、减轻服务器的压力、节省流量。
 图片懒加载的 逻辑  先找一个较小的图代替 当需要显示时把自定义属性的真实路径赋予图片的src实现懒加载的效果

        原理: 滚动的 + 可视的 > 图片距离顶部的   替换src

 <img src="./img/loading.gif" alt="" data-src="./img/1.jpg">
    <script>
        var img = document.querySelector("img");
        var screenHeight = document.documentElement.clientHeight;
        var imgTop = img.offsetTop;

        window.onscroll = function () {
            var sTop = document.documentElement.scrollTop;
            if(sTop  + screenHeight > imgTop + 500){
                img.src = img.dataset.src;
            }
        }

图片的onload事件:  

        如果没有将获取图片的高度放入  onload事件中  默认为21px

        原因是资源还没有加载  代码已经执行结束  

        行内元素默认高度为21px  

可将懒加载函数放在window的onload事件中,或给图片直接设置好高

 document.querySelector('img').onload = function () {
            console.log(document.querySelector("div").clientHeight);
        };

lazyload插件的使用:

 <!-- 1.引入  lazyload 插件 -->

    <script src="./lazyload.min.js"></script>

    <script>

        window.onload = function () {

            var imgs = document.querySelectorAll("img");

            for (let i = 0; i < imgs.length; i++) {

                var img = imgs[i];

                img.dataset.src = `./img/${i + 1}.jpg`;

                // 2.指定类名

                img.className = "lazyload";

            }

            //3.在onload中调用  lazyload方法

            lazyload();

           

        }

6.上传头像

在头像框的盒子里,添加type为file的input,给input加上accept属性,其值设为image/*,

        <input type="file" name="" id="" accept="image/*">

将 input 用display:none;隐藏,给头像框的盒子绑定点击事件,用 input.click(); 触发 input的click事件,然后给input绑定onchange事件,里面再根据file对象来生成url地址,再将地址赋给框的背景图的地址

    <p>上传头像:</p>
    <div>
        <span class="mask">
            <span class="iconfont icon-shangchuan"></span>
            上传头像
        </span>
        <!-- accept 只有file类型可以使用  image/ 接受所有的图片类型  -->
        <input type="file" name="" id="" accept="image/*">
    </div>
    <script>
        var div = document.querySelector('div');
        var input = document.querySelector('input');
        var mask = document.querySelector('.mask');


        div.onclick = function () {
            input.click(); // 触发 input的click事件
        }
        input.onchange = function () {
            console.log(event.target.files[0]);
            var file = event.target.files[0];
            // 根据file对象来生成url地址
            var url = URL.createObjectURL(file);
            mask.style.display = "none";
            div.style.backgroundImage = `url(${url})`;

        }

    </script>

        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值