JavaScript知识

本文最后更新于 2025年7月30日 下午

解析连接 URL

可以通过创建 a 标签,给 a 标签赋值 href 属性的方式,获取到协议、pathname、origin 等 location 对象上的属性。

1
2
3
4
5
6
7
8
9
10
const aEle = document.createElement("a");
aEle.href = "https://www.baidu.com/s?tn=68018901_2_oem_dg&ie=utf-8&wd=china";

aEle.protocol; // 'https:'
aEle.port; // ''
aEle.pathname; // '/s'
aEle.origin; // 'https://www.baidu.com'
aEle.host; // 'www.baidu.com'
aEle.hostname; // 'www.baidu.com'
aEle.search; // '?tn=68018901_2_oem_dg&ie=utf-8&wd=china'

复制文字到剪切板

参考:https://www.zhangxinxu.com/wordpress/2021/10/js-copy-paste-clipboard/

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
const execCommandCopy = () => {
const textarea = document.createElement("textarea");
document.body.appendChild(textarea);
// 隐藏此输入框
textarea.style.position = "fixed";
textarea.style.clip = "rect(0 0 0 0)";
textarea.style.top = "10px";
// 赋值
textarea.value = text;
// 选中
textarea.select();
// 复制
document.execCommand("copy", true);
// 移除输入框
document.body.removeChild(textarea);
};

// clipboard api
if (navigator.clipboard) {
navigator.clipboard.writeText(text).then(
(res) => {
console.log("res---", res);
},
(err) => {
console.log("err---", err);
execCommandCopy();
}
);
} else {
execCommandCopy();
}

防抖节流

参考:https://juejin.cn/post/6946022649768181774
Demo:防抖和节流

防抖

防抖:事件被触发 n 秒之后再执行函数。

如果在这 n 秒内事件又被触发,则重新计时 n 秒,之后再执行函数。加入了防抖以后,频繁触发事件并不会一直执行函数,只有在指定间隔内没有再次触发事件,才会执行对应的函数。

简单版

简单版:函数内部支持使用 this 和 event 对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function debounce(fun, wait) {
let context = this,
args = arguments,
timeout;
return function () {
if (timeout) clearTimeout(timeout);
timeout = setTimeout(function () {
fun.apply(context, args);
}, wait);
};
}
// 使用
function clickDeBounce() {
console.log(arguments);
console.log("这是简单版防抖函数");
}
const de = document.getElementById("de");
de.addEventListener("click", debounce(clickDeBounce, 3000), false);

升级版

升级版增加功能:

  • 支持立即执行
  • 函数可能有返回值
  • 支持取消功能
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
function debounce(func, wait, immediate) {
let context = this,
args = arguments,
timeout,
result;

let debounced = function () {
if (timeout) clearTimeout(timeout);
if (immediate) {
// 如果已经执行过,不再执行
let callNow = !timeout;
timeout = setTimeout(function () {
timeout = null;
}, wait);
if (callNow) result = func.apply(context, args);
} else {
timeout = setTimeout(function () {
func.apply(context, args);
}, wait);
}
return result;
};

debounced.cancel = function () {
clearTimeout(timeout);
timeout = null;
};

return debounced;
}
// 使用
let setUseAction = debounce(getUserAction, 3000, true);
node.onmousemove = setUseAction; // 使用防抖
setUseAction.cancel(); // 取消防抖

节流

节流:事件在 n 秒内最多只能执行一次函数。

事件第一次被触发立即执行函数,想要再次执行函数,需等待 n 秒,之后再次触发事件才能再次执行函数。在 n 秒内连续多次触发事件,只有第一次执行函数。加入了节流以后,触频繁发事件并不会一直执行函数,一段时间内只执行一次函数。

简单版

简单版:使用时间戳来实现,立即执行一次,然后每 N 秒执行一次。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function throttle(fun, wait) {
let context = this,
args = arguments,
previous = 0,
now;
return function () {
now = new Date();
if (now - previous > wait) {
fun.apply(context, args);
previous = now;
}
};
}
// 使用
function clickThrottle() {
console.log(arguments);
console.log("这是简单版节流函数");
}
const thro = document.getElementById("thro");
thro.addEventListener("click", throttle(clickThrottle, 3000), false);

升级版

升级版增加功能:支持取消节流;通过传入第三个参数,options.leading 来表示是否可以立即执行一次,opitons.trailing 表示结束调用的时候是否还要执行一次,默认都是 true。(注意设置的时候不能同时将 leading 或 trailing 设置为 false。)

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
function throttle(func, wait, options) {
let timeout, context, args, result;
let previous = 0;
if (!options) options = {};

let later = function () {
previous = options.leading === false ? 0 : new Date().getTime();
timeout = null;
func.apply(context, args);
if (!timeout) context = args = null;
};

let throttled = function () {
let now = new Date().getTime();
if (!previous && options.leading === false) previous = now;
let remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
func.apply(context, args);
if (!timeout) context = args = null;
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
};

throttled.cancel = function () {
clearTimeout(timeout);
previous = 0;
timeout = null;
};
return throttled;
}

总结

函数防抖和函数节流都是防止某一时间频繁触发,稀释函数的执行频率,但是原理不一样。

  • 防抖 debounce 结合应用场景
    • search 搜索联想,用户在不断输入值时,用防抖来节约请求资源。
    • window 触发 resize 时,不断的调整浏览器窗口大小会不断触发事件,用防抖来让只触发一次。
  • 节流 throttle 结合应用场景
    • 鼠标不断点击触发,mousedown(单位时间内只触发一次)。
    • 监听滚动事件,比如是否滑到底部自动加载更多,用节流来判断。

JavaScript知识
https://xuekeven.github.io/2022/10/24/JavaScript知识/
作者
Keven
发布于
2022年10月24日
更新于
2025年7月30日
许可协议