|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
例子: let cols = document.querySelectorAll('ul li') [].forEach.call(cols, function (col, index) { // TODO } 分析: ① []是一个空数组,无论这个数组里的最初值是什么,它们都不会被使用到; ② forEach方法是一个数组方法,只有数组才能调用;完整写法:Array.prototype.forEach,Array.forEach为简写; ③ call方法: 语法:fun.call(thisArg, arg1, arg2, ...) 参数:thisArg:在 fun 函数运行时指定的this值; arg1, arg2, ... : 指定的参数列表; 综上:[]这个空数组里的值(当然,它没有值)是最初的this值,通过call方法,当这个空数组调用方法forEach时, cols里的值会取代空数组原先的this值。 通俗的说,就是cols需要使用forEach这个方法, 但是这个方法是一个数组方法,只有数组才能调用,于是通过call方法来了个偷梁换柱, 在数组调用forEach方法的时候,将数组里的this值替换成了cols的值,达成了目的。 |
分类:JavaScript
Javascript异步编程
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
1、什么是异步(Asynchronous)编程? 相对于同步(Synchronous)而言,异步就是后一个任务不需要等待前一个任务结束就执行,而前一个任务结束以后执行回调函数。 最常见的异步编程有setTimeout函数、 ajax请求等。 如: for (var i = 1; i <= 3; i++) { setTimeout(function(){ console.log("#",i); }, 0); console.log("*",i); }; 输出的结果是:*1 *2 *3 #4 #4 #4 涉及到的知识点: 异步、闭包、作用域 setTimeout是一个注册事件,在主程序运行结束前,是不会调用的。 就像为某个div绑定一个点击事件一样,在没点击之前,这个事件是不会被触发的。 这就是一个常见的异步编程的例子。 2、异步编程的方法 Ⅰ、回调函数 假设有 f1(); f2(); 两个函数,其中f2()在等待f1()的执行结果。 function f1(f2){ setTimeout(function(){ f2(); }, 1000); } 代码执行顺序:f1(f2); 优点:f1不会堵塞程序运行,相当于先执行程序的主要逻辑,将耗时的操作推迟执行 缺点:不利于代码的阅读和维护,各个部分之间高度耦合(Coupling),而且每个任务只能指定一个回调函数 Ⅱ、事件监听 f1.on('done', f2);//jQuery写法,当f1发生done事件,就执行f2 function f1(){ setTimeout(function () { f1.trigger('done');//执行完成后,立即触发done事件 }, 1000); } 优点:可以绑定多个事件,每个事件可以指定多个回调函数,而且可以"去耦合"(Decoupling),有利于实现模块化 缺点:整个程序都要变成事件驱动型,运行流程会变得很不清晰 Ⅲ、发布/订阅 jQuery.subscribe("done", f2);//f2向jQuery订阅"done"信号 function f1(){ setTimeout(function () { jQuery.publish("done");//f1执行完成后,向jQuery发布"done"信号,从而引发f2的执行 }, 1000); } Ⅳ、Promises对象 它的思想是,每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。比如,f1的回调函数f2,可以写成: f1().then(f2); 对f1进行如下改写: function f1(){ var dfd = $.Deferred(); setTimeout(function () { dfd.resolve(); }, 500); return dfd.promise; } 优点:回调函数变成了链式写法,程序的流程可以看得很清楚,可以指定多个回调函数,如: f1().then(f2).then(f3); f1().then(f2).fail(f3); 缺点:编写和理解,都相对比较难 附几个概念: 一、事件 事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。 二、注册事件 注册事件分为属性注册和方法注册。 属性注册:1.内嵌在DOM结构里的属性赋值 HTML: <button onclick="sayHello()">点击</button> JS: function sayHello() { console.log('hello') } 2.通过JS来指定元素对象的属性赋值 document.body.onclick = function (e) { alert("为body注册一个点击事件"); }; 方法注册:1.通过addEventListener()方法注册 说明:在JS中,window、document、HtmlElement等对象可以通过addEventListener()方法注册事件的处理程序。 语法:EventTarget.addEventListener(eventName, eventHandler, |useCapture ) 参数: ①eventName {string} :所要注册的事件名称,不区分大小写。此名称不需要像注册事件属性那样前缀加上"on"。如注册鼠标点击事件,写为click。 ②eventHandler {function | function Object} :函数或者函数对象。事件触发时所需要执行的函数;当使用函数对象多次注册同一事件时,只当注册一遍。 ③useCapture {boolean} 可选 :是否处于捕获阶段,默认为false。 多次注册:addEventListener()方法能为同一个对象的同一事件注册多次。当发生此事件时,注册的处理事件程序将按照注册先后顺序执行。 注意: ①IE9之前的IE的不支持此方法,可使用attachEvent()代替。 ②若使用相同的事件处理程序对象多次注册在同一个事件上,只算注册一次。 例: document.body.addEventListener('click',function(e){ console.log('被点击一'); }); document.body.addEventListener('click',function(e){ console.log('被点击二'); }); document.body.click(); // 输出: 被点击一 被点击二 2.通过attachEvent()方法注册 说明:IE9之前的IE版本可通过此方法注册事件。 语法:EventTarget.attachEvent(eventName, eventHandler) ①eventName {string} :所要注册的事件名称,区分大小写。这里的名称跟事件属性一样,以"on"开头,后面跟着事件名称。如:onclick、onload。 ②eventHandler {function | function Object} :函数或者函数对象。事件触发时所需要执行的函数;当使用函数对象多次注册同一事件时,可注册多次(addEventListener()方法只当注册一次)。 多次注册:attachEvent()方法能为同一个对象的同一事件注册多次。当触发此事件时,也会依次执行。 例: function sayHellow(){ console.log('hello'); } document.body.attachEvent('onclick',sayHellow); document.body.attachEvent('onclick',sayHellow); // sayHellow第二次注册同一事件 document.body.click(); //输出2次sayHellow函数 :hello hello 二、注销事件 JS中,可调用removeEventListener()[注销addEventListener()] 和 detachEvent()[注销attachEvent()] 来注销元素的某个事件指定的处理程序,也可以给事件属性赋值null来注销此事件的所有绑定。 1.removeEventListener(eventName, function Object) 说明:注销通过addEventListener()注册的事件处理程序。 语法:EventTarget.removeEventListener(eventName, eventHandlerObj) 参数: ①eventName {string} :所要注销的事件名称,不区分大小写。此名称不需要像注册事件属性那样前缀加上"on"。如注册鼠标点击事件,写为click。 ②eventHandlerObj {function Object} :函数对象。传入一个函数体是没有效果的。 例: // 注销body click事件的sayHello函数 document.body.removeEventListener('click',sayHello); 2.detachEvent(eventName, function Object) 说明:注销通过attachEvent()注册的事件处理程序。 语法:EventTarget.detachEvent(eventName, eventHandlerObj) 参数: ①eventName {string} :所要注销的事件名称,区分大小写。这里的名称跟事件属性一样,以"on"开头,后面跟着事件名称。如:onclick、onload。 ②eventHandlerObj {function Object} ::函数对象。传入一个函数体是没有效果的。 例: // 注销body click事件的sayHello函数 document.body.detachEvent('onclick', sayHello); 3.取消事件 给对象的事件属性赋值为null,可取消此事件的所有注册过的处理事件程序。 例: // onclick属性赋值为null,相当于注销了onclick事件 document.body.onclick=null; |
参考链接: http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html
JS让任意图片垂直水平居中且页面不滚动
JS判断IE版本并在页面显示内容
禁止 iphone 网页上下拖动露底
判断当前系统当前浏览器是否安装启用 Adobe Flash Player,检查在chrome中的状态
一、判断当前所在系统
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
let sUserAgent = navigator.userAgent; let isWin = (navigator.platform == "Win32") || (navigator.platform == "Windows"); let isMac = (navigator.platform == "Mac68K") || (navigator.platform == "MacPPC") || (navigator.platform == "Macintosh") || (navigator.platform == "MacIntel"); if (isMac) return "Mac"; let isUnix = (navigator.platform == "X11") && !isWin && !isMac; if (isUnix) return "Unix"; let isLinux = (String(navigator.platform).indexOf("Linux") > -1); if (isLinux) return "Linux"; if (isWin) { let isWin2K = sUserAgent.indexOf("Windows NT 5.0") > -1 || sUserAgent.indexOf("Windows 2000") > -1; if (isWin2K) return "Windows2000"; let isWinXP = sUserAgent.indexOf("Windows NT 5.1") > -1 || sUserAgent.indexOf("Windows XP") > -1; if (isWinXP) return "WindowsXP"; let isWin2003 = sUserAgent.indexOf("Windows NT 5.2") > -1 || sUserAgent.indexOf("Windows 2003") > -1; if (isWin2003) return "Windows2003"; let isWinVista = sUserAgent.indexOf("Windows NT 6.0") > -1 || sUserAgent.indexOf("Windows Vista") > -1; if (isWinVista) return "WindowsVista"; let isWin7 = sUserAgent.indexOf("Windows NT 6.1") > -1 || sUserAgent.indexOf("Windows 7") > -1; if (isWin7) return "Windows7"; let isWin8 = sUserAgent.indexOf("Windows NT 6.2") > -1 || sUserAgent.indexOf("Windows 8") > -1; if (isWin8) return "Windows8"; let isWin10 = sUserAgent.indexOf("Windows NT 10.0") > -1 || sUserAgent.indexOf("Windows 10") > -1; if (isWin10) return "Windows10"; } return "OtherOS"; |
二、判断当前浏览器内核
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
let Sys = {}; let ua = navigator.userAgent.toLowerCase(); let s; (s = ua.match(/msie ([\d.]+)/)) ? Sys.ie = s[1] : (s = ua.match(/firefox\/([\d.]+)/)) ? Sys.firefox = s[1] : (s = ua.match(/chrome\/([\d.]+)/)) ? Sys.chrome = s[1] : (s = ua.match(/version\/([\d.]+).*safari/)) ? Sys.safari = s[1] : 0; if (Sys.ie) { console.log('ie core') } if (Sys.firefox) { console.log('gecko core') } if (Sys.chrome || Sys.safari) { console.log('webkit core') } |
三、判断浏览器是否安装 Adobe Flash Player
[crayon-698e832ccd947[……]
Js跑马灯效果 && 在Vue中使用
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
DEMO: <!DOCTYPE html> <html> <head> <title>滚动播报</title> <meta charset="UTF-8"> <style> .content { height: 60px; background-color: #2c2c34; overflow: hidden; } .content ul { white-space: nowrap; } .content ul li { position: relative; font-size: 14px; vertical-align: middle; line-height: 35px; padding: 0 8px; white-space: nowrap; display: inline-block; color: #fff } #scrollBox { overflow: hidden; } #scrollBox .scrollWrap { width: 500% } .scrollCont { float: left; } </style> </head> <body> <div class="content"> <ul> <div id="scrollBox"> <div class="scrollWrap"> <div id="scrollContOne" class="scrollCont"> <li>我是第一条数据</li> <li>我是第二条数据</li> <li>我是第三条数据</li> <li>我是第四条数据</li> <li>我是第五条数据</li> <li>我是第六条数据</li> <li>我是第七条数据</li> <li>我是第八条数据</li> </div> <div id="scrollContTwo" class="scrollCont"></div> </div> </div> </ul> </div> <script> let speed = 40 let scrollBox = document.getElementById("scrollBox"); let scrollContOne = document.getElementById("scrollContOne"); let scrollContTwo = document.getElementById("scrollContTwo"); scrollContTwo.innerHTML = scrollContOne.innerHTML; scrollBox.scrollLeft = 0; function scrollRadio() { if (scrollBox.scrollLeft >= scrollContTwo.offsetWidth) { scrollBox.scrollLeft -= scrollContOne.offsetWidth } else { scrollBox.scrollLeft += 2; } } let MyScrollRadio = setInterval(scrollRadio, speed); scrollBox.onmouseover = function() { clearInterval(MyScrollRadio) }; scrollBox.onmouseout = function() { MyScrollRadio = setInterval(scrollRadio, speed) }; </script> </body> </html> 在Vue中使用: <template> <div class="content"> <ul> <div id="scrollBox"> <div class="scrollWrap"> <div id="scrollContOne" class="scrollCont"> <li v-for="item in items"> <a href="{{item}" target="_blank"></a> </li> </div> <div id="scrollContTwo" class="scrollCont"></div> </div> </div> </ul> </div> </template> <style scoped> .content { height: 60px; background-color: #2c2c34; overflow: hidden; } .content ul { white-space: nowrap; } .content ul li { position: relative; font-size: 14px; vertical-align: middle; line-height: 35px; padding: 0 8px; white-space: nowrap; display: inline-block; } .content ul li a { text-decoration: none; color:#fff; } #scrollBox { overflow: hidden; margin-left: 36px; } #scrollBox .scrollWrap { width: 500% } .scrollCont { float: left; } </style> <script> export default { data: () => ({ canScrollTimer: 0 }), vuex: { getters: { scrollLists: state => state.scrollLists } }, watch:{ scrollLists:{ deep:true, handler(v,ov){ if(v.length){ this.run(); } } } }, methods: { run() { let speed = 40; let scrollBox = document.getElementById("scrollBox"); let scrollContOne = document.getElementById("scrollContOne"); let scrollContTwo = document.getElementById("scrollContTwo"); scrollContTwo.innerHTML = scrollContOne.innerHTML; scrollBox.scrollLeft = 0; function scrollRadio() { if (scrollBox.scrollLeft >= scrollContTwo.offsetWidth) { scrollBox.scrollLeft -= scrollContOne.offsetWidth } else { scrollBox.scrollLeft += 2; } } let MyScrollRadio = setInterval(scrollRadio, speed); scrollBox.onmouseover = function() { clearInterval(MyScrollRadio) }; scrollBox.onmouseout = function() { MyScrollRadio = setInterval(scrollRadio, speed) }; } }, ready() { //接口调用 } } </script> |
JS获取当前时间及时间戳相互转换
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
1.获取当前时间的 时间戳 Date.parse(new Date()) 结果:1486347562000 2.获取当前 时间 new Date() 结果:Mon Feb 06 2017 10:19:42 GMT+0800 (CST) 3.将 时间戳 转换成 时间 new Date(1486347562000) 结果:Mon Feb 06 2017 10:19:22 GMT+0800 (CST) 4.将 时间 转换成 时间戳 Date.parse(new Date("2017-02-06 10:30:50")) 结果:1486348250000 |
根据窗口大小改变悬浮窗显示方式并自动刷新页面
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
如果一个页面有个浮动的二维码,当页面窗口缩小时二维码会遮盖住页面内容,这时候可以根据浏览器大小来决定显示方式: 1.当页面宽度足够大时,完全显示二维码 2.当页面窗口缩小时,这时候需要显示一个按钮,点击按钮才显示二维码 这时候需要添加onresize来监听窗口变化,以此来刷新页面: window.onresize = function() { //监听窗口变化 window.location.reload(); //兼容chrome safari window.location.href = ""; //兼容火狐 } 至于上面二维码的显示方式,在 vue 里使用 v-show 实现非常方便: HTML: <!-- 按钮 --> <div class="qr-btn" v-show="qrBtn" @click="showQr"><img src="../assets/images/tangulunyin.jpg" alt="谈股论银"></div> <!-- 二维码 --> <div class="qr-code" v-show="qrCode"> <ul> <li><img src="../assets/images/yinruyi.png" alt="银如意" title="银如意"><span>扫描下载银如意app</span></li> <li><img src="../assets/images/tangulunyin.jpg" alt="谈股论银"><span>扫描关注谈股论银公众号</span></li> </ul> </div> CSS: .qr-btn { width: 30px; height: 30px; background-color: #064491; display: block; position: absolute; left: 20px; bottom: 50px; border-radius: 50%; box-shadow: 2px 2px 8px rgba(0, 0, 0, .6); cursor: pointer } .qr-btn>img { width: 20px; height: 20px; position: relative; top: 5px; display: block; padding: 0 auto; margin: 0 auto; } .qr-code { position: fixed; bottom: 10%; left: 1%; background-color: aliceblue; font-size: 12px; text-align: center; } .qr-code>ul>li { padding: .8em; } .qr-code>ul>li:last-child { margin: 0 0 1em 0; } .qr-code>ul>li>img { width: 130px; height: 130px; display: block; } VUE: export default { data:()=>({ qrCode: false, qrBtn: false }) }, methods:{ showQr() { if (this.qrCode == false) { this.qrCode = true; } else { this.qrCode = false; } } }, ready(){ let w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; let h = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; if (w < 1330) { //根据屏幕宽度决定是显示二维码还是按钮 this.qrCode = false; this.qrBtn = true; } else { this.qrCode = true; this.qrBtn = false; } window.onresize = function() { //监听窗口变化 window.location.reload(); //兼容chrome safari window.location.href = ""; //兼容火狐 } } ------------------------------------------------------------------- 以上的方法比较耗性能,而且不安全,另一个方法: VUE: export default { data:()=>({ qrCode: false, qrBtn: false }) }, methods:{ showQr() { if (this.qrCode == false) { this.qrCode = true; } else { this.qrCode = false; } }, listen() { let w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; if (w < 1330) { //根据屏幕宽度决定是显示二维码还是按钮 this.qrCode = false; this.qrBtn = true; } else { this.qrCode = true; this.qrBtn = false; } } }, ready(){ this.listen(); window.onresize = () => { //监听窗口变化 this.listen(); } } } |
ajax循环读取json多维数组
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
test.json: { "one": [ { "name": "黑默丁格", "car": "鲁LLL608", "mobil": "15666666666", "mount": "1", "time": "2016-07-13", "cat": "保养", "state": "有效", "message":"长安福特4S店温馨提醒:是时候给您的爱车去做保养了。" }, { "name": "EZ", "car": "鲁LLL608", "mobil": "15666666666", "mount": "1", "time": "2016-07-13", "cat": "保养", "state": "有效", "message":"长安福特4S店温馨提醒:是时候给您的爱车去做保养了。" } ], "two": [ { "name": "机器人", "car": "鲁LLL608", "mobil": "15666666666", "mount": "1", "time": "2016-07-13", "cat": "保养", "state": "有效", "message": "长安福特4S店温馨提醒:是时候给您的爱车去做保养了。" }, { "name": "贾克斯", "car": "鲁LLL608", "mobil": "15666666666", "mount": "1", "time": "2016-07-13", "cat": "保养", "state": "有效", "message":"长安福特4S店温馨提醒:是时候给您的爱车去做保养了。" } ] } |
ajax:

效果:

