防抖
概念
若事件被频繁触发,防抖能保证只有最后一次触发生效,前面N多次的触发都会被忽略(也就是持续触发不执行,不触发一段时间后才执行,若在一段时间内频发触发,当前时间被清除,重新计时)
使用场景:
- 搜索框输入查询;
- 表单验证;
- 按钮提交事件;
- scroll事件滚动触发;
- 浏览器窗口缩放,resize事件
代码
效果图
index.html
<body>
<div class="box">
<!-- 搜索框和按钮 -->
<div class="search-box">
<input type="text" id="ipt" placeholder="请输入要搜索的内容" />
<button class="btnSearch">搜索</button>
</div>
<!-- 搜索建议 -->
<div id="suggest-list"></div>
</div>
<!-- 模板引擎 -->
<script type="text/html" id="tpl-suggestList">
{{each result}}
<div class="suggest-item">{{$value[0]}}</div>
{{/each}}
</script>
<script src="./jquery.js"></script>
<script src="./template-web.js"></script>
<script src="./index.js"></script>
</body>
index.css
#ipt {
width: 300px;
height: 20px;
outline: 0;
}
#suggest-list {
width: 300px;
display: none;
border: 1px solid #ccc;
padding-left: 5px;
}
.suggest-item:hover {
cursor: pointer;
background-color: skyblue;
color: red;
}
index.js
$(function () {
// 1防抖
// 1.1 定义延时器id
var timer = null
// 2 缓存数据列表
// 2.1 定义全局缓存对象
var cachObj = {}
// 1.2定义防抖函数
function debounceSearch(kw) {
timer = setTimeout(function () {
getSuggestList(kw)
}, 500)
}
$('#ipt').on('keyup', function () {
// 1.4 清空timer
clearTimeout(timer)
var keywords = $(this).val().trim()
// 用户未输入内容,返回
if (keywords <= 0) {
return $('#suggest-list').empty().hide()
}
// 2.3 如果缓存中有,从缓存里拿
if(cachObj[keywords]){
return renderSuggestList(cachObj[keywords])
}
// 1.3输入内容
debounceSearch(keywords)
})
// 发起请求,搜索框输入内容时,获取搜索建议(即下拉框相对应的内容)
function getSuggestList(kw) {
$.ajax({
url: 'http://127.0.0.1//sug?q=' + kw,
dataType: 'jsonp',
success: function (res) {
console.log(res)
renderSuggestList(res)
},
})
}
// 渲染ui结构
function renderSuggestList(res) {
if (res.result.length <= 0) {
return $('#suggest-list').empty().hide()
}
var htmlStr = template('tpl-suggestList', res)
$('#suggest-list').html(htmlStr).show()
// 2.2将搜索的结果,添加到缓存对象中
var k = $('#ipt').val().trim()
cachObj[k] = res
}
})
缓存数据
用户在输入框中输入两个内容,network发起两次请求,若删除一个内容,network会将未删除的内容再次重新发送一次请求,导致未删除内容重复发送,若很多资源出现同样情况造成服务器压力
注意:代码如上---->index.js中序号2所示
节流
概念
降低触发的频率,隔一段时间后才触发
使用场景
- DOM元素的拖拽功能实现
- 射击游戏类
- 计算鼠标移动的距离
- 监听scroll事件
代码
index.html
<img src="./images/fly.png" id="fly" alt="Image" />
index.css
#fly {
width: 500px;
height: 280px;
position: absolute;
cursor: pointer;
}
index.js
<script>
// 未设置节流阀情况
// $(function () {
// // 获取图片元素
// var fly = $('#fly')
// // 监听文档的 mousemove 事件
// $(document).on('mousemove', function (e) {
// // 设置图片的位置
// // console.log(e.pageX, e.pageY);鼠标一移动,位置跟随立马显示(很多次)
// $(fly).css('left', e.pageX + 'px').css('top', e.pageY + 'px')
// })
// })
// 设置节流阀
$(function () {
var fly = $('#fly')
// 1.定义timer 节流阀
var timer = null;
$(document).on('mousemove', function (e) {
if (timer) {
return
} // 3.判断节流阀是否为空,如果不为空,则证明距离上次执行间隔不足1秒
timer = setTimeout(function () {
$(fly).css('left', e.pageX + 'px').css('top', e.pageY + 'px')
// 2.设置鼠标跟随效果后,清空 timer 节流阀,方便下次开启延时器
timer = null ;
// console.log(e.pageX, e.pageY);鼠标一移动,位置出现频率相对减少
}, 1000)
})
})
</script>
效果
未设置节流阀