1.倒计时:
设置一个定时器,每秒执行一次函数(将改变倒计时的时间封装为一个函数),利用时间戳的差值得到剩余的总毫秒数,对其运算得到对应剩余的天数,时,分,秒,对得到的数据用parseInt()取整,还有补零,最后将数据追加到相应的元素内容中。
<div>
<h1>距离2023年春节: <span>xxx天 xx 时 xx 分 xx秒</span></h1>
</div>
<script>
var yearOfDate = new Date("2023-1-22").getTime();
setInterval(() => {
distance();
}, 1000);
distance();
function distance() {
var now = Date.now();
var offsetTime = (yearOfDate - now) / 1000;
// 获取天数据
var day = parseInt(offsetTime / (24 * 60 * 60));
// 时
// var hours = offsetTime % (24*60*60) / (60 * 60);
var hours = parseInt((offsetTime / (60 * 60) ) % 24);
// 分
var minutes = parseInt(offsetTime / 60 % 60);
// 秒
var seconds = parseInt(offsetTime % 60);
document.querySelector('span').innerText = `${addZero(day)} 天${addZero(hours)} 时 ${addZero(minutes)} 分 ${addZero(seconds)} 秒`;
}
// 补零
function addZero(num) {
return num > 10 ? num : "0" + num;
}
</script>
2.拖拽事件
指定了draggable属性的元素,才可以完成拖拽
<div class="move" draggable="true"></div>
开始拖拽事件:
document.querySelector('.move').ondragstart=function(){
//可对拖拽的对象设置传输数据,方便在目标元素的丢事件中得到对应的对象,将
//其添加到目标对象中
//transfer 传输
//p1: key p2:value
event.dataTransfer.setData("tdata",this.classname);
}
持续拖拽事件
move.ondragover = function () {
console.log("持续拖拽中.....");
}
结束拖拽事件:
move.ondragend = function () {
console.log("结束拖拽");
}
目标元素的拖拽事件:
进入:
document.querySelector('.box').ondragenter=funtion(){}
离开:
document.querySelector('.box').ondragleave=funtion(){}
drop丢进事件:
ondrop事件要想执行,
1.必须要给当前元素在ondragover事件中阻止默认事件
box.ondragover = function() {
event.preventDefault();
}
2.或给html元素在ondragover事件中阻止默认事件
document.documentElement.ondragover = function () {
event.preventDefault();
}
document.querySelector('.box').ondrop=funtion(){
//阻止外部文件拖入该元素 会在新窗口中打开
event.preventDefault();
//可将拖拽元素直接追加到该目标元素中
//this.appendChild(move);
//利用拖拽元素在开始拖拽事件中传输的数据,将其用key获取到该元素再对其进行
//追加操作
let data = event.dataTransfer.getData("tdata");
var el = document.querySelector('.'+data);
this.appendChild(el);
}
3.表格的拖拽
首先找到表格中所有所要的拖拽的对象trs,对其进行遍历添加可拖拽属性 (el.draggable = true;);在开始拖拽事件中设置传输数据,方便下面找到拖拽对象,利用冒泡给tbody添加ondrop丢事件,首先根据event.dataTransfer.getData('key')找到拖拽对象,再根据事件的触发者找到其父元素的下一个节点,再tbody的insertBefore()方法实现表格的插入( tbody.insertBefore(dragEl,targetEl);)。
<script>
var trs = document.querySelectorAll("tr:not(:first-child)");
var tbody = document.querySelector('tbody');
trs.forEach((el,index) => {
el.draggable = true;//遍历添加可拖拽属性
el.className = "t" + index;
el.ondragstart = function () {
event.dataTransfer.setData("move",this.className);//通过设置传输数据(key-value),方便下面通过类名找到拖拽对象
}
});
document.documentElement.ondragover = function () {
event.preventDefault();//阻止html的ondragover的默认事件
}
tbody.ondrop = function () {
// 1.获取拖动的元素
var cname = event.dataTransfer.getData("move");
var dragEl = document.querySelector("."+cname);
console.log("dragEl = ",dragEl);
// 2.目标元素 (放在谁的身上)
var targetEl = event.target.parentElement.nextElementSibling;
console.log("targetEl = ",targetEl);
if(targetEl == dragEl){
targetEl = event.target.parentElement;
}
// 把a插入在b的前面
// 如果b元素为空 则把a添加在 tbody的末尾
tbody.insertBefore(dragEl,targetEl);
}
</script>
4.函数的防抖和节流-------优化浏览器的性能
利用settimeout 降低事件的执行频率
4.1 防抖(debounce):当一个动作连续触发,只执行最后一次
连续的事件,只需触发一次回调的场景有:
搜索框搜索输入。只需用户最后一次输入完,再发送请求
手机号、邮箱验证输入检测
窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染
<input type="text" id="input">
<script>
// 1.函数的防抖 多次触发 只执行最后一次
// 先清除timer 再创建timer
// var timer = null;
// input.oninput = function () {
// clearTimeout(timer);
// // 会影响性能 每次都会执行发送网络请求
// // console.log("发起网络请求");
// timer = setTimeout(() => {
// console.log("发起网络请求");
// }, 1000);
// }
// 这样写是不可以的 因为debounce返回的是undefined
// 给input oniput 赋值undefined
// 后续的输入不会执行任何代码
// var timer = null;
// input.oninput = debounce(function () {
// console.log("发起网络请求")
// },1000)
// function debounce(cb,wait) {
// clearTimeout(timer);
// timer = setTimeout(() => {
// if(typeof cb == "function"){
// cb();
// }
// }, wait);
// }
// 1.
// var timer = null;
// input.oninput = function () {
// debounce(function () {
// console.log("发起网络请求")
// }, 1000);
// }
// function debounce(cb, wait) {
// clearTimeout(timer);
// timer = setTimeout(() => {
// if (typeof cb == "function") {
// cb();
// }
// }, wait);
// }
// 2.debounce 返回时一个函数 赋值给我 oninput事件
var timer = null;
input.oninput = debounce(function () {
console.log("发起网络请求")
}, 1000)
function debounce(cb, wait) {
return function () {
clearTimeout(timer);
timer = setTimeout(() => {
if (typeof cb == "function") {
cb();
}
}, wait);
}
}
</script>
4.2 节流(throttle):限制函数在一定时间内只执行一次
函数节流的应用场景
间隔一段时间执行一次回调的场景有:
滚动加载,加载更多或滚到底部监听
高频点击提交,表单重复提交
下拉加载更多
<input type="text" id="input">
<script>
// 节流 规定时间内只执行一次
// 定义全局变量 bool
// 1.
// var isStart = true;
// input.oninput = function () {
// if (isStart) {
// isStart = false;
// setTimeout(() => {
// console.log("发起网络请求");
// isStart = true;
// }, 2000)
// }
// }
// 2.
//
// var timer = null;
// input.oninput = function () {
// if (timer) return;
// timer = setTimeout(() => {
// console.log("发起网络请求");
// timer = null;
// }, 2000);
// }
// 3.通过时间戳
input.oninput = fn(function () {
console.log("发送网络请求");
},2000);
function fn(cb,wait) {
// 记录第一次的时间
var previous = Date.now();//3
console.log(previous)
return function () {
var current = Date.now();//6
if(current - previous >= wait){
if(typeof cb === "function"){
cb();
previous = current;
}
}
}
}
</script>
5.懒加载--优化网页性能
懒加载是一种对网页性能优化的方式,比如当访问一个页面的时候,优先显示可视区域的图片而不一次性加载所有图片,当需要显示时,再发送图片请求,避免打开网页时加载过多资源。
当一个网站的加载图片过多时就需要懒加载的协助,页面图片多时,在首次载入时一次性加载会耗费时间长,使用懒加载可以使页面加载速度快、减轻服务器的压力、节省流量。
图片懒加载的 逻辑 先找一个较小的图代替 当需要显示时把自定义属性的真实路径赋予图片的src实现懒加载的效果
原理: 滚动的 + 可视的 > 图片距离顶部的 替换src
<img src="./img/loading.gif" alt="" data-src="./img/1.jpg">
<script>
var img = document.querySelector("img");
var screenHeight = document.documentElement.clientHeight;
var imgTop = img.offsetTop;
window.onscroll = function () {
var sTop = document.documentElement.scrollTop;
if(sTop + screenHeight > imgTop + 500){
img.src = img.dataset.src;
}
}
图片的onload事件:
如果没有将获取图片的高度放入 onload事件中 默认为21px
原因是资源还没有加载 代码已经执行结束
行内元素默认高度为21px
可将懒加载函数放在window的onload事件中,或给图片直接设置好高
document.querySelector('img').onload = function () {
console.log(document.querySelector("div").clientHeight);
};
lazyload插件的使用:
<!-- 1.引入 lazyload 插件 -->
<script src="./lazyload.min.js"></script>
<script>
window.onload = function () {
var imgs = document.querySelectorAll("img");
for (let i = 0; i < imgs.length; i++) {
var img = imgs[i];
img.dataset.src = `./img/${i + 1}.jpg`;
// 2.指定类名
img.className = "lazyload";
}
//3.在onload中调用 lazyload方法
lazyload();
}
6.上传头像
在头像框的盒子里,添加type为file的input,给input加上accept属性,其值设为image/*,
<input type="file" name="" id="" accept="image/*">
将 input 用display:none;隐藏,给头像框的盒子绑定点击事件,用 input.click(); 触发 input的click事件,然后给input绑定onchange事件,里面再根据file对象来生成url地址,再将地址赋给框的背景图的地址
<p>上传头像:</p>
<div>
<span class="mask">
<span class="iconfont icon-shangchuan"></span>
上传头像
</span>
<!-- accept 只有file类型可以使用 image/ 接受所有的图片类型 -->
<input type="file" name="" id="" accept="image/*">
</div>
<script>
var div = document.querySelector('div');
var input = document.querySelector('input');
var mask = document.querySelector('.mask');
div.onclick = function () {
input.click(); // 触发 input的click事件
}
input.onchange = function () {
console.log(event.target.files[0]);
var file = event.target.files[0];
// 根据file对象来生成url地址
var url = URL.createObjectURL(file);
mask.style.display = "none";
div.style.backgroundImage = `url(${url})`;
}
</script>