Skip to content

Instantly share code, notes, and snippets.

@john-yuan
Created June 12, 2019 07:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save john-yuan/c3ec86965c391912c81d8ed2e32920d3 to your computer and use it in GitHub Desktop.
Save john-yuan/c3ec86965c391912c81d8ed2e32920d3 to your computer and use it in GitHub Desktop.
/**
* 将值转换为字符串并移除首尾空白字符
*
* @param {any} value 需要转换的值
* @returns {string}
*/
function toTrimedString(value) {
if (typeof value !== 'string') {
if (value === null || value === undefined) {
value = '';
} else {
value = '' + value;
}
}
return value.replace(/^\s+|\s+$/g, '');
}
/**
* 去重数组
*
* @param {string[]|number[]} values 字符串或数字数组
* @returns {string[]|number[]} 返回去重后的数组
*/
function removeMulti(values) {
const cache = {};
const prefix = '#';
const newValues = [];
for (let i = 0; i < values.length; i += 1) {
const value = values[i];
const key = prefix + value;
if (cache[key] !== true) {
newValues.push(value);
cache[key] = true;
}
}
return newValues;
}
/**
* 检查节点是否包含指定类名
*
* @param {Node} node 需要检查的节点
* @param {string} className 需要判断的类名(多个以空格隔开)
* @param {string} [mode=ALL] 判定模式:`ALL` 包含所有类名时返回成功,`ANY` 包含任一类名时返回成功
* @returns {boolean} 成功时返回 `true`,失败时返回 `false`
*/
function hasClass(node, className, mode) {
className = toTrimedString(className);
mode = toTrimedString(mode).toUpperCase();
if (mode !== 'ANY') {
mode = 'ALL';
}
if (!className) {
return true;
}
const nodeClassName = toTrimedString(node.className);
if (!nodeClassName) {
return false;
}
const classNames = className.split(/\s+/);
const nodeClassNames = nodeClassName.split(/\s+/);
if (mode === 'ALL') {
for (let i = 0; i < classNames.length; i += 1) {
let found = false;
// 查找当前类名是否存在
for (let j = 0; j < nodeClassNames.length; j += 1) {
if (classNames[i] === nodeClassNames[j]) {
found = true;
break;
}
}
// 如果不存在则返回 false
if (found === false) {
return false;
}
}
return true;
} else {
for (let i = 0; i < classNames.length; i += 1) {
// 查找当前类名是否存在
for (let j = 0; j < nodeClassNames.length; j += 1) {
// 任意一个存在则返回 true
if (classNames[i] === nodeClassNames[j]) {
return true;
}
}
}
return false;
}
}
/**
* 添加指定的类名
*
* @param {Node} node 需要添加类名的节点
* @param {string} className 需要添加的类名(多个以空格隔开)
*/
function addClass(node, className) {
const newClassName = toTrimedString(node.className) + ' ' + toTrimedString(className);
const newClassNames = newClassName.split(/\s+/);
const cleanClassNames = removeMulti(newClassNames);
if (cleanClassNames.length) {
node.className = cleanClassNames.join(' ');
} else {
node.className = '';
}
}
/**
* 移除指定的类名
*
* @param {Node} node 需要移除类名的节点
* @param {string} className 需要移除的类名(多个以空格隔开)
*/
function removeClass(node, className) {
const classNames = toTrimedString(className).split(/\s+/);
const nodeClassNames = toTrimedString(node.className).split(/\s+/);
const newClassNames = [];
const cache = {};
const prefix = '#';
classNames.forEach(value => {
const key = prefix + value;
cache[key] = true;
});
nodeClassNames.forEach(value => {
const key = prefix + value;
if (cache[key] !== true) {
newClassNames.push(value);
cache[key] = true;
}
});
if (newClassNames.length) {
node.className = newClassNames.join(' ');
} else {
node.className = '';
}
}
export default {
hasClass,
addClass,
removeClass
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment