1、定时器的基础知识(设置、清除、返回值分析)

JS中的定时器一共有两种:

1、window.setTimeout([function],[interval]):设置一个定时器,当到达指定时间后执行对应的方法(执行一次定时器就结束了)

2、window.setInterval([function],[interval]):设置一个定时器,当到达指定时间后执行对应的方法(以后每间隔这么长时间都要从新的执行定时器中的方法,直到定时器清除为止,执行很多次)

var count = 0;
setTimeout(function () {console.log(++count);//=>1
}, 1000);//=>1000MS=1Svar count = 0;
setInterval(function () {console.log(++count);
}, 1000);
复制代码

定时器的返回值:当我们设置定时器(不管是setTimeout还是setInterval),都会有一个返回值,返回值是一个数字,代表当前是在浏览器中设置的第几个定时器(返回的是定时器序号)

1、setTimeout和setInterval虽然是处理不同需求的定时器,但是都是浏览器的定时器,所以设置的时候,返回的序号是依次排列的

2、setInterval设置完成定时器会有一个返回值,不管执行多少次,这个代表序号的返回值不变(设置定时器就有返回值,执行多少次是定时器的处理)

var timer1 = setTimeout(function () {}, 1000);
console.log(timer1);//=>1var timer2 = setInterval(function () {}, 1000);
console.log(timer2);//=>2
复制代码

定时器的清除

clearTimeout([定时器的排队序号])

clearInterval([定时器的排队序号])

定时器需要手动清除

var t1 = setTimeout(function () {//=>当方法执行完成后,定时器没用了,我们清除定时器即可// clearTimeout(t1);//=>t1存储的就是当前定时器的编号// clearInterval(t1);//=>使用它也可以清除掉clearTimeout(t1);//=>在浏览器内部把定时器清除掉了(相当于银行业务员在系统中清除我们的排队号)t1 = null;//=>我们手动把之前存储序号的变量赋值为null(相当于我们把排队号那个纸条撕毁扔掉)
}, 1000);
复制代码

2、实现简单渐现的动画(融合到图片懒加载案例中)

css/index.less

@import "reset";.newsBox {margin: 0 10px;li {border-bottom: 1px solid #E4E4E4;&:nth-last-child(1) {border-bottom: none;}a {position: relative;display: block;padding: 10px 0;.imgBox {position: absolute;left: 0;top: 10px;width: 84px;height: 56px;background: url("../img/default.gif") no-repeat center center #EEE;background-size: 25px;img {display: none;opacity: 0;filter: alpha(opacity=0);width: 100%;height: 100%;}}.con {margin-left: 94px;p {height: 40px;line-height: 20px;font-size: 14px;color: #555;overflow: hidden;}span {display: block;line-height: 20px;font-size: 12px;color: #999;text-indent: 15px;background: url("../img/comment.png") no-repeat left center;background-size: 13px 15px;}}}}
}
复制代码

css/reset.less

body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, button, input, textarea, th, td {margin: 0;padding: 0
}body {font-size: 12px;font-style: normal;font-family: "\5FAE\8F6F\96C5\9ED1", Helvetica, sans-serif
}small {font-size: 12px
}h1 {font-size: 18px
}h2 {font-size: 16px
}h3 {font-size: 14px
}h4, h5, h6 {font-size: 100%
}ul, ol {list-style: none
}a {text-decoration: none;background-color: transparent
}a:hover, a:active {outline-width: 0;text-decoration: none
}table {border-collapse: collapse;border-spacing: 0
}hr {border: 0;height: 1px
}img {border-style: none
}img:not([src]) {display: none
}svg:not(:root) {overflow: hidden
}html {-webkit-touch-callout: none;-webkit-text-size-adjust: 100%
}input, textarea, button, a {-webkit-tap-highlight-color: rgba(0, 0, 0, 0)
}article, aside, details, figcaption, figure, footer, header, main, menu, nav, section, summary {display: block
}audio, canvas, progress, video {display: inline-block
}audio:not([controls]), video:not([controls]) {display: none;height: 0
}progress {vertical-align: baseline
}mark {background-color: #ff0;color: #000
}sub, sup {position: relative;font-size: 75%;line-height: 0;vertical-align: baseline
}sub {bottom: -0.25em
}sup {top: -0.5em
}button, input, select, textarea {font-size: 100%;outline: 0
}button, input {overflow: visible
}button, select {text-transform: none
}textarea {overflow: auto
}button, html [type="button"], [type="reset"], [type="submit"] {-webkit-appearance: button
}button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner {border-style: none;padding: 0
}button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring {outline: 1px dotted ButtonText
}[type="checkbox"], [type="radio"] {box-sizing: border-box;padding: 0
}[type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button {height: auto
}[type="search"] {-webkit-appearance: textfield;outline-offset: -2px
}[type="search"]::-webkit-search-cancel-button, [type="search"]::-webkit-search-decoration {-webkit-appearance: none
}::-webkit-input-placeholder {color: inherit;opacity: .54
}::-webkit-file-upload-button {-webkit-appearance: button;font: inherit
}.clearfix:after {display: block;height: 0;content: "";clear: both
}
复制代码

css/reset.min.css

body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,button,input,textarea,th,td{margin:0;padding:0}body{font-size:12px;font-style:normal;font-family:"\5FAE\8F6F\96C5\9ED1",Helvetica,sans-serif}small{font-size:12px}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4,h5,h6{font-size:100%}ul,ol{list-style:none}a{text-decoration:none;background-color:transparent}a:hover,a:active{outline-width:0;text-decoration:none}table{border-collapse:collapse;border-spacing:0}hr{border:0;height:1px}img{border-style:none}img:not([src]){display:none}svg:not(:root){overflow:hidden}html{-webkit-touch-callout:none;-webkit-text-size-adjust:100%}input,textarea,button,a{-webkit-tap-highlight-color:rgba(0,0,0,0)}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block}audio:not([controls]),video:not([controls]){display:none;height:0}progress{vertical-align:baseline}mark{background-color:#ff0;color:#000}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}button,input,select,textarea{font-size:100%;outline:0}button,input{overflow:visible}button,select{text-transform:none}textarea{overflow:auto}button,html [type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button}button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-cancel-button,[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}.clearfix:after{display:block;height:0;content:"";clear:both}
复制代码

js/index.js

var newsRender = (function () {var _newsData = null,_newsBox = document.getElementById('newsBox');//=>queryData:使用AJAX获取到需要绑定的数据function queryData() {var xhr = new XMLHttpRequest();xhr.open('get', 'json/news.json', false);xhr.onreadystatechange = function () {if (xhr.readyState === 4 && xhr.status === 200) {_newsData = utils.toJSON(xhr.responseText);}};xhr.send(null);}//=>bindHTML:根据获取的数据把HTML绑定在页面中function bindHTML() {if (!_newsData) return;var str = ``;for (var i = 0; i < _newsData.length; i++) {var item = _newsData[i];str += `<li><a href="${item.link}"><div class="imgBox"><img src="" data-img="${item.figure}" alt=""></div><div class="con"><p class="title">${item.title}</p><span>${item.comment}</span></div></a></li>`;}_newsBox.innerHTML = str;}//=>computed:计算出哪些图片需要延迟加载,我们让其延迟加载function computed() {var imgList = _newsBox.getElementsByTagName('img');for (var i = 0; i < imgList.length; i++) {var curImg = imgList[i],curBox = curImg.parentNode;if (curImg.isLoad) continue;//=>如果当前图片已经处理过了,我们不需要再重复处理,直接进行下一轮的循环,验证下一张图片是否需要加载即可//=>获取“图片所在盒子底边框距离BODY的距离 A” 和 “浏览器底边框距离BODY的距离 B”var A = utils.offset(curBox)['top'] + curBox.offsetHeight;var B = utils.winBox('clientHeight') + utils.winBox('scrollTop');if (A <= B) {//=>当前这张图片符合延迟加载的条件,我们开始加载lazyImg(curImg);}}}//=>lazyImg:给某一张图片进行延迟加载function lazyImg(curImg) {curImg.isLoad = true;//=>避免重复处理(isLoad:是自定义属性)var tempImg = new Image;tempImg.onload = function () {curImg.src = tempImg.src;curImg.style.display = 'block';imgFade(curImg);tempImg = null;};tempImg.src = curImg.getAttribute('data-img');}//=>imgFade:让当前图片渐现出来function imgFade(curImg) {var n = 0;var timer = setInterval(function () {if (n > 1) {clearInterval(timer);timer = null;return;}n += 0.05;utils.css(curImg, 'opacity', n);}, 17);//=>17MS是执行定时器动画相对比较理想的间隔时间}return {init: function () {//=>模块的入口:在入口中协调控制先做什么再做什么queryData();bindHTML();setTimeout(computed, 500);//=>当页面中数据都加载完成,过500MS在执行图片的延迟加载操作 <=> window.onload=computed 这个事件就是页面整体都加载完成才会触发window.onscroll = computed;//=>当滚动到具体的区域的时候,我们把当前符合条件的图片做延迟加载}}
})();
newsRender.init();
复制代码

js/less-2.5.3.min.js

......
复制代码

js/utils.js

var utils = (function () {//=>toArray:converts the class array to an arrayvar toArray = function (classAry) {var ary = [];try {ary = Array.prototype.slice.call(classAry);} catch (e) {for (var i = 0; i < classAry.length; i++) {ary[ary.length] = classAry[i];}}return ary;};//=>toJSON:converts a JSON formatted string to a JSON objectvar toJSON = function (str) {return 'JSON' in window ? JSON.parse(str) : eval('(' + str + ')');};//=>getCss:gets a value of a style attribute of the current elementvar getCss = function (curEle, attr) {var value = null,reg = null;if (window.getComputedStyle) {value = window.getComputedStyle(curEle, null)[attr];} else {if (attr === 'opacity') {value = curEle.currentStyle['filter'];reg = /^alpha\(opacity=(.+)\)$/i;value = reg.test(value) ? reg.exec(value)[1] / 100 : 1;} else {value = curEle.currentStyle[attr];}}reg = /^-?\d+(\.\d+)?(px|pt|rem|em)?$/i;reg.test(value) ? value = parseFloat(value) : null;return value;};//=>setCss:sets a value for a style property of the current elementvar setCss = function (curEle, attr, value) {if (attr === 'opacity') {curEle['style']['opacity'] = value;curEle['style']['filter'] = 'alpha(opacity=' + value * 100 + ')';return;}!isNaN(value) && !/^(zIndex|zoom|lineHeight|fontWeight)$/i.test(attr) ? value += 'px' : null;curEle['style'][attr] = value;};//=>setGroupCss:setting style attribute values to current elements in batchesvar setGroupCss = function (curEle, options) {if (Object.prototype.toString.call(options) !== '[object Object]') return;for (var attr in options) {if (options.hasOwnProperty(attr)) {setCss(curEle, attr, options[attr]);}}};//=>css:integrated method of setting styles, obtaining styles and setting styles in batchesvar css = function () {var len = arguments.length,type = Object.prototype.toString.call(arguments[1]),fn = getCss;len >= 3 ? fn = setCss : (len === 2 && type === '[object Object]' ? fn = setGroupCss : null);return fn.apply(this, arguments);};//=>offset:gets the offset of the current element distance BODY, including left offset and top offsetvar offset = function (curEle) {var l = curEle.offsetLeft,t = curEle.offsetTop,p = curEle.offsetParent;while (p.tagName !== 'BODY') {if (!/MSIE 8/i.test(navigator.userAgent)) {l += p.clientLeft;t += p.clientTop;}l += p.offsetLeft;t += p.offsetTop;p = p.offsetParent;}return {top: t, left: l};};//=>winBox:the operation has the JS box model property about the browser and handles the compatibilityvar winBox = function (attr, value) {if (typeof value !== 'undefined') {document.documentElement[attr] = value;document.body[attr] = value;return;}return document.documentElement[attr] || document.body[attr];};return {toArray: toArray,toJSON: toJSON,css: css,offset: offset,winBox: winBox}
})();
复制代码

json/mocData.js

var ary = [{"id": 1,"title": "勤政日历·省委书记|6地书记学习中央统一领导的规定","figure": "img/1.jpg","comment": 100,"link": "http://news.sina.cn/mrdx/swsj.d.html?cre=tianyi&mod=wnews&loc=0&r=-1&doct=0&rfunc=67&tj=none&tr=73&vt=4&pos=3"},{"id": 2,"title": "章莹颖家人计划明日回国 案件是否延期审判未定","figure": "img/2.jpg","comment": 97,"link": "http://news.sina.cn/sh/2017-11-11/detail-ifynshev5246310.d.html?cre=tianyi&mod=wnews&loc=1&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 3,"title": "上海浦东一家超市发生坍塌多人被埋 致1人遇难","figure": "img/3.jpg","comment": 70,"link": "http://news.sina.cn/gn/2017-11-11/detail-ifynshev5276174.d.html?cre=tianyi&mod=wnews&loc=2&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 4,"title": "山西官方回应幼童校园被袭事件:施暴者已被刑拘","figure": "img/4.jpg","comment": 591,"link": "http://news.sina.cn/2017-11-11/detail-ifynsait7262878.d.html?cre=tianyi&mod=wnews&loc=3&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 5,"title": "中国留学生加拿大失联 警方:或接恐吓电话躲起来","figure": "img/5.jpg","comment": 83,"link": "http://news.sina.cn/2017-11-11/detail-ifynsait7271765.d.html?cre=tianyi&mod=wnews&loc=4&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 6,"title": "复旦版“中国医院排行榜”公布 这些医院排名靠前","figure": "img/6.jpg","comment": 380,"link": "http://news.sina.cn/2017-11-11/detail-ifynrsrf3816830.d.html?cre=tianyi&mod=wnews&loc=5&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 7,"title": "赵薇股神人设崩塌 是演技太好还是我们入戏太深?","figure": "img/7.jpg","comment": 546,"link": "http://news.sina.cn/2017-11-11/detail-ifynsait7310451.d.html?cre=tianyi&mod=wnews&loc=6&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 8,"title": "特朗普和普京批准联合声明:将共同打击IS直至消灭","figure": "img/8.jpg","comment": 100,"link": "http://news.sina.cn/gj/2017-11-11/detail-ifynshev5289601.d.html?cre=tianyi&mod=wnews&loc=7&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 9,"title": "法国男子撞伤3名中国留学生 检方按谋杀案调查","figure": "img/9.jpg","comment": 100,"link": "http://news.sina.cn/gj/2017-11-11/detail-ifynrsrf3768828.d.html?cre=tianyi&mod=wnews&loc=8&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"}
];
var data = [];
for (var i = 1; i <= 1000; i++) {var ran = Math.round(Math.random() * 8),res = ary[ran];data.push({id: i,title: res.title,figure: res.figure,comment: res.comment,link: res.link});
}
var fs = require('fs');
fs.writeFileSync('./news.json', JSON.stringify(data), 'utf-8');
复制代码

json/news.json

[{"id": 1,"title": "章莹颖家人计划明日回国 案件是否延期审判未定","figure": "img/2.jpg","comment": 97,"link": "http://news.sina.cn/sh/2017-11-11/detail-ifynshev5246310.d.html?cre=tianyi&mod=wnews&loc=1&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 2,"title": "复旦版“中国医院排行榜”公布 这些医院排名靠前","figure": "img/6.jpg","comment": 380,"link": "http://news.sina.cn/2017-11-11/detail-ifynrsrf3816830.d.html?cre=tianyi&mod=wnews&loc=5&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 3,"title": "特朗普和普京批准联合声明:将共同打击IS直至消灭","figure": "img/8.jpg","comment": 100,"link": "http://news.sina.cn/gj/2017-11-11/detail-ifynshev5289601.d.html?cre=tianyi&mod=wnews&loc=7&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 4,"title": "复旦版“中国医院排行榜”公布 这些医院排名靠前","figure": "img/6.jpg","comment": 380,"link": "http://news.sina.cn/2017-11-11/detail-ifynrsrf3816830.d.html?cre=tianyi&mod=wnews&loc=5&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 5,"title": "勤政日历·省委书记|6地书记学习中央统一领导的规定","figure": "img/1.jpg","comment": 100,"link": "http://news.sina.cn/mrdx/swsj.d.html?cre=tianyi&mod=wnews&loc=0&r=-1&doct=0&rfunc=67&tj=none&tr=73&vt=4&pos=3"},{"id": 6,"title": "山西官方回应幼童校园被袭事件:施暴者已被刑拘","figure": "img/4.jpg","comment": 591,"link": "http://news.sina.cn/2017-11-11/detail-ifynsait7262878.d.html?cre=tianyi&mod=wnews&loc=3&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 7,"title": "上海浦东一家超市发生坍塌多人被埋 致1人遇难","figure": "img/3.jpg","comment": 70,"link": "http://news.sina.cn/gn/2017-11-11/detail-ifynshev5276174.d.html?cre=tianyi&mod=wnews&loc=2&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 8,"title": "中国留学生加拿大失联 警方:或接恐吓电话躲起来","figure": "img/5.jpg","comment": 83,"link": "http://news.sina.cn/2017-11-11/detail-ifynsait7271765.d.html?cre=tianyi&mod=wnews&loc=4&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 9,"title": "特朗普和普京批准联合声明:将共同打击IS直至消灭","figure": "img/8.jpg","comment": 100,"link": "http://news.sina.cn/gj/2017-11-11/detail-ifynshev5289601.d.html?cre=tianyi&mod=wnews&loc=7&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 10,"title": "赵薇股神人设崩塌 是演技太好还是我们入戏太深?","figure": "img/7.jpg","comment": 546,"link": "http://news.sina.cn/2017-11-11/detail-ifynsait7310451.d.html?cre=tianyi&mod=wnews&loc=6&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 11,"title": "特朗普和普京批准联合声明:将共同打击IS直至消灭","figure": "img/8.jpg","comment": 100,"link": "http://news.sina.cn/gj/2017-11-11/detail-ifynshev5289601.d.html?cre=tianyi&mod=wnews&loc=7&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 12,"title": "山西官方回应幼童校园被袭事件:施暴者已被刑拘","figure": "img/4.jpg","comment": 591,"link": "http://news.sina.cn/2017-11-11/detail-ifynsait7262878.d.html?cre=tianyi&mod=wnews&loc=3&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 13,"title": "山西官方回应幼童校园被袭事件:施暴者已被刑拘","figure": "img/4.jpg","comment": 591,"link": "http://news.sina.cn/2017-11-11/detail-ifynsait7262878.d.html?cre=tianyi&mod=wnews&loc=3&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 14,"title": "赵薇股神人设崩塌 是演技太好还是我们入戏太深?","figure": "img/7.jpg","comment": 546,"link": "http://news.sina.cn/2017-11-11/detail-ifynsait7310451.d.html?cre=tianyi&mod=wnews&loc=6&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 15,"title": "法国男子撞伤3名中国留学生 检方按谋杀案调查","figure": "img/9.jpg","comment": 100,"link": "http://news.sina.cn/gj/2017-11-11/detail-ifynrsrf3768828.d.html?cre=tianyi&mod=wnews&loc=8&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 16,"title": "复旦版“中国医院排行榜”公布 这些医院排名靠前","figure": "img/6.jpg","comment": 380,"link": "http://news.sina.cn/2017-11-11/detail-ifynrsrf3816830.d.html?cre=tianyi&mod=wnews&loc=5&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 17,"title": "章莹颖家人计划明日回国 案件是否延期审判未定","figure": "img/2.jpg","comment": 97,"link": "http://news.sina.cn/sh/2017-11-11/detail-ifynshev5246310.d.html?cre=tianyi&mod=wnews&loc=1&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 18,"title": "特朗普和普京批准联合声明:将共同打击IS直至消灭","figure": "img/8.jpg","comment": 100,"link": "http://news.sina.cn/gj/2017-11-11/detail-ifynshev5289601.d.html?cre=tianyi&mod=wnews&loc=7&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 19,"title": "山西官方回应幼童校园被袭事件:施暴者已被刑拘","figure": "img/4.jpg","comment": 591,"link": "http://news.sina.cn/2017-11-11/detail-ifynsait7262878.d.html?cre=tianyi&mod=wnews&loc=3&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 20,"title": "特朗普和普京批准联合声明:将共同打击IS直至消灭","figure": "img/8.jpg","comment": 100,"link": "http://news.sina.cn/gj/2017-11-11/detail-ifynshev5289601.d.html?cre=tianyi&mod=wnews&loc=7&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 21,"title": "中国留学生加拿大失联 警方:或接恐吓电话躲起来","figure": "img/5.jpg","comment": 83,"link": "http://news.sina.cn/2017-11-11/detail-ifynsait7271765.d.html?cre=tianyi&mod=wnews&loc=4&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 22,"title": "上海浦东一家超市发生坍塌多人被埋 致1人遇难","figure": "img/3.jpg","comment": 70,"link": "http://news.sina.cn/gn/2017-11-11/detail-ifynshev5276174.d.html?cre=tianyi&mod=wnews&loc=2&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 23,"title": "中国留学生加拿大失联 警方:或接恐吓电话躲起来","figure": "img/5.jpg","comment": 83,"link": "http://news.sina.cn/2017-11-11/detail-ifynsait7271765.d.html?cre=tianyi&mod=wnews&loc=4&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 24,"title": "章莹颖家人计划明日回国 案件是否延期审判未定","figure": "img/2.jpg","comment": 97,"link": "http://news.sina.cn/sh/2017-11-11/detail-ifynshev5246310.d.html?cre=tianyi&mod=wnews&loc=1&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 25,"title": "上海浦东一家超市发生坍塌多人被埋 致1人遇难","figure": "img/3.jpg","comment": 70,"link": "http://news.sina.cn/gn/2017-11-11/detail-ifynshev5276174.d.html?cre=tianyi&mod=wnews&loc=2&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 26,"title": "特朗普和普京批准联合声明:将共同打击IS直至消灭","figure": "img/8.jpg","comment": 100,"link": "http://news.sina.cn/gj/2017-11-11/detail-ifynshev5289601.d.html?cre=tianyi&mod=wnews&loc=7&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 27,"title": "上海浦东一家超市发生坍塌多人被埋 致1人遇难","figure": "img/3.jpg","comment": 70,"link": "http://news.sina.cn/gn/2017-11-11/detail-ifynshev5276174.d.html?cre=tianyi&mod=wnews&loc=2&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 28,"title": "特朗普和普京批准联合声明:将共同打击IS直至消灭","figure": "img/8.jpg","comment": 100,"link": "http://news.sina.cn/gj/2017-11-11/detail-ifynshev5289601.d.html?cre=tianyi&mod=wnews&loc=7&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 29,"title": "特朗普和普京批准联合声明:将共同打击IS直至消灭","figure": "img/8.jpg","comment": 100,"link": "http://news.sina.cn/gj/2017-11-11/detail-ifynshev5289601.d.html?cre=tianyi&mod=wnews&loc=7&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 30,"title": "上海浦东一家超市发生坍塌多人被埋 致1人遇难","figure": "img/3.jpg","comment": 70,"link": "http://news.sina.cn/gn/2017-11-11/detail-ifynshev5276174.d.html?cre=tianyi&mod=wnews&loc=2&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 31,"title": "特朗普和普京批准联合声明:将共同打击IS直至消灭","figure": "img/8.jpg","comment": 100,"link": "http://news.sina.cn/gj/2017-11-11/detail-ifynshev5289601.d.html?cre=tianyi&mod=wnews&loc=7&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 32,"title": "中国留学生加拿大失联 警方:或接恐吓电话躲起来","figure": "img/5.jpg","comment": 83,"link": "http://news.sina.cn/2017-11-11/detail-ifynsait7271765.d.html?cre=tianyi&mod=wnews&loc=4&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 33,"title": "复旦版“中国医院排行榜”公布 这些医院排名靠前","figure": "img/6.jpg","comment": 380,"link": "http://news.sina.cn/2017-11-11/detail-ifynrsrf3816830.d.html?cre=tianyi&mod=wnews&loc=5&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 34,"title": "上海浦东一家超市发生坍塌多人被埋 致1人遇难","figure": "img/3.jpg","comment": 70,"link": "http://news.sina.cn/gn/2017-11-11/detail-ifynshev5276174.d.html?cre=tianyi&mod=wnews&loc=2&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 35,"title": "复旦版“中国医院排行榜”公布 这些医院排名靠前","figure": "img/6.jpg","comment": 380,"link": "http://news.sina.cn/2017-11-11/detail-ifynrsrf3816830.d.html?cre=tianyi&mod=wnews&loc=5&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 36,"title": "山西官方回应幼童校园被袭事件:施暴者已被刑拘","figure": "img/4.jpg","comment": 591,"link": "http://news.sina.cn/2017-11-11/detail-ifynsait7262878.d.html?cre=tianyi&mod=wnews&loc=3&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"},{"id": 37,"title": "章莹颖家人计划明日回国 案件是否延期审判未定","figure": "img/2.jpg","comment": 97,"link": "http://news.sina.cn/sh/2017-11-11/detail-ifynshev5246310.d.html?cre=tianyi&mod=wnews&loc=1&r=25&doct=0&rfunc=67&tj=none&tr=25&vt=4&pos=3"}
]
复制代码

index.html

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><!--meta:vp [TAB]--><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><title></title><link rel="stylesheet/less" href="css/index.less"><script src="js/less-2.5.3.min.js"></script>
</head>
<body>
<ul class="newsBox" id="newsBox"><li><a href="#"><div class="imgBox"><img src="img/1.jpg" alt=""></div><div class="con"><p class="title">广西又曝两起虐童案 园长:家长敢曝光会被弄死</p><span>1923</span></div></a></li>
</ul><!--IMPORT JS-->
<script src="js/utils.js"></script>
<script src="js/index.js"></script>
</body>
</html>
复制代码

在index.js中增加:让当前图片渐现出来的方法

 //=>imgFade:让当前图片渐现出来function imgFade(curImg) {var n = 0;var timer = setInterval(function () {if (n > 1) {clearInterval(timer);timer = null;return;}n += 0.05;utils.css(curImg, 'opacity', n);}, 17);//=>17MS是执行定时器动画相对比较理想的间隔时间}
复制代码

3、JS中的同步和异步编程

JS中的同步编程和异步编程

JS是单线程的(一次只能执行一个任务,当前任务没有完成,下面的任务是不进行处理的)

同步编程(sync:synchronize):任务是按照顺序一件件的完成的,当前任务没有完成,下面的任务不进行处理

异步编程(async):当前任务在等待执行的时候,我们不去执行,继续完成下面的任务,当下面的任务完成后,而是也到达等待的时间了,才去完成当前的任务

  • 定时器都是异步编程的

  • 所有的事件绑定也是异步编程的

  • AJAX中有异步编程

  • 有些人把回调函数当做异步编程(理解起来比较牵强)

其余的都是同步编程

同步编程以及如何验证当前任务消耗的时间或者性能

var startTime = new Date();
for (var i = 0; i < 100000000; i++) {if (i === 999999) {console.log('no');//=>1 'no'}
}
console.log(new Date() - startTime);
console.log('ok');//=>2 'ok'
复制代码

在真实项目中我们要避免出现死循环:因为循环是同步编程,当前循环无法结束证明任务没完成,后续的任务操作都执行不了了

while (1 === 1) {}
console.log('ok');
复制代码

定时器有两件任务:创建定时器和过多长时间执行方法。创建定时器是同步,但是多长时间之后执行方法(等待任务)是异步。

//=>第一件任务:创建一个变量
var n = 0;
//=>第二件任务:创建一个定时器 (定时器里面还有个等待任务:1000MS执行方法是一个等待执行的任务)
setTimeout(function () {n++;console.log(n);//=>再输出 1
}, 1000);
//=>第三个任务:输出0
console.log(n);//=>先输出 0
复制代码

同步异步编程的核心原理

JS中有两个任务队列(存放任务列表的空间就是任务队列)

1、主任务队列:同步执行任务(从上到下依次执行)

2、等待任务队列:异步执行任务

// 王洋饭店
//   高梅(单线程理解为只能招聘一个服务员)
//
// 10:00:00 徐锐:拍黄瓜 (5MIN)
// 10:00:01 赵淼:水煮鱼 (30MIN)
// 10:00:02 金广:醋溜白菜 (10MIN)
// 10:00:03 元帅:白开水 (1MIN)
// ...
// 11:00:00 高梅忙完了,开始端菜,谁的先到时间先给谁端setTimeout(function () {console.log(1);
}, 50);setTimeout(function () {console.log(2);
}, 10);setTimeout(function () {console.log(3);
}, 30);for (var i = 0; i < 100000000; i++) {//=>需要600MS~700MS
}
console.log(4);=>输出
123
...
123
4
2
3
1
复制代码

代码执行图

js中有两个任务队列:主任务队列(同步)和等待任务队列(异步)

js是单线程的(同步),浏览器是多线程的,浏览器只给js分了一个线程,所以所有要执行的方法都要放在主任务队列中去执行,主任务队列执行是一个同步编程的过程,只能从上到下依次执行,而js所谓的异步编程只是把某些事情先临时存放在等待任务队列当中,浏览器开始计时,当主任务队列都完成之后,到等待任务队列中,找到已经到达时间的任务,把等待任务队列中的任务拿到主任务队列中执行,当前这个任务完成后,在等待中去找其他的任务。

4、同步异步编程应用1

for (var i = 1; i <= 5; i++) {setTimeout(function () {console.log(i);}, (5 - i) * 10);
}
// =>[主任务队列]
// i=1 创建一个定时器
// i=2 创建一个定时器
// i=3 创建一个定时器
// i=4 创建一个定时器
// i=5 创建一个定时器
// i=6 循环结束,此时主任务队列中的方法都已经执行完成了,到等待任务队列中找先到时间的方法,拿到主任务队列中执行
// 执行它 function () {console.log(i);},i不是自己私有的,找全局下的i(此时的i已经是6了)// =>[等待任务队列]
// 40MS后执行某方法
// 30MS后执行某方法
// 20MS后执行某方法
// 10MS后执行某方法
// 0MS后执行某方法//输出5次,5次都是输出6//--------------------------------------------------------------------------for (var i = 0; i <oList.length; i++) {oList[i].onclick=function () {alert(i);}
}
// 所有事件绑定也是异步编程,第一次循环给oList[i]绑定一个方法,但是并没有执行,
// 异步编程放在等待任务队列中去,点击这个事件的时候才会执行(浏览器在等待任务队列中
// 除了有计时器功能外,还有监听是否触发点击事件,点击了才会把等待任务队列中的事件拿到
// 主任务中去执行)。当点击执行这个事件时,主任务中循环已经完成,i永远是最后的结果i,
// 所以最后输出的结果永远都是最后的结果i// 结论:所有事件绑定都是异步的,当我们触发执行的时候,同步变成的循环早已结束,i就是最后循环的值// 解决方案 把var换成let或者闭包
for (var i = 1; i <= 5; i++) {~function (i) {setTimeout(function () {console.log(i);}, (5 - i) * 10);}(i);
}
复制代码

5、同步异步编程应用2

同步编程和异步编程在真正项目中会存在一个实际的应用:比如当我们打开类似京东页面,当页面在加载中时,点击页面不会任何反应,只有这个加载完成(圆圈没有了的时候),点击页面才会有对应的操作。原因就是在加载过程中,主任务队列中任务还没有完成,所以放在等待任务队列中的所有事件绑定都不会执行,只有等主任务队列完成后才去执行。

项目中会这样去实现:我们把一个页面按功能分成很多个板块,把每一块板块内容都分别用page1,page2包起来,把除第一屏page1外的板块内容都放到定时器里面,来实现异步操作,使页面加载速度更快,让首页能更快的加载出来并操作。(让主任务队列中的任务少一点,等待任务队列中的任务多一点)。

这样做还有一个好处:假设某个区域数据太多,加载出来会花很长时间,但是也不会影响其他区域加载出来(用异步操作,这个区域没加载出来,其他区域到达时间也会去加载出来)

var page1 = (function () {return {init: function () {}}
})();
page1.init();var page2 = (function () {return {init: function () {}}
})();
setTimeout(page2.init, 0);
复制代码

例子1

setTimeout(function () {console.log('ok');
}, 0);//=>定时器等待时间设置为0也不是立马执行,浏览器都有一个最小的反应时间(谷歌:5~7MS IE:10~13MS ...),写0也需要等到几毫秒
console.log('no');//-----------------------------------------------------------------------
setTimeout(function () {console.log(1);
}, 100);
while (1 == 1) {}
// 主任务队列死循环永远完成不了,所以永远执行不到等待任务队列中的定时器输出不到1
复制代码

例子2

setTimeout(function () {console.log(1);
}, 1000);setTimeout(function () {console.log(2);while (1 == 1) {}
}, 500);setTimeout(function () {console.log(3);
}, 100);for (var i = 0; i < 1000000000; i++) {}
console.log(4);
// 输出2后,主任务队列中的while死循环执行不到输出1,所以输出结果是:4,3,2
复制代码

6、js中固定步长和固定时间的均速运动动画

html

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title></title><link rel="stylesheet" href="css/reset.min.css"><style>.box {position: absolute;top: 0;left: 0;width: 100px;height: 100px;background: red;opacity: 1;filter: alpha(opacity=100);}</style>
</head>
<body>
<div class="box" id="box"></div><script src="js/utils.js"></script>
<script src="js/2-1.js"></script>
</body>
</html>
复制代码

2-1.js 步长固定(每一步走多少固定了),但是多长时间运动完成不固定

//=>JS中的动画:
//1、步长固定(每一步走多少固定了),但是多长时间运动完成不固定
var oBox = document.getElementById('box'),target = utils.winBox('clientWidth') - oBox.offsetWidth;//目标长度
//=>动画:每间隔一定时间都在自己原有的LEFT基础上累加步长50PX即可,一直到达目标值结束
var timer = setInterval(function () {var curL = utils.css(oBox, 'left');//获取当前的LEFT值curL += 50;utils.css(oBox, 'left', curL);if (curL >= target) {utils.css(oBox, 'left', target);clearInterval(timer);}
}, 17);
复制代码

2-2.js 固定时间的匀速动画

//=>JS中动画:固定时间的匀速动画
//1、target:目标值
//2、begin:起始值
//3、change:总距离  target-begin
//4、duration:总时间
//5、time:已经运动的时间// time/duration =>已经走了百分之多少的距离
// time/duration*change =>已经运动的距离
// time/duration*change+begin =>当前元素的位置//=>匀速公式:计算出当前元素应该运动到的位置
function linear(t, b, c, d) {return t / d * c + b;
}
var oBox = document.getElementById('box');
var time = 0,duration = 1000,begin = utils.css(oBox, 'left'),target = utils.winBox('clientWidth') - oBox.offsetWidth,change = target - begin;
var timer = setInterval(function () {time += 17;if (time >= duration) {utils.css(oBox, 'left', target);clearInterval(timer);return;}var curL = linear(time, begin, change, duration);utils.css(oBox, 'left', curL);
}, 17);
复制代码

7、使用setTimeout模拟setInterval的效果

html

// 同6
复制代码

js

//=>使用setTimeout模拟setInterval的效果(递归)
//固定步长来模拟
var oBox = document.getElementById('box'),target = utils.winBox('clientWidth') - oBox.offsetWidth,//目标距离step = 50;//步长// var timer = null;
function move() {//=>每一次开始之前,都把上一次创建的,那个没用的定时器清除掉(内存优化)clearTimeout(oBox.timer);//=>每一次走一步var curL = utils.css(oBox, 'left');//当前位置if (curL + step >= target) {utils.css(oBox, 'left', target);return;}curL += step;utils.css(oBox, 'left', curL);// var timer = setTimeout(move, 17); // 私有变量timer,下次执行得不到这个timer,如果把这个// // timer放在全局下(var timer = null),全局变量会增加,所以最好把这个定时器放在自定义属性 oBox.timer上;oBox.timer = setTimeout(move, 17);//递归}
move();
复制代码

8、多方向固定时间匀速运动的动画

//=>多方向匀速固定时间动画
var oBox = document.getElementById('box');var time = 0, // 已经走的时间duration = 1000;
var begin = { // 两个方向的起始值 一个变量存两个值用对象方式left: utils.css(oBox, 'left'),top: utils.css(oBox, 'top')
};
var target = { // 两个方向的目标值left: utils.winBox('clientWidth') - oBox.offsetWidth,top: utils.winBox('clientHeight') - oBox.offsetHeight
};var change = {};//两个方向的距离值
for (var key in target) {if (target.hasOwnProperty(key)) {change[key] = target[key] - begin[key];}
}
// console.log(change)// // 也可以直接这样去写
// var change = {
//     left:target['left']-begin['left'],
//     top:target['top']-begin['top']
// };oBox.timer = setInterval(function () {time += 17;//当前走了多长时间//=>边界if (time >= duration) {utils.css(oBox, target);clearInterval(oBox.timer);return;}var curPos = {};//当前元素位置for (var key in change) {if (change.hasOwnProperty(key)) {curPos[key] = linear(time, begin[key], change[key], duration);}}//curPos={top:xxx,left:xxx} 每一个方向当前的位置utils.css(oBox, curPos);//批量设置oBox的样式
}, 17);//匀速运动的公式
function linear(t, b, c, d) {return t / d * c + b;
}
复制代码

加了个透明度

//=>多方向匀速固定时间动画
var oBox = document.getElementById('box');
var time = 0,duration = 1000;
var begin = {left: utils.css(oBox, 'left'),top: utils.css(oBox, 'top'),opacity: utils.css(oBox, 'opacity')//加一个透明度
};
var target = {left: utils.winBox('clientWidth') - oBox.offsetWidth,top: utils.winBox('clientHeight') - oBox.offsetHeight,opacity: 0.1//目标值  从1变到0.1
};
var change = {};
for (var key in target) {if (target.hasOwnProperty(key)) {change[key] = target[key] - begin[key];}
}oBox.timer = setInterval(function () {time += 17;//=>边界if (time >= duration) {utils.css(oBox, target);clearInterval(oBox.timer);return;}var curPos = {};for (var key in change) {if (change.hasOwnProperty(key)) {curPos[key] = linear(time, begin[key], change[key], duration);}}//curPos={top:xxx,left:xxx} 每一个方向当前的位置utils.css(oBox, curPos);
}, 17);function linear(t, b, c, d) {return t / d * c + b;
}
复制代码

多方向匀速运动原理:把每一个方向的固定时间的匀速运动最终汇总到一起,用一个对象存储多个方向

9、封装简易的动画库(支持匀速定时多方向运动)

html

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title></title><link rel="stylesheet" href="css/reset.min.css"><style>.box {position: absolute;top: 0;left: 0;width: 100px;height: 100px;background: red;opacity: 1;filter: alpha(opacity=100);}</style>
</head>
<body>
<div class="box" id="box"></div><script src="js/utils.js"></script> //这里需要用到utiles里面的utils.winBox('clientWidth'),所以还是需要引入
<script src="js/animate.js"></script>
<script src="js/2-6.js"></script>
</body>
</html>
复制代码

animate.js

//=>支持多方向匀速运动(固定时间)
~function () {//=>4、把UTILS中的CSS单独提取出来:这样以后我们的ANIMATE动画库不需要依赖UTILS也可以独立运行var utils = (function () {var isCompatible = 'getElementsByClassName' in document;function getCss(curEle, attr) {var value = null, reg = null;if (isCompatible) {value = window.getComputedStyle(curEle, null)[attr];} else {if (attr === 'opacity') {value = curEle.currentStyle['filter'];reg = /^alpha\(opacity=(.+)\)$/i;return reg.test(value) ? reg.exec(value)[1] / 100 : 1;}value = curEle.currentStyle[attr];}reg = /^-?\d+(.\d+)?(pt|px|rem|em)?$/i;return reg.test(value) ? parseFloat(value) : value;}function setCss(curEle, attr, value) {if (attr === 'opacity') {curEle.style.opacity = value;curEle.style.filter = 'alpha(opacity=' + value * 100 + ')';return;}!isNaN(value) && !/(fontWeight|lineHeight|zoom|zIndex)/i.test(attr) ? value += 'px' : null;curEle.style[attr] = value;}function setGroupCss(curEle, options) {if (Object.prototype.toString.call(options) !== '[object Object]') return;for (var attr in options) {if (options.hasOwnProperty(attr)) {setCss(curEle, attr, options[attr])}}}function css() {var len = arguments.length,type = Object.prototype.toString.call(arguments[1]),fn = getCss;len >= 3 ? fn = setCss : (len === 2 && type === '[object Object]' ? fn = setGroupCss : null)return fn.apply(this, arguments);}return {css: css}})();/** curEle:当前需要运动的元素* target:运动的目标位置 {xxx:xxx,...}* duration:运动的总时间*/// 1、匀速运动公式 function linear(t, b, c, d) {return t / d * c + b;}//2、实现运动的方法function animate(curEle, target, duration) {var t = 0,d = duration || 1000,b = {},//起始值c = {};//总距离//=>传递的目标中有哪些方向,我们需要分别获取当前这些方向的起始值和总距离for (var key in target) {if (target.hasOwnProperty(key)) {b[key] = utils.css(curEle, key); //获取当前位置(起始值) 3、需要用到utils的css 提取utils的css方法c[key] = target[key] - b[key];//总距离}}//=>开始设置定时器,让元素运动即可clearInterval(curEle.animateTimer);//=>在设置新动画之前把之前正在运行的动画清除掉,防止当前元素相同的动画共存curEle.animateTimer = setInterval(function () {t += 17;if (t >= d) {utils.css(curEle, target);clearInterval(curEle.animateTimer);return;}var cur = {};for (var key in target) {if (target.hasOwnProperty(key)) {cur[key] = linear(t, b[key], c[key], d);}}utils.css(curEle, cur);//批量设置curEle样式}, 17);}window.animate = animate;//暴露animate
}();
复制代码

2-6.js

// var oBox = document.getElementById('box'),
//     target = { //获取目标值
//         left: utils.winBox('clientWidth') - oBox.offsetWidth,
//         top: utils.winBox('clientHeight') - oBox.offsetHeight,
//         opacity: 0.1
//     };
// animate(oBox, target);
// animate(oBox, target, 500);//-------------------------------------------------------
//目标值可以直接写// var oBox = document.getElementById('box');
// animate(oBox, {
//     top: 300,
//     left:700,
//     width:200,
//     height:200
// }, 1000);// animate(oBox, {
//     top: 100,
//     left:100,
//     width:50,
//     height:50
// }, 500);
//-------------------------------------------------------var oBox = document.getElementById('box');
animate(oBox, {top: -300
}, 1000);animate(oBox, {top: 300
}, 1000);// 给当前元素设置两个动画时会冲突,所以 clearInterval(curEle.animateTimer);
//=>在设置新动画之前把之前正在运行的动画清除掉,防止当前元素相同的动画共存
复制代码

utils.js

var utils = (function () {var isCompatible = 'getElementsByClassName' in document,isSupportJSON = 'JSON' in window;//=>toArray & toJSONvar toArray = function (classAry) {var ary = [];if (isCompatible) {ary = Array.prototype.slice.call(classAry);} else {for (var i = 0; i < classAry.length; i++) {ary[ary.length] = classAry[i];}}return ary;};var toJSON = function (str) {return isSupportJSON ? JSON.parse(str) : eval('(' + str + ')');};//=>offset & winBoxvar offset = function (curEle) {var l = curEle.offsetLeft,t = curEle.offsetTop,p = curEle.offsetParent;while (p.tagName !== 'BODY') {if (isCompatible === false && isSupportJSON === true) {l += p.clientLeft;t += p.clientTop;}l += p.offsetLeft;t += p.offsetTop;p = p.offsetParent;}return {left: l, top: t};};var winBox = function (attr, value) {if (typeof value !== 'undefined') {document.documentElement[attr] = value;document.body[attr] = value;return;}return document.documentElement[attr] || document.body[attr];};//=>childrenfunction children(ele, attr) {var ary = [];isCompatible ? ary = toArray(ele.children) : ary = toArray(ele.childNodes);for (var k = 0; k < ary.length; k++) {var obj = ary[k];if (obj.nodeType === 1) {if (attr && attr.toLowerCase() !== obj.tagName.toLowerCase()) {ary.splice(k, 1);k--;}} else {ary.splice(k, 1);k--;}}return ary;}//=>getElementsByClassNamefunction getElementsByClassName(classStr, context) {if (arguments.length === 0) return [];context = context || document;if (isCompatible) {return toArray(context.getElementsByClassName(classStr));}var eleList = toArray(context.getElementsByTagName("*"));var classList = classStr.replace(/^ +| +$/g, "").split(/ +/);for (var i = 0; i < classList.length; i++) {var cur = classList[i];var reg = new RegExp("(^| +)" + cur + "( +|$)");for (var j = 0; j < eleList.length; j++) {if (!reg.test(eleList[j].className)) {eleList.splice(j, 1);j--;}}}return eleList;}//=>cssfunction getCss(curEle, attr) {var value = null, reg = null;if (isCompatible) {value = window.getComputedStyle(curEle, null)[attr];} else {if (attr === 'opacity') {value = curEle.currentStyle['filter'];reg = /^alpha\(opacity=(.+)\)$/i;return reg.test(value) ? reg.exec(value)[1] / 100 : 1;}value = curEle.currentStyle[attr];}reg = /^-?\d+(.\d+)?(pt|px|rem|em)?$/i;return reg.test(value) ? parseFloat(value) : value;}function setCss(curEle, attr, value) {if (attr === 'opacity') {curEle.style.opacity = value;curEle.style.filter = 'alpha(opacity=' + value * 100 + ')';return;}!isNaN(value) && !/(fontWeight|lineHeight|zoom|zIndex)/i.test(attr) ? value += 'px' : null;curEle.style[attr] = value;}function setGroupCss(curEle, options) {if (Object.prototype.toString.call(options) !== '[object Object]') return;for (var attr in options) {if (options.hasOwnProperty(attr)) {setCss(curEle, attr, options[attr])}}}function css() {var len = arguments.length,type = Object.prototype.toString.call(arguments[1]),fn = getCss;len >= 3 ? fn = setCss : (len === 2 && type === '[object Object]' ? fn = setGroupCss : null)return fn.apply(this, arguments);}return {toArray: toArray,toJSON: toJSON,offset: offset,winBox: winBox,children: children,getElementsByClassName: getElementsByClassName,css: css}
})();
复制代码

10、使用动画库实现DIALOG弹出层 

html

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title></title><link rel="stylesheet" href="css/reset.min.css"><link rel="stylesheet" href="css/dialog.css">
</head>
<body>
<a id="login" href="javascript:;">立即登陆</a><!--DIALOG-->
<div class="dialogBg" id="dialogBg"></div>
<div class="dialogBox" id="dialogBox"><h2>欢迎登陆</h2><a href="javascript:;" class="close" id="close">X</a><div class="content"><!--具体详细展示的内容--></div>
</div><script src="js/utils.js"></script>//同之前的utils.js
<script src="js/animate.js"></script>
<script src="js/1-1.js"></script>
</body>
</html>
复制代码

animate.js

~function () {var utils = (function () {var isCompatible = 'getElementsByClassName' in document;function getCss(curEle, attr) {var value = null, reg = null;if (isCompatible) {value = window.getComputedStyle(curEle, null)[attr];} else {if (attr === 'opacity') {value = curEle.currentStyle['filter'];reg = /^alpha\(opacity=(.+)\)$/i;return reg.test(value) ? reg.exec(value)[1] / 100 : 1;}value = curEle.currentStyle[attr];}reg = /^-?\d+(.\d+)?(pt|px|rem|em)?$/i;return reg.test(value) ? parseFloat(value) : value;}function setCss(curEle, attr, value) {if (attr === 'opacity') {curEle.style.opacity = value;curEle.style.filter = 'alpha(opacity=' + value * 100 + ')';return;}!isNaN(value) && !/(fontWeight|lineHeight|zoom|zIndex)/i.test(attr) ? value += 'px' : null;curEle.style[attr] = value;}function setGroupCss(curEle, options) {if (Object.prototype.toString.call(options) !== '[object Object]') return;for (var attr in options) {if (options.hasOwnProperty(attr)) {setCss(curEle, attr, options[attr])}}}function css() {var len = arguments.length,type = Object.prototype.toString.call(arguments[1]),fn = getCss;len >= 3 ? fn = setCss : (len === 2 && type === '[object Object]' ? fn = setGroupCss : null)return fn.apply(this, arguments);}return {css: css}})();/** 动画公式*   t:time 已经运动的时间*   b:begin 当前运动方向的起始位置*   c:change 当前运动方向的总距离*   d:duration 当前运动的总时间*/function linear(t, b, c, d) {return t / d * c + b;}/** 实现动画*  curEle:当前要运动的元素*  target:当前元素运动的目标位置 {xxx:xxx...}*  duration:当前运动的总时间(默认值1000MS)*  callBack:回调函数(动画完成后我们处理什么事情)*/function animate(curEle, target, duration, callBack) {var time = 0,begin = {},change = {};duration = duration || 1000;for (var key in target) {if (target.hasOwnProperty(key)) {begin[key] = utils.css(curEle, key);change[key] = target[key] - begin[key];}}clearInterval(curEle.animateTimer);curEle.animateTimer = setInterval(function () {time += 17;if (time >= duration) {utils.css(curEle, target);clearInterval(curEle.animateTimer);//=>动画完成后执行回调函数(验证是否为函数,是函数才执行)// typeof callBack === 'function' ? callBack() : null;callBack && callBack();// callBack && callBack.call(curEle);return;}var curPos = {};for (var key in target) {if (target.hasOwnProperty(key)) {curPos[key] = linear(time, begin[key], change[key], duration);}}utils.css(curEle, curPos);}, 17);}window.animate = animate;
}();复制代码

1-1.js 动画库实现DIALOG弹出层

var dialogRender = (function () {var dialogBg = document.getElementById('dialogBg'),dialogBox = document.getElementById('dialogBox'),close = document.getElementById('close');function show() {utils.css(dialogBg, 'display', 'block');utils.css(dialogBox, 'display', 'block');animate(dialogBox, {width: 400,height: 500,marginLeft: -200,marginTop: -250}, 500);}function hide() {close.onclick = function () {utils.css(dialogBg, 'display', 'none');utils.css(dialogBox, {display: 'none',width: 0,height: 0,marginLeft: 0,marginTop: 0});}}return {init: function () {//=>控制显示show();//=>控制隐藏hide();}}
})();//=>点击登陆的时候执行DIALOG中的方法
var loginBtn = document.getElementById('login');
loginBtn.onclick = function () {dialogRender.init();
};
复制代码

css

html, body {height: 100%;
}.login {display: block;
}.dialogBg {display: none;position: fixed;top: 0;left: 0;z-index: 998;width: 100%;height: 100%;background: #000;opacity: 0.3;filter: alpha(opacity=30);
}.dialogBox {display: none;position: fixed;z-index: 999;top: 50%;left: 50%;/*margin: -250px 0 0 -200px;width: 400px;height: 500px;*/margin: 0;width: 0;height: 0;background: #FFF;overflow: hidden;
}.dialogBox h2 {height: 49px;line-height: 49px;text-align: center;background: #EEE;border-bottom: 1px solid #CCC;font-size: 16px;font-weight: normal;letter-spacing: 6px;overflow: hidden;
}.dialogBox .close {position: absolute;top: 0;right: 0;width: 50px;height: 50px;line-height: 50px;text-align: center;font-size: 22px;font-weight: normal;color: #E01D20;
}
复制代码

11、扩展动画库(让其支持回调函数)

js中的定时器及动画

完整版动画库封装

  • 回调函数初步讲解

  • 扩展更多的运动方式(非匀速)

  • options对象参数的应用

回调函数

把一个函数当做实参值传递给另外一个函数,在另外一个函数中执行这个函数,这种处理机制就是回调函数机制

function fn(callBack){}function aa(){console.log('aa');
}fn(aa);//以上等价于以下写法---------------------------------function fn(callBack) {//=>callBack:传递进来的匿名函数callBack();
}
fn(function () {console.log('ok');
});//---------------------------------------------------------------------------
var ary = [12, 23];//通过实例找到原型上的sort方法,并且让sort方法执行,sort里面的fuction就相当于传递的匿名函数=>回调函数//这个function是在执行sort方法的时候,在sort方法体中把传递进来的匿名函数执行,匿名函数是在sort方法体中//执行的,同理:数组里面很多方法中传递的匿名函数都是回调函数
ary.sort(function (a, b) {return a - b;
});
ary.forEach(function () {});
ary.map(function () {});
setTimeout(function () {},1000);
str.replace(reg,function () {});
复制代码

执行animate方法,在动画执行结束之后需要做的事情(具体做什么不知道,所以传一个函数,动画结束之后执行这个函数)

animate.js 中传递一个回调函数 callBack

~function () {var utils = (function () {var isCompatible = 'getElementsByClassName' in document;function getCss(curEle, attr) {var value = null, reg = null;if (isCompatible) {value = window.getComputedStyle(curEle, null)[attr];} else {if (attr === 'opacity') {value = curEle.currentStyle['filter'];reg = /^alpha\(opacity=(.+)\)$/i;return reg.test(value) ? reg.exec(value)[1] / 100 : 1;}value = curEle.currentStyle[attr];}reg = /^-?\d+(.\d+)?(pt|px|rem|em)?$/i;return reg.test(value) ? parseFloat(value) : value;}function setCss(curEle, attr, value) {if (attr === 'opacity') {curEle.style.opacity = value;curEle.style.filter = 'alpha(opacity=' + value * 100 + ')';return;}!isNaN(value) && !/(fontWeight|lineHeight|zoom|zIndex)/i.test(attr) ? value += 'px' : null;curEle.style[attr] = value;}function setGroupCss(curEle, options) {if (Object.prototype.toString.call(options) !== '[object Object]') return;for (var attr in options) {if (options.hasOwnProperty(attr)) {setCss(curEle, attr, options[attr])}}}function css() {var len = arguments.length,type = Object.prototype.toString.call(arguments[1]),fn = getCss;len >= 3 ? fn = setCss : (len === 2 && type === '[object Object]' ? fn = setGroupCss : null)return fn.apply(this, arguments);}return {css: css}})();/** 动画公式*   t:time 已经运动的时间*   b:begin 当前运动方向的起始位置*   c:change 当前运动方向的总距离*   d:duration 当前运动的总时间*/function linear(t, b, c, d) {return t / d * c + b;}/** 实现动画*  curEle:当前要运动的元素*  target:当前元素运动的目标位置 {xxx:xxx...}*  duration:当前运动的总时间(默认值1000MS)*  callBack:回调函数(动画完成后我们处理什么事情)*/function animate(curEle, target, duration, callBack) {var time = 0,begin = {},change = {};duration = duration || 1000;for (var key in target) {if (target.hasOwnProperty(key)) {begin[key] = utils.css(curEle, key);change[key] = target[key] - begin[key];}}clearInterval(curEle.animateTimer);curEle.animateTimer = setInterval(function () {time += 17;if (time >= duration) {utils.css(curEle, target);clearInterval(curEle.animateTimer);//=>动画完成后执行回调函数(验证是否为函数,是函数才执行)// typeof callBack === 'function' ? callBack() : null;callBack && callBack();//左边不成立返回左边,左边成立才返回右边// callBack && callBack.call(curEle);//改变回调函数中的this,this变成当前元素return;}var curPos = {};for (var key in target) {if (target.hasOwnProperty(key)) {curPos[key] = linear(time, begin[key], change[key], duration);}}utils.css(curEle, curPos);}, 17);}window.animate = animate;
}();复制代码

使用这个回调函数实现直角运动动画

html

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title></title><link rel="stylesheet" href="css/reset.min.css"><style>.box {position: absolute;top: 300px;left: 400px;width: 100px;height: 100px;background: red;border-radius: 50%;}</style>
</head>
<body>
<div class="box" id="box"></div><script src="js/utils.js"></script>//同上utils.js
<script src="js/animate.js"></script> //同上animate.js
<script src="js/2-2.js"></script>
</body>
</html>
复制代码

2-2.js

var oBox = document.getElementById('box');function move() {animate(oBox, {top: 0}, 500, function () {utils.css(oBox, 'backgroundColor', 'green');animate(oBox, {left: 800}, 500, function () {utils.css(oBox, 'backgroundColor', 'orange');animate(oBox, {top: 300}, 500, function () {utils.css(oBox, 'backgroundColor', 'pink');animate(oBox, {left: 400}, 500, function () {utils.css(oBox, 'backgroundColor', 'red');});});});});
}
move();
// setInterval(move, 2000);
复制代码

12、使用css3的animate实现动画

css3不兼容,标准浏览器下使用css3,ie下做个判断使用js实现(css3实现动画性能比js好)

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title></title><link rel="stylesheet" href="css/reset.min.css"><style>.box {position: absolute;top: 300px;left: 400px;width: 100px;height: 100px;background: red;border-radius: 50%;/*animation: move 2s linear 0s infinite both;*/ /* 2s 匀速运动 0s的延迟 无限次运动 运动完成回到最初位置 */}@keyframes move { //@keyframes做动画  animation播放动画0%, 100% {top: 300px;left: 400px;background: red;transform: scale(1);}25% {top: 0;left: 400px;background: green;transform: scale(1.5);}50% {top: 0;left: 800px;background: orange;transform: scale(1);}75% {top: 300px;left: 800px;background: blue;transform: scale(1.5);}}</style>
</head>
<body>
<div class="box" id="box"></div>
</body>
</html>
复制代码

13、动画库最后完整版封装

当前animate动画库执行的所有动画都是匀速运动动画(只有一个linear匀速运动公式),

接下来基于这个动画库去扩展支持非匀速运动的,非匀速运动的跟linear一样也需要有个运动公式才行

重点都在运动公式上 animationEffect封装的动画公式(来自flash源码里面的动画运动公式,比jquery封装的运动动画还要强大

参考网址 old.zhufengpeixun.cn/tween/

支持多运动回调函数的动画库完整封装=> 这里主要是运动公式

html

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title></title><link rel="stylesheet" href="css/reset.min.css"><style>.box {position: absolute;top: 300px;left: 400px;width: 100px;height: 100px;background: red;border-radius: 50%;}</style>
</head>
<body>
<div class="box" id="box"></div><script src="js/utils.js"></script>
<script src="js/animate.js"></script>
<script src="js/2-3.js"></script>
</body>
</html>
复制代码

animate.js

~function () {//=>封装CSS工具方法var utils = (function () {var isCompatible = 'getElementsByClassName' in document;function getCss(curEle, attr) {var value = null, reg = null;if (isCompatible) {value = window.getComputedStyle(curEle, null)[attr];} else {if (attr === 'opacity') {value = curEle.currentStyle['filter'];reg = /^alpha\(opacity=(.+)\)$/i;return reg.test(value) ? reg.exec(value)[1] / 100 : 1;}value = curEle.currentStyle[attr];}reg = /^-?\d+(.\d+)?(pt|px|rem|em)?$/i;return reg.test(value) ? parseFloat(value) : value;}function setCss(curEle, attr, value) {if (attr === 'opacity') {curEle.style.opacity = value;curEle.style.filter = 'alpha(opacity=' + value * 100 + ')';return;}!isNaN(value) && !/(fontWeight|lineHeight|zoom|zIndex)/i.test(attr) ? value += 'px' : null;curEle.style[attr] = value;}function setGroupCss(curEle, options) {if (Object.prototype.toString.call(options) !== '[object Object]') return;for (var attr in options) {if (options.hasOwnProperty(attr)) {setCss(curEle, attr, options[attr])}}}function css() {var len = arguments.length,type = Object.prototype.toString.call(arguments[1]),fn = getCss;len >= 3 ? fn = setCss : (len === 2 && type === '[object Object]' ? fn = setGroupCss : null)return fn.apply(this, arguments);}return {css: css}})();//=>封装动画公式:匀速运动和非匀速运动//http://old.zhufengpeixun.cn/tween/var animationEffect = {//匀速运动Linear: function (t, b, c, d) {return c * t / d + b;},Bounce: {//加速easeIn: function (t, b, c, d) {return c - animationEffect.Bounce.easeOut(d - t, 0, c, d) + b;},//减速easeOut: function (t, b, c, d) {if ((t /= d) < (1 / 2.75)) {return c * (7.5625 * t * t) + b;} else if (t < (2 / 2.75)) {return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;} else if (t < (2.5 / 2.75)) {return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;} else {return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;}},//先加速再减速easeInOut: function (t, b, c, d) {if (t < d / 2) {return animationEffect.Bounce.easeIn(t * 2, 0, c, d) * .5 + b;}return animationEffect.Bounce.easeOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b;}},Quad: {easeIn: function (t, b, c, d) {return c * (t /= d) * t + b;},easeOut: function (t, b, c, d) {return -c * (t /= d) * (t - 2) + b;},easeInOut: function (t, b, c, d) {if ((t /= d / 2) < 1) {return c / 2 * t * t + b;}return -c / 2 * ((--t) * (t - 2) - 1) + b;}},Cubic: {easeIn: function (t, b, c, d) {return c * (t /= d) * t * t + b;},easeOut: function (t, b, c, d) {return c * ((t = t / d - 1) * t * t + 1) + b;},easeInOut: function (t, b, c, d) {if ((t /= d / 2) < 1) {return c / 2 * t * t * t + b;}return c / 2 * ((t -= 2) * t * t + 2) + b;}},Quart: {easeIn: function (t, b, c, d) {return c * (t /= d) * t * t * t + b;},easeOut: function (t, b, c, d) {return -c * ((t = t / d - 1) * t * t * t - 1) + b;},easeInOut: function (t, b, c, d) {if ((t /= d / 2) < 1) {return c / 2 * t * t * t * t + b;}return -c / 2 * ((t -= 2) * t * t * t - 2) + b;}},Quint: {easeIn: function (t, b, c, d) {return c * (t /= d) * t * t * t * t + b;},easeOut: function (t, b, c, d) {return c * ((t = t / d - 1) * t * t * t * t + 1) + b;},easeInOut: function (t, b, c, d) {if ((t /= d / 2) < 1) {return c / 2 * t * t * t * t * t + b;}return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;}},Sine: {easeIn: function (t, b, c, d) {return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;},easeOut: function (t, b, c, d) {return c * Math.sin(t / d * (Math.PI / 2)) + b;},easeInOut: function (t, b, c, d) {return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;}},Expo: {easeIn: function (t, b, c, d) {return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;},easeOut: function (t, b, c, d) {return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;},easeInOut: function (t, b, c, d) {if (t == 0) return b;if (t == d) return b + c;if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;}},Circ: {easeIn: function (t, b, c, d) {return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;},easeOut: function (t, b, c, d) {return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;},easeInOut: function (t, b, c, d) {if ((t /= d / 2) < 1) {return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;}return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;}},Back: {easeIn: function (t, b, c, d, s) {if (s == undefined) s = 1.70158;return c * (t /= d) * t * ((s + 1) * t - s) + b;},easeOut: function (t, b, c, d, s) {if (s == undefined) s = 1.70158;return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;},easeInOut: function (t, b, c, d, s) {if (s == undefined) s = 1.70158;if ((t /= d / 2) < 1) {return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;}return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;}},Elastic: {easeIn: function (t, b, c, d, a, p) {if (t == 0) return b;if ((t /= d) == 1) return b + c;if (!p) p = d * .3;var s;!a || a < Math.abs(c) ? (a = c, s = p / 4) : s = p / (2 * Math.PI) * Math.asin(c / a);return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;},easeOut: function (t, b, c, d, a, p) {if (t == 0) return b;if ((t /= d) == 1) return b + c;if (!p) p = d * .3;var s;!a || a < Math.abs(c) ? (a = c, s = p / 4) : s = p / (2 * Math.PI) * Math.asin(c / a);return (a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b);},easeInOut: function (t, b, c, d, a, p) {if (t == 0) return b;if ((t /= d / 2) == 2) return b + c;if (!p) p = d * (.3 * 1.5);var s;!a || a < Math.abs(c) ? (a = c, s = p / 4) : s = p / (2 * Math.PI) * Math.asin(c / a);if (t < 1) return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;}}};//=>实现动画//=>必传参数:curEle/target//=>选传参数:duration/callBack/effect//1、以后封装方法的时候,如果当前方法需要传递很多值进来,我们一般都不会定义为一个个的形参,定义为一个个的形参会有很多问题://A:传递实参的顺序必须和定义的形参一一对应//B:如果中间少传递一项值,后面每一项的值都会错位,不方便扩展性//...//2、我们一般都采用传递一个参数集合的方式,把一些参数作为对象中的某一个属性值传递进来// animate({//     target: {top: 0},//     effect: animationEffect.Linear,//     curEle: oBox// });function animate(options) {//=>init parameter 初始化参数var _default = {curEle: null,target: {},duration: 1000,effect: animationEffect.Linear,callBack: null};// 传递进来的options覆盖_default默认值for (var key in options) {if (options.hasOwnProperty(key)) {_default[key] = options[key];}}//把需要用到的值都定义成一个个变量从_default拿出来var curEle = _default.curEle,target = _default.target,duration = _default.duration,effect = _default.effect,callBack = _default.callBack;//=>prepare准备 t/b/c/d  遍历target每一项把target每个方向的起始值和总距离算出来var time = null,begin = {},change = {};for (var attr in target) {if (target.hasOwnProperty(attr)) {begin[attr] = utils.css(curEle, attr);change[attr] = target[attr] - begin[attr];}}//=>move开始运动clearInterval(curEle.animateTimer);curEle.animateTimer = setInterval(function () {time += 17;if (time >= duration) {utils.css(curEle, target);clearInterval(curEle.animateTimer);callBack && callBack.call(curEle);//回调函数中的this都是当前元素curElereturn;}var curPos = {};//通过target目标值计算出每个方向的当前位置for (var key in target) {if (target.hasOwnProperty(key)) {curPos[key] = effect(time, begin[key], change[key], duration);//effect存的是运动公式}}utils.css(curEle, curPos);}, 17);}window.animate = animate;window.animateEffect = animationEffect;
}();复制代码

2-3.js

var oBox = document.getElementById('box');animate({curEle: oBox,target: {top: 0},duration: 500,effect: animateEffect.Bounce.easeOut,callBack: function () {//=>this:oBox 动画库中处理的//=>第二次运动animate({curEle: this,target: {left: 800},duration: 500,effect: animateEffect.Back.easeOut,callBack: function () {//=>第三次运动animate({curEle: this,target: {top: 300},duration: 500,effect: animateEffect.Elastic.easeOut,callBack: function () {//=>第四次运动animate({curEle: this,target: {left: 400},duration: 500});}});}});}
});
复制代码

14、for in循环遍历的一点细节问题

var obj = {name: '呵呵', age: 8};
for (var key in obj) {if (obj.hasOwnProperty(key)) {}
}
复制代码

为啥么每次for in循环要多加一个hasOwnProperty(key)?

Object.prototype.hasPubProperty = function hasPubProperty() {//验证是不是公有属性};/** for in*   不仅可以遍历当前对象(或者当前实例)所有的私有属性和方法,还可以把原型上自己创建的公共属性方法进行遍历** for*   只会遍历私有的属性和方法(更多的是索引),自己在原型上扩展的方法不会被遍历出来*/var obj = {name: '呵呵', age: 8};
for (var key in obj) {if (obj.hasOwnProperty(key)) { // 判断当前key这个属性是不是它的私有属性}
}// var ary = [12, 23, 34];
// for (var i = 0; i < ary.length; i++) {
//     console.log(ary[i]);
// }
//
// for (var key in ary) {
//     console.log(ary[key]);
// }复制代码

webstorm快捷键配置:

file -> setting -> editor -> live templates-javascript ->

TWEEN动画、JQUERY、ES6 — 1、定时器和TWEEN动画相关推荐

  1. android 左移动画_Android研究院之游戏开发Tween动画的实现(十九)

    今天和大伙讨论一下Android开发中的Tween动画的实现.首先它和上一章我们讨论的Frame动画同属于系统提供的绘制动画的方法.Tween动画主要的功能是在绘制动画前设置动画绘制的轨迹,包括时间, ...

  2. html首页 slider图片切换效果,jQuery插件Slider Revolution实现响应动画滑动图片切换效果...

    jQuery插件Slider Revolution实现响应动画滑动图片切换效果 2018-12-31 编程之家 https://www.jb51.cc 这是一款非常强大的内容切换插件,它基于jQuer ...

  3. JS JQuery实现简单的鼠标移动动画效果

    JS JQuery实现简单的鼠标移动动画效果 说明: 之前看到过很多别人写的的网页鼠标特效,感觉很炫酷. 但是那些都涉及到复杂的数学知识和逻辑,我没有能力写出类似的鼠标效果,于是我仿照一般的显示鼠标移 ...

  4. 开发工具与关键技术: 使用HTML 徽章 CSS3 动画 JQUERY 动态切换 JS自动切换

    开发工具与关键技术: HTML CSS3 JQUERY JS 作者:冉启东 撰写时间:2019年1月18日 1.使用HTML制作Contextual variations各种颜色类型的徽章代码如下: ...

  5. html自定义动画让元素下落,jQuery实现的模仿雨滴下落动画效果

    本文实例讲述了jQuery实现的模仿雨滴下落动画效果.分享给大家供大家参考,具体如下: 效果如图: 实现思路:定时器每隔x秒生成宽高.下落速度(即动画执行时间).left随机的div. 1.CSS: ...

  6. css3+jQuery制作导航菜单(带动画效果)

    <!DOCTYPE html> <html><head><meta charset="UTF-8"><title>css ...

  7. jquery实现:返回顶部(动画·代码精简版)- 代码篇

    jquery实现:返回顶部(动画·代码精简版):animate 使用css3的animate属性,一行代码就能实现功能. 动画演示(省略) 代码如下:(精简) <script type=&quo ...

  8. jQuery框架学习第七天:jQuery动画–jQuery让页面动起来!

    jQuery框架学习第一天:开始认识jQuery jQuery框架学习第二天:jQuery中万能的选择器 jQuery框架学习第三天:如何管理jQuery包装集 jQuery框架学习第四天:使用jQu ...

  9. 【jQuery笔记Part2】05-jQuery自定义动画

    jQuery自定义动画 简介 animate() 使用 操作多个属性 使用相对值 使用预定义的值 通过连缀或者顺序来实现列队动画 顺序写法 连缀写法 停止动画 延时动画 jQuery笔记目录 简介 j ...

最新文章

  1. 电子与通信工程专硕考分_2021西安电子科技大学电子与通信工程考研经验分享...
  2. Butter Knife 8.8.1的安装和使用
  3. sql server 2008 远程连接配置
  4. 【ArcGIS微课1000例】0006:创建随机点(Create Random Points)
  5. table 多行 宽度不一致_layui table 中固定列的行高和table行高不一致
  6. Mybatis 系列2-配置文件
  7. APIO/CTSC2017游记
  8. china-pub春季教材展,给力优惠,买二赠一
  9. PHP报错:Invalid body indentation level (expecting an indentation level of at least 4)
  10. 海量数据插入数据库的快速方案
  11. 酒店计算机系统管理实训,酒店管理信息系统实训课实践
  12. Office Tool Plus v8.2.4.0 安装Office组件小工具
  13. 高校学生社团管理系统
  14. python断言语句_Python断言assert的用法代码解析
  15. 大战略游戏:统治者:罗马 for Mac
  16. 青岛大学2020计算机考研录取名单,青岛大学复试录取名单 青岛大学2020年复试名单...
  17. 关于密码测评,你必须了解的10个基本问题
  18. 老年人怎么办理美国旅游签证?
  19. wow转服服务器不显示,魔兽世界怀旧服13日第二批免费转服详情 可以转服到哪些服务器?...
  20. 我的四周年创作纪念日

热门文章

  1. 计算机立方平方乘方的专用键,计算器的使用介绍课件.ppt
  2. 林家翘先生提醒青年学者:千万不要Garbage in,garbage out
  3. mdf是什么mysql_mdf是数据库文件吗
  4. opencv人脸检测+美颜
  5. js传参数受特殊字符影响错误
  6. 基于预训练模型 ERNIE 实现语义匹配
  7. SNN学习笔记-静息电位和平衡电位的理解
  8. linux ps le hrtime,前端Tips#4 - 用 process.hrtime 获取纳秒级的计时精度
  9. matlab 秒数转换时分秒,js 时分秒与秒数的转换
  10. (0091)iOS开发itms-services协议安装IPA安装包