• 你好javascript day20


    1)预加载

    一张图片的加载

    let img=new Image();//构造函数

    img.addEventListener("load",loadHandler);//事件侦听

    img.src="./img/3-.jpg";//标签直接引入

    document.body.appendChild(img);//dom操作创建子元素

    console.log(img.offsetWidth);

    load事件侦听回调函数

    function loadHandler(e){

    console.log(img.width);

    }

    创建多张图片:循环创建并添加侦听

    for(let i=3;i<80;i++){

     let img=new Image();

    img.addEventListener("load",loadHandler);

    img.src=`./img/${i}-.jpg`;

    }

    function loadHandler(e){

    console.log(e.currentTarget.width,e.currentTarget.src);

    }

    工作流程:

    1.首先加载第一张图片

    2.侦听load事件,当完成加载,把图片放在数组中,并且打印图片宽度和地址

    3.执行message函数,增加num,通知继续加载

    4.收到通知就会继续加载内容,因为num已经改变了,所以加载最新的

    //图片初始num
    let num=3;
    //空数组存放图片地址
    let arr=[];
    //侦听全局图片加载
    document.addEventListener("startLoad",loadImage);
    loadImage();
    function loadImage(){
    let img=new Image();
    img.addEventListener("load",loadHandler);
    img.src=`./img/${num}-.jpg`;
    }
    function loadHandler(e){
    arr.push(e.currentTarget);
    console.log(e.currentTarget.width,e.currentTarget.src);
    message();
    }
    
    function message(){
    num++;
    if(num>79){
    return;
    }
    let evt=new Event("startLoad");
    document.dispatchEvent(evt);
    }

     当加载完成,改变num,然后重新调用loadImage

    let num=3;
    let arr=[];
    loadImage();
    function loadImage(){
    let img=new Image();
    img.addEventListener("load",loadHandler);
    img.src=`./img/${num}-.jpg`;
    }
    function loadHandler(e){
    arr.push(e.currentaTarget);
    num++;
    if(num>79){
    //这是最后一次展现
    arr.forEach(function(item){
    console.log(item.width,item.src);
    })
    init(arr);
    return;
    }
    e.currentTarget.src=`./img/${num}-.jpg`;
    }

    //把代码写在函数外,意味着刚一开始就会同步执行所有内容
    //但是有时候我们需要在代码执行之前先执行某些内容,这些内容可以是异步的
    //需要一定的时间处理,不能一开始就同步执行所有内容,因此我们会把这些代码
    //放在初始执行函数中,一旦需要异步执行某些内容时,只需要执行完调用init就可以了
    function init(){}

     2)懒加载

        <script>
            let width;
            let clientWidth;
            // list是存储所有li的DOM元素数组
            let list=[],
            // 每个li里面所有内容的高度
                heightList=[],
                num=3
            const COL=5;
            const GAP=10;
            init();
            function init(){
                document.body.style.margin="0px";
                let ul=ce("ul",{
                    listStyle:"none",
                    margin:"0px",
                    padding:"0px"
                });
                clientWidth=document.documentElement.clientWidth;
                width=(clientWidth-(COL-1)*GAP-1)/COL;
                for(let i=0;i<COL;i++){
                    let li=ce("li",{
                        float:"left",
                        width+"px",
                        marginLeft:i===0 ? "0px" : GAP+"px",
                        // backgroundColor:"#"+Math.floor(Math.random()*0x1000000).toString(16).padStart(6,"0")
                    });
                    // 初始默认值是0
                    heightList.push(0);
                    ul.appendChild(li);
                    list.push(li);
                }
                document.body.appendChild(ul);
                loadImage();
                window.addEventListener("resize",resizeHandler);
                document.addEventListener("scroll",scrollHandler);
            }

            function loadImage(){
                let img=new Image();
                img.addEventListener("load",loadHandler);
                img.src=`./img/${num}-.jpg`;
            }
            function loadHandler(e){
                this.removeEventListener("load",loadHandler);
                let scale=this.height/this.width;
                let height=scale*width;
                this.style.width=width+"px";
                this.style.height=height+"px";
                this.scale=scale;
                let min=Math.min.apply(null,heightList);
                let index=heightList.indexOf(min);
                list[index].appendChild(this);
                heightList[index]+=height;
                if(clientWidth!==document.documentElement.clientWidth){
                    clientWidth=document.documentElement.clientWidth;
                    resizeHandler();
                }
             
                // if(num>79){
                //     return;
                // }
                // console.log(document.body.scrollHeight>document.documentElement.clientHeight*2);
                if(document.body.scrollHeight>document.documentElement.clientHeight*4){
                    return;
                }
                num++;
                if(num>79) num=3;
                loadImage();
            }

            function scrollHandler(e){
                if(document.documentElement.scrollHeight-document.documentElement.scrollTop<document.documentElement.clientHeight*2){
                    num++;
                    if(num>79)num=3;
                    loadImage();
                }
            }
         

            function ce(type,style){
                let elem=document.createElement(type);
                Object.assign(elem.style,style);
                return elem;
            }

            function resizeHandler(e){
                width=(document.documentElement.clientWidth-(COL-1)*GAP-1)/COL;
                for(let i=0;i<list.length;i++){
                    list[i].style.width=width+"px";
                    for(let j=0;j<list[i].children.length;j++){
                        let img=list[i].children[j];
                        img.style.width=width+"px";
                        img.style.height=width*img.scale+"px";
                    }
                }
            }

            
        </script>
     //瀑布流
        <script>
            var width;
            var clientWidth;
            // list是存储所有li的DOM元素数组
            var list = [],
                // 每个li里面所有内容的高度
                heightList = [],
                num = 3
            const COL = 5;
            const GAP = 10;
            init();

            function init() {
                document.body.style.margin = "0px";
                document.documentElement.style.fontSize = "100px";
                var ul = ce("ul", {
                    listStyle: "none",
                    margin: "0px",
                    padding: "0px"
                });
                clientWidth = screen.width;
                width = (clientWidth - (COL - 1) * GAP - 1) / COL / 100;
                for (var i = 0; i < COL; i++) {
                    var li = ce("li", {
                        float: "left",
                         width + "rem",
                        marginLeft: i === 0 ? "0px" : GAP / 100 + "rem",
                        // backgroundColor:"#"+Math.floor(Math.random()*0x1000000).toString(16).padStart(6,"0")
                    });
                    // 初始默认值是0
                    heightList.push(0);
                    ul.appendChild(li);
                    list.push(li);
                }
                document.body.appendChild(ul);
                loadImage();
                window.addEventListener("resize", resizeHandler);
            }

            function loadImage() {
                var img = new Image();
                img.addEventListener("load", loadHandler);
                img.src = `./img/${num}-.jpg`;
            }

            function loadHandler(e) {
                this.removeEventListener("load", loadHandler);
                var scale = this.height / this.width;
                var height = scale * width;
                this.style.width = width + "rem";
                this.style.height = height + "rem";
                this.scale = scale;
                var min = Math.min.apply(null, heightList);
                var index = heightList.indexOf(min);
                list[index].appendChild(this);
                heightList[index] += height;
                if (clientWidth !== document.documentElement.clientWidth) {
                    clientWidth = document.documentElement.clientWidth;
                    resizeHandler();
                }
                num++;
                if (num > 79) {
                    return;
                }
                loadImage();
            }


            function ce(type, style) {
                let elem = document.createElement(type);
                Object.assign(elem.style, style);
                return elem;
            }

            function resizeHandler(e) {
                var scale = (document.documentElement.clientWidth - 1) / screen.availWidth;
                document.documentElement.style.fontSize = scale * 100 + "px";
            }
        </script>

     4)轮播图

    //css  样式
    <style>
    .leftMove{
      animation:leftMove 0.5s;
    
    }
    .rightMove{
      animation:rightMove 0.5s;
    }
    @kryframes leftMove{
    0%{
    left:0
    }
    100%{
      left:-1500px;
    }
    }
    @keyframes rightMove{
      0%{
      left:-1500px;
    }
    100%{
    left:0px;
    }
    }
    </style>//JS 部分
    
    
        <script>
            // 1、布局
            // 2、定义当前第几张图片和应该向什么方向运动
            // 3、将需要放置的图片根据方向放在前面或者后面
            // 4、将整个容器向左或者向右移动,
            // 5、完成后将上一次的图片删除

            // imgCon  放置所有图片的容器
            // dotList 放置小圆点列表
            // bnList  放置左右按钮的数组
            // imgList  放置所有图片的数组
            // pos是确定当前是第几个图片
            // direction 图片运行的方向
            // imgSrcList 存储轮播图图片地址的数组
            var imgCon, ul, preDot;
            var pos = 0,
                x = 0,
                bool = false,
                autoBool = false,
                dotList = [],
                imgList = [],
                bnList = [],
                time = 300,
                num = 0,
                imgSrcList = ["./img/a.png", "./img/b.png", "./img/c.png", "./img/d.png", "./img/e.png"]
            direction = "";
            const WIDTH = 1500;
            const HEIGHT = 500;
            const SPEED = 40;
            const LEFT = Symbol();
            const RIGHT = Symbol();


            /* loadImage();
            function loadImage(){
                var img=new Image();
                img.addEventListener("load",loadHandler);
                img.src=imgSrcList[0];
            }

            function loadHandler(e){
                // this是当前加载的图片,将这个图片复制一个新的DOM图片
                var m=this.cloneNode(false);
                m.style.width=WIDTH+"px";
                m.style.height=HEIGHT+"px";
                imgList.push(m);
                num++;
                if(num>imgSrcList.length-1){
                    this.removeEventListener("load",loadHandler);
                    init();
                    return;
                }
                this.src=imgSrcList[num];
            } */

            Utils.loadImage(imgSrcList, init);

            /* 
                init  初始化函数
               1、 创建轮播图的外层容器
               2、创建轮播图图片容器
               3、创建按钮列表
               4、创建小圆点列表
               5、将轮播图容器放在body中
               6、切换小圆点,因为当前是第0张,所以就会让第0个小圆点变红
               7、将小圆点容器水平居中
               8、设置时间间隔,每16毫秒执行animation函数一次,因为一秒是1000毫秒
               一秒中执行60次,就是60帧频,每次花费的时间是16.6666毫秒
               9、给外层的轮播图增加事件侦听,一个鼠标进入,一个是鼠标离开
             */
            function init(list) {
                imgList = list;
                list.forEach(item => {
                    item.style.width = WIDTH + "px";
                    item.style.height = HEIGHT + "px";
                })
                var carousel = ce("div", {
                     WIDTH + "px",
                    height: HEIGHT + "px",
                    position: "relative",
                    margin: "auto",
                    overflow: "hidden"
                });
                createImgCon(carousel);
                createButton(carousel);
                createDotList(carousel)
                document.body.appendChild(carousel);
                changeDot();
                ul.style.left = (WIDTH - ul.offsetWidth) / 2 + "px";
                setInterval(animation, 16);
                carousel.addEventListener("mouseenter", mouseHandler);
                carousel.addEventListener("mouseleave", mouseHandler);
            }

            /* 
                轮播图进入和离开的事件函数
                1、如果进入轮播图,设置自动轮播的开关是false,就不会自动轮播
                    并且重新将计时设为300
                2、如果离开轮播图,设置自动轮播开关是true,就会自动轮播了
            
            
             */
            function mouseHandler(e) {
                if (e.type === "mouseenter") {
                    autoBool = false;
                    time = 300;
                } else if (e.type === "mouseleave") {
                    autoBool = true;
                }
            }

            /* 
                创建轮播图容器和图片
                参数 
                   parent  父容器,  元素类型  将创建好的容器和图片放在这个父容器内
                1、创建图片容器,宽度是2张图片宽度
                2、根据所有轮播图地址数组创建所有图片,并且放在数组imgList中
                3、将第0张图片放在创建图片容器imgCon中
                4、将图片容器放在轮播图容器中
             */
            function createImgCon(parent) {
                imgCon = ce("div", {
                    position: "absolute",
                     2 * WIDTH + "px",
                    height: HEIGHT + "px",
                    left: 0
                });

                imgCon.appendChild(imgList[0]);
                parent.appendChild(imgCon);
            }

            /*
                 创建左右按钮
                参数 
                   parent  父容器,  元素类型  将创建好的按钮放在这个父容器内
                1、创建按钮地址数组
                2、循环这个地址数组,创建所有图片,并且放置对应的位置
                3、设置图片的地址
                4、将按钮图片放在轮播图容器中
                5、给左右按钮增加点击事件执行函数bnClickHandler
              */
            function createButton(parent) {
                var arr = ["left", "right"];
                for (var i = 0; i < arr.length; i++) {
                    var img = ce("img", {
                        position: "absolute",
                        // (外容器高度-当前图片高度)/2 垂直居中
                        top: (HEIGHT - 60) / 2 + "px",
                        // 如果是第0张图片,左边按钮,让他居左50像素,否则是none
                        left: i === 0 ? "50px" : "none",
                        // 如果是第1张图片,右边按钮,让他居右50像素,否则是none
                        right: i === 1 ? "50px" : "none"
                    });
                    img.src = `./img/${arr[i]}.png`;
                    parent.appendChild(img);
                    bnList.push(img);
                    img.addEventListener("click", bnClickHandler);
                }
            }


            /* 
            
                  创建小圆点
                参数 
                   parent  父容器,  元素类型  将创建好的小圆点放在这个父容器内
                 1、创建ul,设置样式
                 2、根据图片地址的数组,循环若干次,有多少图片就循环多少次创建小圆点
                 3、将每一个小圆点存在数组dotList中
                 4、将小圆点放在ul中
                 5、给ul增加点击事件,事件是点击小圆点,事件委托
             */
            function createDotList(parent) {
                var ulstyle = {
                    listStyle: "none",
                    margin: 0,
                    padding: 0,
                    position: "absolute",
                    bottom: "50px"
                }
                ul = ce("ul", ulstyle);
                for (var i = 0; i < imgSrcList.length; i++) {
                    var dot = ce("li", {
                         "28px",
                        height: "28px",
                        borderRadius: "50%",
                        border: "2px solid #FF0000",
                        float: "left",
                        marginLeft: i === 0 ? "0px" : "15px"
                    });
                    dotList.push(dot);
                    ul.appendChild(dot);
                }
                // dotList=Array.from(ul.children);
                parent.appendChild(ul);
                ul.addEventListener("click", dotClickHandler);
            }

            /* 
                点击左右按钮事件函数
                e   点击事件  MouseEvent
                e.target 是被点击的按钮图片
                如果bool是true,也就是当前轮播图正在播放时,点击按钮跳出,不继续执行
                1、判断被点击图片的地址里面是否包含有left.png字符串,
                  如果有,就是点击左侧按钮,反之是右按钮
                2、如果点击了左侧按钮,当前图片下标-1,如果小于0,
                    就让他为当前图片地址数量-1,也就是最大应该有图片下标
                   并且设置方向是向右运动
                3、如果点击了右侧按钮,当前图片下标+1,如果大于前图片地址数量-1,
                    就让他为0,回到最开始第0张图片
                   并且设置方向是向左运动
             */
            function bnClickHandler(e) {
                if (bool) return;
                if (e.target.src.includes("left.png")) {
                    pos--;
                    if (pos < 0) pos = imgSrcList.length - 1;
                    direction = RIGHT;
                } else {
                    pos++;
                    if (pos > imgSrcList.length - 1) pos = 0;
                    direction = LEFT;
                }
                createNextImg();
            }

            /* 
                小圆点点击事件函数
                e   鼠标事件对象  MouseEvent
                 e.target 是鼠标点击的目标
                 因为使用时事件委托,因此判断点击目标是不是li,如果不是就跳出
                   如果bool是true,也就是当前轮播图正在播放时,点击按钮跳出,不继续执行
                 1、判断点击目标是否是li,不是跳出
                 2、获取当前点击的小圆点是数组中第几个
                 3、如果当前的点击小圆点的下标和当前展示图片的下标相同时,跳出不处理
                 4、如果大于当前展示图片的下标,方向设为向左运动,反之向右
                 5、将当前点击的下标设为当前应展现图片的下标
            
             */
            function dotClickHandler(e) {
                if (bool) return;
                // if(e.target.nodeName!=="LI") return;
                if (e.target.constructor !== HTMLLIElement) return;
                var index = dotList.indexOf(e.target);
                if (index === pos) return;
                direction = index > pos ? LEFT : RIGHT;
                pos = index;
                createNextImg();
            }


            /* 
                创建下一张需要显示图片
                当点击左右按钮和当点击小圆点时,触发该函数
                1、如果方向向左运动,给图片容器尾部添加新的图片
                2、如果方向向右运动,给图片容器的最头部添加新图片,
                但是这时候原图被挤到后面,我们将这个容器向左挪动一个宽度位置
                3、设置完成后,设置bool是true,这时候就打开了动画的播放开关
                动画就可以完成播放了
                4、切换当前小圆点
            
             */
            function createNextImg() {
                // console.log(direction,pos,imgList[pos]);
                if (direction === LEFT) {
                    imgCon.appendChild(imgList[pos]);
                    x = 0;
                    imgCon.className = "leftMove";
                    var ids = setTimeout(function () {
                        clearTimeout(ids);
                        imgCon.firstElementChild.remove();
                        imgCon.className = "";
                        imgCon.style.left = "0px";
                    }, 490)
                } else if (direction === RIGHT) {
                    imgCon.insertBefore(imgList[pos], imgCon.firstElementChild);
                    imgCon.style.left = -WIDTH + "px";
                    x = -WIDTH;
                    imgCon.className = "rightMove";
                    var ids = setTimeout(function () {
                        imgCon.lastElementChild.remove();
                        imgCon.className = "";
                        imgCon.style.left = "0px";
                        clearTimeout(ids);
                    }, 490)
                }
                changeDot();
            }

            /* 
                切换小圆点
                preDot是对上一次小圆点的引用变量
                刚开始第一次时,没有这个引用,因此不执行,并且设置第一次设置了第0个小圆点
                更改了第0个小圆点的背景色
                第二次进来时,上次小圆点的引用时第0个小圆点,所以就将上次小圆点修改背景透明
                将本次小圆点设置给这个引用,并且修改背景色
                这样再次进入时就可以修改原来的,设置新的
             */
            function changeDot() {
                if (preDot) {
                    preDot.style.backgroundColor = "rgba(255,0,0,0)";
                }
                preDot = dotList[pos];
                preDot.style.backgroundColor = "rgba(255,0,0,0.5)";
            }

            /* 
                创建元素
                参数:
                   type   创建元素的类型  字符串
                   style  创建元素的样式  对象  使用对象方式给出所有该元素的样式
                  1、根据类型创建元素
                  2、将给入的样式设置给元素的行内样式
                  3、返回创建好的元素 
            
             */
            function ce(type, style) {
                var elem = document.createElement(type);
                // ES6的方法   将后面的对象中的属性复制到前面对象中
                Object.assign(elem.style, style);
                return elem;
            }

            /* 
                每16毫秒执行该函数一次
                1、执行imgConMove这个函数,这是让图片移动方法
                2、执行自动轮播
            
             */
            function animation() {
                // imgConMove();
                autoPlay();
            }

            /* 
                每16毫秒让图片移动一次
                开始的时候就一直运行,因为有一个bool值判断,如果是false时,一直就不能进入
                如果可以进入
                1、如果方向向左
                   不断让变量x递减,每16毫秒减40像素,设置图片容器位置,图片容器就可以移动了
                   当图片容器的第一张图完全移动到最左侧以后,也就是x小于等于负的图片宽度
                   设置bool是false,16毫秒后进入时直接跳出,并且删除掉移到最左侧的图片,
                   这时候后面的图片就会补充到最前面,因此我们设置将这x为0,让整个容器向后
                   挪回初始位置
                2、如果方向向右
                x不断增加40像素
                如果x大于0,表示左侧的图片已经移到中间位置,原图片移到了右侧
                这时候停止运动,bool设为false,x设为初始的0,删除右侧的图片
             */
            function imgConMove() {
                if (!bool) return;
                if (direction === LEFT) {
                    x -= SPEED;
                    if (x <= -WIDTH) {
                        imgCon.firstElementChild.remove();
                        x = 0;
                        bool = false;
                    }
                    imgCon.style.left = x + "px";

                } else if (direction === RIGHT) {
                    x += SPEED;
                    if (x >= 0) {
                        bool = false;
                        x = 0;
                        imgCon.lastElementChild.remove();
                    }
                    imgCon.style.left = x + "px";
                }
            }

            /* 
                自动轮播
                1、如果自动轮播开关是false时,跳出
                2、time不断减少
                3、如果time大于0就不继续执行,跳出
                4、time值等于0,设置time初始为300
                5、创建一个点击事件对象
                6、向右侧按钮抛发这个点击事件
            
             */
            function autoPlay() {
                if (!autoBool) return;
                time--;
                if (time > 0) return;
                time = 300;
                var evt = new MouseEvent("click");
                bnList[1].dispatchEvent(evt);
            }
        </script>
     
  • 相关阅读:
    如何将一棵树转化成二叉树
    雪碧图的使用
    CSS简介,引入方式,文字和文本样式设置
    表格Table和表单元素
    html 中< col>标签和< colgroup>标签的区别
    Emmet的HTML语法(敲代码的快捷方式)
    抖音风格字体效果
    几种有效减小电脑系统盘使用量的方法
    ubuntu 机器名称修改方法
    Ubuntu 为基于X应用程序增加启动项的正确做法
  • 原文地址:https://www.cnblogs.com/zqm0924/p/13224798.html
Copyright © 2020-2023  润新知