分享18个实用的ECMAScript 6代码片段
最近在整理电脑的项目,总结了一些常见的小功能(获取URL、URL参数解析、Form表单数据解析等),特别的reduce方法的妙用。
1.如何批量隐藏指定的元素?
const hide = (...el) => [...el].forEach((e) => (e.style.display = "none"));
// 调用示例
hide(document.querySelectorAll("img"));
2.如何检查元素是否具有指定的类?
const hasClass = (el, className) => el.classList.contains(className);
// 调用示例
hasClass(document.querySelector("p.special"), "special"); // true
3.如何切换元素的样式类?
const toggleClass = (el, className) => el.classList.toggle(className);
// 调用示例
toggleClass(document.querySelector("p.special"), "special");
4.如何获取当前页面的滚动位置?
const getScrollPosition = (el = window) => ({
x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop,
});
// 调用示例
getScrollPosition(); // {x: 0, y: 100}
5.如何平滑滚动到页面顶部?
const scrollToTop = () => {
const scrollTop =
document.documentElement.scrollTop || document.body.scrollTop;
if (scrollTop > 0) {
window.requestAnimationFrame(scrollToTop);
window.scrollTo(0, scrollTop - scrollTop / 8);
}
};
// 调用示例
scrollToTop();
6.如何检查父元素是否包含子元素?
const elementContains = (parent, child) =>
parent !== child && parent.contains(child);
// 调用示例
elementContains(
document.querySelector("head"),
document.querySelector("title")
);
// true
elementContains(document.querySelector("body"), document.querySelector("body")); // false
7.如何检查指定的元素在视窗中是否可见?
const elementIsVisibleInViewport = (el, partiallyVisible = false) => {
const { top, left, bottom, right } = el.getBoundingClientRect();
const { innerHeight, innerWidth } = window;
return partiallyVisible
? ((top > 0 && top < innerHeight) ||
(bottom > 0 && bottom < innerHeight)) &&
((left > 0 && left < innerWidth) ||
(right > 0 && right < innerWidth))
: top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth;
};
// 调用示例
elementIsVisibleInViewport(el); // 不完全可见
elementIsVisibleInViewport(el, true); // 部分可见
8.如何获取元素中的所有图像?
const getImages = (el, includeDuplicates = false) => {
const images = [...el.getElementsByTagName("img")].map((img) =>
img.getAttribute("src")
);
return includeDuplicates ? images : [...new Set(images)];
};
// 调用示例
getImages(document, true); // ['image1.jpg', 'image2.png', 'image1.png', '...']
getImages(document, false); // ['image1.jpg', 'image2.png', '...']
9.如何确定该设备是移动设备还是桌面端?
const detectDeviceType = () =>
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
navigator.userAgent
)
? "Mobile"
: "Desktop";
// 调用示例
detectDeviceType(); // "移动端" or "桌面"
10.如何获取当前URL?
const currentURL = () => window.location.href;
// 调用示例
currentURL();
11.将URL参数解析为对象?
const getURLParameters = (url) =>
(url.match(/([^?=&]+)(=([^&]*))/g) || []).reduce(
(a, v) => (
(a[v.slice(0, v.indexOf("="))] = v.slice(v.indexOf("=") + 1)), a
),
{}
);
// 调用示例
getURLParameters("http://url.com/page?n=DevPoint&s=Shenzhen"); // {n: 'DevPoint', s: 'Shenzhen'}
getURLParameters("baidu.com"); // {}
12.如何将Form表单数据转为对象?
const formToObject = (form) =>
Array.from(new FormData(form)).reduce(
(account, [key, value]) => ({
...account,
[key]: value,
}),
{}
);
// 调用示例
formToObject(document.querySelector("#form")); // { city: 'Shenzhen', name: 'DevPoint' }
13.延迟执行函数(毫秒)?
const delay = (fn, wait, ...args) => setTimeout(fn, wait, ...args);
delay(
(text) => {
console.log(text);
},
1000,
"later"
);
14.如何删除DOM事件?
const off = (el, evt, fn, opts = false) =>
el.removeEventListener(evt, fn, opts);
const fn = () => console.log("!");
document.body.addEventListener("click", fn);
off(document.body, "click", fn);
15.如何将时间戳转为直观的时间格式?
const formatDuration = (ms) => {
if (ms < 0) ms = -ms;
const time = {
day: Math.floor(ms / 86400000),
hour: Math.floor(ms / 3600000) % 24,
minute: Math.floor(ms / 60000) % 60,
second: Math.floor(ms / 1000) % 60,
millisecond: Math.floor(ms) % 1000,
};
const timeZh = {
day: "天",
hour: "小时",
minute: "分钟",
second: "秒",
millisecond: "毫秒",
};
return Object.entries(time)
.filter((val) => val[1] !== 0)
.map(([key, val]) => `${val} ${timeZh[key]}`)
.join(",");
};
// 调用示例
formatDuration(1001); // 1 秒,1 毫秒
formatDuration(34325055574); // 397 天,6 小时,44 分钟,15 秒,574 毫秒
16.如何获得两个日期的时间差?
const getDaysDiffBetweenDates = (dateInitial, dateFinal) =>
(dateFinal - dateInitial) / (1000 * 3600 * 24);
// 调用示例,以天计算
getDaysDiffBetweenDates(new Date("2021-03-20"), new Date("2021-04-03")); // 14
17.如何将字符串复制到剪贴板?
const copyToClipboard = (str) => {
const el = document.createElement("textarea");
el.value = str;
el.setAttribute("readonly", "");
el.style.position = "absolute";
el.style.left = "-9999px";
document.body.appendChild(el);
const selected =
document.getSelection().rangeCount > 0
? document.getSelection().getRangeAt(0)
: false;
el.select();
document.execCommand("copy");
document.body.removeChild(el);
if (selected) {
document.getSelection().removeAllRanges();
document.getSelection().addRange(selected);
}
};
// 调用示例
copyToClipboard("DevPoint"); // 'DevPoint' copied to clipboard.
18.如何创建一个计数器?
指定一个DOM id,创建一个计数器,指定步长,结束数值,按照同样的频率计数。
const counter = (selector, start, end, step = 1, duration = 2000) => {
let current = start;
const _step = (end - start) * step < 0 ? -step : step;
const timer = setInterval(() => {
current += _step;
document.querySelector(selector).innerHTML = current;
if (current >= end) document.querySelector(selector).innerHTML = end;
if (current >= end) clearInterval(timer);
}, Math.abs(Math.floor(duration / (end - start))));
return timer;
};
// 调用示例
counter("#counter", 1, 1000, 5, 2000); // 创建一个计数器,从1开始,步长为5,计数到1000结束