DOOFOX BLOG

10 月 29 2021 Category:

常用 JavaScript 工具函数合集

经常用到的JavaScript工具函数

标注指定 Dom 字符

使用指定的标签标注网页中的指定关键词. 可用于网页搜索\翻译等

export const markNodeValue = (nodes, findVal = '', tagName = 's-word') => {
	for (let i = 0; i < nodes.length; i++) {
		// 还原(移除)之前存在的 S-WORD 标签
		if (nodes[i].nodeName.toUpperCase() === tagName.toUpperCase()) {
			const parentNode = nodes[i].parentNode
			nodes[i].replaceWith(document.createTextNode(nodes[i].innerText))

			// 合并相邻的前后元素
			const prevNode = i === 0 ? null : parentNode.childNodes[i - 1]
			const nextNode = i === parentNode.childNodes.length - 1 ? null : parentNode.childNodes[i + 1]
			if (nextNode && nextNode.nodeName === '#text') {
				// 当前元素内容加上后一个元素内容,并删除后一个元素
				nodes[i].nodeValue += nextNode.nodeValue
				parentNode.removeChild(nextNode)
			}
			if (prevNode && prevNode.nodeName === '#text') {
				// 前元素内容加上当前元素,并删除当前元素
				prevNode.nodeValue += nodes[i].nodeValue
				parentNode.removeChild(nodes[i])
			}

			return markNodeValue(parentNode.childNodes, findVal, tagName)
		}

		// 给关键词添加 S-WORD 标签
		if (findVal && nodes[i].childNodes.length === 0 && nodes[i].nodeName === '#text' && nodes[i].nodeValue.indexOf(findVal) !== -1) {
			const html = nodes[i].nodeValue.replaceAll(findVal, `<${tagName}>${findVal}`)
			const tempNode = document.createElement('div')
			tempNode.innerHTML = html

			const tempNodeCount = tempNode.childNodes.length
			const originNode = nodes[i]
			while (tempNode.childNodes.length) {
				originNode.parentNode.insertBefore(tempNode.childNodes[0], originNode)
			}
			originNode.parentNode.removeChild(originNode)

			// 跳过新添加的 dom 元素
			i += tempNodeCount - 1
			continue
		}

		markNodeValue(nodes[i].childNodes, findVal, tagName)
	}
}

将 Blob 转为文件

const dataURLtoFile = (dataurl, filename) => {
	var arr = dataurl.split(','),
		mime = arr[0].match(/:(.*?);/)[1],
		bstr = window.atob(arr[1]),
		n = bstr.length,
		u8arr = new Uint8Array(n)

	while (n--) {
		u8arr[n] = bstr.charCodeAt(n)
	}

	return new File([u8arr], filename, { type: mime })
}

指定范围随机数

const rand = (min, max) => {
	return parseInt(Math.random()*(max - min + 1) + min, 10);
}
rand(1, 100);

获取DOM元素坐标

const getNodePosition = (o) => {
	let x = 0
	let y = 0
	while (o.offsetParent) {
		x += o.offsetLeft
		y += o.offsetTop
		o = o.offsetParent
	}
	return { 'x': x, 'y': y }
}

判断元素是否在可见区域

const isElementInVisibleArea = (elem) => {
	const viewport = {
		top: window.scrollY,
		left: window.scrollX
	}
	viewport.right = viewport.left + window.innerWidth
	viewport.bottom = viewport.top + window.innerHeight
	const width = elem.offsetWidth
	const height = elem.offsetHeight
	const bodyRect = document.body.getBoundingClientRect()
	const elemRect = elem.getBoundingClientRect()
	const bounds = {
		top: elemRect.top - bodyRect.top,
		right: '',
		bottom: '',
		left: elemRect.left - bodyRect.left
	}
	bounds.right = bounds.left + width
	bounds.bottom = bounds.top + height
	return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom))
}

判断一个地址是否是图片地址

const isImageUrl = (url) => {
	if (typeof url !== 'string') return false
	try {
		return /^(?:([^:/?#]+):)?(?:\/\/([^/?#]*))?([^?#]*\/)?([^?#]*\.([Jj][Pp][Ee]?[Gg]|[Pp][Nn][Gg]|[Gg][Ii][Ff]))(?:\?([^#]*))?(?:#(.*))?$/.test(url)
	} catch (e) {
		return false
	}
}
浙ICP备17013116号-1