JavaScript学习笔记(七)高级定时器和自定义事件
1.重复定时器
当使用setInterval()时,仅当没有该定时器得任何其他代码实例时,才将定时器添加到队列中。
setTimeout(function() { var div = document.getElementById('myDiv') var left = parseInt(div.style.left) - 5 div.style.left = left + 'px' if (left > 200) { setTimeout(arguments.callee, 50) } }, 50)
2. Yielding Processes
代码运行超过特定的时间或者特定的语句数量时,浏览器会阻止其执行。
长时间运行的循环(可以分割成使用一系列定时器的小任务)
function chunk(array, process, context) { setTimeout(function() { var item = array.shift() process.call(context, item) if (array.length > 0) { setTimeout(arguments.callee, 100) } }, 100) } var data = [12, 123, 1234, 454, 344, 3212, 3123, 351] function printValue(item) { console.log(item) var div = document.getElementById('myDiv') var p = document.createElement('p') p.innerText = item div.appendChild(p) } chunk(data,concat(), printValue)
3. 函数节流
function throttle(method, context) { clearTimeout(method.tId) method.tId = setTimeout(function() { method.call(context) }, 100) } function resizeDiv() { var div = document.getElementById('myDiv') div.style.height = div.offsetWidth + 'px' } window.onresize = function() { throttle(resizeDiv) }
4. scrollWidth, clientWidth, offsetWidth
除了scrollTop和scrollLeft外其余的属性都是只读的
offsetWidth 包含边线
clientWidth 不包含边线
scrollWidth 包含边线(元素实际内容的宽度)
上述属性均返回数字。(不返回百分比)
5. 自定义事件
function EventTarget() { this.handlers = {} } EventTarget.prototype = { constructor: EventTarget, addHandler: function(type, handler) { if (this.handlers[type] === undefined) { this.handlers[type] = [] } this.handlers[type].push(handler) }, fire: function(event) { if (!event.target) { event.target = this } if (Array.isArray(this.handlers[event.type])) { var handlers = this.handlers[event.type] for (let index = 0; index < handlers.length; index++) { handlers[index](event) } } }, removeHandler: function(type, handler) { if (Array.isArray(this.handlers[type])) { var handlers = this.handlers[type] var hitIndex = handlers.findIndex(x => x === handler) handler.splice(hitIndex, 1) } } } function handleMessage(event) { console.log(event.message) } var target = new EventTarget() target.addHandler('message', handleMessage) target.fire({type: 'message', message: 'Hello World'}) target.removeHandler('message', handleMessage)