1 实现一个事件委托函数
<ul id="myul">
<li>这是第一个li</li>
<li>这是第二个li</li>
</ul>
var $ul = document.getElementById("myul");
$ul.addEventListener('click', function (e) {
if (e.target.tagName.toLowerCase() === "li") {
console.log("dayin")
}
}, false)
2 实现一个可以拖拽的DIV
实现拖动图片到矩形框中
#div1 {
width: 350px;
height: 70px;
padding: 10px;
border: 1px solid #aaaaaa;
}
<p>拖动 RUNOOB.COM 图片到矩形框中:</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<img id="drag1" src="/images/logo.png" draggable="true" ondragstart="drag(event)" width="336" height="69">
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("Text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
实现一个可以拖动的div
var dragging = false
var position = null
xxx.addEventListener('mousedown',function(e){
dragging = true
position = [e.clientX, e.clientY]
})
document.addEventListener('mousemove', function(e){
if(dragging === false) return null
const x = e.clientX
const y = e.clientY
const deltaX = x - position[0]
const deltaY = y - position[1]
const left = parseInt(xxx.style.left || 0)
const top = parseInt(xxx.style.top || 0)
xxx.style.left = left + deltaX + 'px'
xxx.style.top = top + deltaY + 'px'
position = [x, y]
})
document.addEventListener('mouseup', function(e){
dragging = false
})
3 函数节流和函数防抖
函数防抖:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
场景:
- 浏览器窗口大小resize避免次数过于频繁
- 登录,发短信等按钮避免发送多次请求
- 文本编辑器实时保存
function debounce(func, delay) {
var timeout;
return function(e) {
console.log("清除",timeout,e.target.value)
clearTimeout(timeout);
var context = this, args = arguments
console.log("新的",timeout, e.target.value)
timeout = setTimeout(function(){
console.log("----")
func.apply(context, args);
},delay)
};
};
var validate = debounce(function(e) {
console.log("change", e.target.value, new Date-0)
}, 380);
// 绑定监听
document.querySelector("input").addEventListener('input', validate);
函数节流:规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。
场景:
- scroll滚动事件,每隔特定描述执行回调函数
- input输入框,每个特定时间发送请求或是展开下拉列表,(防抖也可以)
function throttle(fn, threshhold) {
var timeout
var start = new Date;
var threshhold = threshhold || 160
return function () {
var context = this, args = arguments, curr = new Date() - 0
clearTimeout(timeout)//总是干掉事件回调
if(curr - start >= threshhold){
console.log("now", curr, curr - start)//注意这里相减的结果,都差不多是160左右
fn.apply(context, args) //只执行一部分方法,这些方法是在某个时间段内执行一次
start = curr
}else{
//让方法在脱离事件后也能执行一次
timeout = setTimeout(function(){
fn.apply(context, args)
}, threshhold);
}
}
}
var mousemove = throttle(function(e) {
console.log(e.pageX, e.pageY)
});
// 绑定监听
document.querySelector("#panel").addEventListener('mousemove', mousemove);
4 数组去重
var arr = [1, 1, 2, 3]
var arr = arr.reduce((init, cur) => init.includes(cur) ? init : [...init, cur], [])
// arr = arr.reduce((pre, cur) => pre.includes(cur) ? pre : [...pre, cur], []);
console.log(arr)
5 手写bind()
Function.prototype.mybind = function(context,...args){
return (...newargs)=>{
return this.call(context,...args,...newargs)
}
}
//测试
let cc = {
name: 'TianTian'
}
function say(something, other) {
console.log(`I want to tell ${this.name} ${something}`);
console.log('This is some' + other)
}
let tmp = say.mybind(cc, 'happy', 'you are kute')
let tmp1 = say.bind(cc, 'happy', 'you are kute')
tmp()
tmp1()