A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

尹以寒

初级黑马

  • 黑马币:25

  • 帖子:8

  • 精华:0

© 尹以寒 初级黑马   /  2019-10-13 16:40  /  1837 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

倒计时
核心算法就是用输入时间的毫秒数(时间戳)减去现在时间的毫秒数(时间戳),得到的就是剩余时间的毫秒数,然后把剩余时间的总毫秒数转换成天,时,分,秒。
公式如下:
        d = parseIint(总秒数/60/60/24)
        h = parseInt(总秒数/60/60%24)
        m = parseInt(总秒数/60%60)
        s = parseInt(总秒数/60)
其中需要注意的是,毫秒和秒的换算是1000,所以开始的时候换算成秒需要先用总的毫秒数/1000。
判断是否是数组
        // 检测是否为数组
        // (1) instanceof  运算符 它可以用来检测是否为数组
        var arr = [];
        var obj = {};
        console.log(arr instanceof Array);
        console.log(obj instanceof Array);
        // (2) Array.isArray(参数);  H5新增的方法  ie9以上版本支持
        console.log(Array.isArray(arr));
        console.log(Array.isArray(obj));
可以用来检测该对象是否是数组,通常用于输入需要是数组的时候用来判断输入。不符合数组要求,就输出不是数组。
添加删除数组元素的方法
  
方法名
  
说明
返回值
push(参数1.)
末尾添加一个或多个元素,(修改原数组)
并返回新的长度
pop()
删除数组最后一个元素,把数组长度减1 无参数、修改原数组
返回他删除的元素的值
unshift()
向数组开头添加一个或更多元素(修改)
返回新的长度
shift()
删除数组第一个元素(修改)
返回第一个元素的值
之所以会修改原数组,是因为他们指向的都是同一块内存,所以相当于是在原来的数组的基础上修改,所以会修改原数组
数组索引
  
方法名
  
说明
返回值
IndexOf()
数组中查找给定元素的第一个索引
如果存在返回索引号,如果不存在返回-1
lastIndexOf()
在数组中最后的一个的索引
如果存在返回索引号,如果不存在返回-1
数组去重
核心算法:我们遍历旧数组,然后拿着旧数组的元素去查询新数组,如果元素在新数组里面没有出现过(即indexOf=-1)),我们就添加,否则就不添加
        //数组去重
        function unique(arr) {
            var newArr = [];
            for (var i = 0; i < arr.length; i++) {
                if (newArr.indexOf(arr) === -1) {
                    newArr.push(arr);
                };
            }
            return newArr;
        }
        var demo = unique([5, 1, 79, 7, 5, 3, 7, 1, 6, 7, ]);
        console.log(demo);
                              
查找字符串’
核心算法:先查找第一个o出现的位置,然后只要indexOf返回的结果不是-1就继续往后查找,因为indexOf只能找到第一个。所以后面的查找需要用第二个参数,从当前的索引+1,从而可以继续查找
        //查找字符串‘abcoefoxyozzopp’中出现的位置以及次数
        var str = 'oabcoefoxyozzopp';
        var num = 0;
        var index = str.indexOf('o');
        while (index !== -1) {
            console.log(index);
            num++;
            str.indexOf('o', index + 1);
        }
        console.log("o出现的次数是" + num);
根据位置返回字符
  
方法名
  
说明
使用
charAt(index)
返回指定位置的字符(index字符串的索引号)
Str.charAt(0)
CharCodeAt(index)
获取指定位置处的ASCII码(index索引号)
Str.charCode(0)
Str[index]
获取指定位置处字符
HTML5.IE8支持
返回字符位置
要求:判断一个字符串’abcoefoxyozzopp’中出现次数最多的字符,并统计次数
核心算法:
1.    利用charAt()遍历这个字符串
2.    把每个字符都储存给对象,如果对象没有这个属性就为1,存在了就加1
3.    遍历对象,得到最大值和该字符
代码演示:
        //统计次数、重点
        var str = 'abcoefoxyozzopp';
        var o = {};
        for (var i = 0; i < str.length; i++) {
            var chars = str.charAt(i); //chars是字符串的每一个字符
            if (o[chars]) {
                o[chars]++;
            } else {
                o[chars] = 1;
            }
        }
        //遍历对象
        var max = 0;
        var ch = '';
        for (var k in o) {
            //l 得到的是属性名。o[k]得到的是属性值
            if (o[k] > max) {
                max = o[k];
                ch = k;
            }
        }
        console.log(max);
        console.log(ch);
注册事件的两种方式
        //传统方式有唯一性
        var btns = document.querySelectorAll('button');
        btns[0].onclick = function() {
                alert('WDNMD');
            }
            //事件监听注册事件
            //同一个元素 同一个事件可以添加多个监听器,按顺序输出
        btns[1].addEventListener('click', function() {
            alert("你也是个闸种");
        })
        btns[1].addEventListener('click', function() {
            alert("你就是个大马猴");
        })
传统的方式就是用onclick来注册事件,但是传统的方式会有唯一性,即不能对同一个元素设置多个的事件
事件监听注册事件可以为同一个元素添加多个监听器,即可以设置多个事件
DOM事件流
定义:事情发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM时间流.
使劲按六描述的是从页面中接收事件的顺序
DOM时间流分为3个阶段
1.    捕获阶段
2.    当前目标阶段
3.    冒泡阶段
计算鼠标在盒子内的坐标
        //首先得到鼠标在页面中的坐标(e.pageX,e.pageY)
        //其次得到盒子在页面中的距离(box.offsetLeft,box.offsetTop)
        //用鼠标距离页面的坐标减去盒子再页面中的距离,得到鼠标在盒子内的坐标
        var box = document.querySelector('.box');
        box.addEventListener('click', function(e) {
            // console.log(e.pageX);
            // console.log(e.pageY);
            // console.log(box.offsetLeft);
            var x = e.pageX - this.offsetLeft;
            var y = e.pageY - this.offsetTop;
            this.innerHTML = 'X坐标是' + x + 'Y坐标是' + y;
        })
放大镜效果
本质:说到底,网页中的放大镜效果其实就是左边一个小图片,右边在通常情况下隐藏一个大图片,通过左侧的遮挡层移动的距离来移动右边大图片移动。
window.addEventListener('load', function() {
    var preview_img = document.querySelector('.preview_img');
    var mask = document.querySelector('.mask');
    var big = document.querySelector('.big');
    //当我们鼠标经过preview_img的时候就显示和隐藏mask和big
    preview_img.addEventListener('mouseover', function() {
        mask.style.display = 'block';
        big.style.display = 'block';
    })
    preview_img.addEventListener('mouseout', function() {
        mask.style.display = 'none';
        big.style.display = 'none';
    })
    preview_img.addEventListener('mousemove', function(e) {
        //先计算鼠标在盒子内的坐标
        var x = e.pageX - this.offsetLeft;
        var y = e.pageY - this.offsetTop;
        //减去盒子高度的一半就是mask的最终left和top值了
        //mask移动的距离
        var maskX = x - mask.offsetWidth / 2;
        var maskY = y - mask.offsetHeight / 2;
        //如果x坐标小于0就让他停在0的位置
        //遮挡层的最大移动距离
        //因为盒子是以左侧为准。所以不是给右边加限制,而是直接限制你能从左边走多远
        var maskMax = preview_img.offsetWidth - mask.offsetWidth;
        if (maskX <= 0) {
            maskX = 0;
        } else if (maskX >= maskMax) {
            maskX = maskMax;
        }
        if (maskY <= 0) {
            maskY = 0;
        } else if (maskY >= maskMax) {
            maskY = maskMax;
        }
        mask.style.left = maskX + 'px';
        mask.style.top = maskY + 'px';
        //大图片的移动距离=遮挡层移动距离*大图片最大移动距离/遮挡层最大移动距离
        var bigImg = document.querySelector('.bigImg');
        //大图片最大移动距离
        var bigMax = bigImg.offsetWidth - big.offsetWidth;
        //大图片的移动距离X Y
        var bigX = maskX / maskMax * bigMax;
        var bigY = maskY / maskMax * bigMax;
        //放大镜往正方向走,大图片反方向走
        bigImg.style.left = -bigX + 'px';
        bigImg.style.top = -bigY + 'px';
    })
})
其中有很多需要注意的点
1.    左侧遮挡层的限制并不是给左右都设置限制,而是限制左侧能走多远,即用左侧放图片盒子的大小减去遮挡层的大小,就是可以走的最大距离
2.    因为要求大图片和遮挡层的移动是正比例的移动,所以我们需要运用计算公式,从而达到两边是按相同比例的移动。即:
遮挡层移动的距离/遮挡层最大移动距离 = 大图片移动距离/大图片最大移动距离
3.    左侧遮挡层是正向移动,而右侧的大图片是反向移动,所以是负值.
4.    注意要给大的图片加上定位,要不然里面的top值和left值会没有起作用,还有赋值给left和top的时候需要在后面加上单位。切记切记
mouseenter 和mouseover的区别
·        当鼠标移动到元素上时就会触发mouseenter 事件
·        类似 mouseover,它们两者之间的差别是
·        mouseover 鼠标经过自身盒子会触发,经过子盒子还会触发。mouseenter  只会经过自身盒子触发
·        之所以这样,就是因为mouseenter不会冒泡
·        跟mouseenter搭配鼠标离开 mouseleave  同样不会冒泡
简单动态函数的封装
        //简单的动画函数封装
        function animate(obj, target) {
            var timer = setInterval(function() {
                if (obj.offsetLeft >= target) {
                    clearInterval(timer);
                }
                console.log(obj.offsetLeft)
                obj.style.left = obj.offsetLeft + 1 + 'px';
            }, 30)
        }
        var div = document.querySelector('div');
        var span = document.querySelector('span');
        //调用函数
        animate(div, 300);
        animate(span, 300);
CSS
        body,
        html {
            padding: 0;
            margin: 0;
        }
        
        div {
            position: absolute;
            left: 0;
            top: 0;
            width: 100px;
            height: 100px;
            background-color: #00a4ff;
        }
        
        span {
            position: relative;
            left: 0;
            top: 100px;
            display: block;
            width: 100px;
            height: 100px;
            background-color: #ccc;
        }
虽然整体代码并没有什么难度。只是单纯的将函数封装了起来。但是需要注意的是上面定位的相对值,如如果没有清除掉html和body的默认的padding值,那么在relative中相对左侧的距离就会多个浏览器默认的8px。从而跑的更加的快、所以这个案例除了需要知道如何封装函数以外,还需要知道relative相对的是什么。为什么要清除body和html的padding和magin

2 个回复

倒序浏览
仅仅代表个人看法,勿喷
回复 使用道具 举报
此长篇之文,大佬也
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马