金九银十,整理一下我遇到的那些手撕代码
queryURLParams
~ function() {
/**
* queryURLParams:根据URL地址问号后面的参数信息(可能包括hash值)
* @params
* @return
* [objact]把问号后面的参数信息用键值对的方式存储起来,并返回
* @example
* let url = "http://www.zhufengpeixun.cn/?lx=1&from=wx#video";
* {lx:1,from:'wx',HASH:'video'}
*/
function queryURLParams() {
let obj = {};
this.replace(/([^?#=&]+)=([^?#=&]+)/g, (...[, $1, $2]) => obj[$1] = $2);
this.replace(/#([^?#=&]+)/g, (...[, $1]) => obj['hash'] = $1);
return obj;
}
['queryURLParams'].forEach(item => {
String.prototype[item] = eval(item);
});
}();
var url = "http://www.zhufengpeixun.cn/?lx=1&from=wx#video";
console.log(url.queryURLParams());// {lx: "1", from: "wx", hash: "video"}
设置、解析、检测 cookie
// 设置cooike
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
var expires = "expires="+ d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
// 获取 cookie
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) === 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
// 检测 cookie
function checkCookie() {
var user = getCookie("username");
if (user != "") {
alert("Welcome again " + user);
} else {
user = prompt("Please enter your name:", "");
if (user != "" && user != null) {
setCookie("username", user, 365);
}
}
}
JavaScript 获取指定字符串中出现次数最多的单词及其出现次数
let article = "Age has reached the's end of the beginning of a word. May be guilty in his seems to passing a lot of different life became the appearance of the same day;";
function findMostWord(article){
// 使用trim()方法删除字符串的头尾空白符
article = article.trim();
// 利用正则取出所有单词存放于数组中
var array = article.match(/[A-z]+/g);
// 所有单词以空格间隔重新拼接
article = " " + array.join(" ") + " ";
var max = 0,
word,
num = 0,
maxword = "";
// 遍历拼接成的新字符串
for(var i = 0; i < array.length; i++) {
// 将所有的单词作为匹配项
word = new RegExp(" " + array[i] + " ", 'g');
// 相当于是统计每个单词的次数
num = article.match(word).length;
// 比较所有单词出现次数
if(num > max){
max = num;
maxword = array[i];
}
}
return {maxword,max}
}
console.log(findMostWord(article));
//打印结果:{ maxword: 'the', max: 4 }
螺旋遍历一个多维数组
function spiralOrder(matrix) {
const list = new Array();
if (matrix === null || matrix.length === 0 || matrix[0].length === 0) {
return list;
}
// m 是矩阵的行数
const m = matrix.length;
// n 是矩阵的列数
const n = matrix[0].length;
// 二位数组的层数,取决于行和列的较小值
const size = (Math.min(m, n) + 1) >> 1;
// 大循环,从外箱内逐层遍历矩阵
for (let i = 0; i < size; i++) {
// 从左到右遍历,上边
for (let j = i; j < n - i; j++) {
list.push(matrix[i][j]);
}
// 从上往下遍历,右边
for (let j = i + 1; j < m - i; j++) {
list.push(matrix[j][(n-1)-i]);
}
// 从右到做遍历,下边
for (let j = i + 1; j < n -i && (m - 1) - i > i; j++) {
list.push(matrix[(m - 1) - i][(n - 1) - j]);
}
// 从下到上遍历,左边
for (let j = i + 1; j < m - 1 - i && i < (n - 1) - i; j++) {
list.push(matrix[(m - 1) - j][i]);
}
}
return list;
}
const array = [
[1,2,3,4,5,6],
[7,8,9,10,11,12],
[13,14,15,16,17,18],
[19,20,21,22,23,24],
];
spiralOrder(array);
// 给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,
// 且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
// 思路:模拟矩阵的生成。按照要求,初始位置设为矩阵的左上角,初始方向设为向右。
// 若下一步的位置超出矩阵边界,或者是之前访问过的位置,则顺时针旋转,进入下一个方向。
// 如此反复直至填入 n2 个元素。
var generateMatrix = function(n) {
const maxNum = n * n;
let curNum = 1;
const matrix = new Array(n).fill(0).map(() => new Array(n).fill(0));
let row = 0,
column = 0;
const directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]; // 右下左上
let directionIndex = 0;
while (curNum <= maxNum) {
matrix[row][column] = curNum;
curNum++;
const nextRow = row + directions[directionIndex][0],
nextColumn = column + directions[directionIndex][1];
if (nextRow < 0 || nextRow >= n || nextColumn < 0 || nextColumn >= n || matrix[nextRow][nextColumn] !== 0) {
directionIndex = (directionIndex + 1) % 4;
// 顺时针旋转至下一个方向
}
row = row + directions[directionIndex][0];
column = column + directions[directionIndex][1];
}
return matrix;
};
写一个模板解析器
给 String 对象添加一个 render 方法,实现将字符串中铁定的字符替换为 obj 对应属性。
var greeting = 'My name is ${name}, age ${age}, I am a ${job.jobName}';
var employee = {
name: 'XiaoMing',
age: 11,
job: {
jobName: 'designer',
jobLevel: 'senior'
}
};
var result = greeting.render(employee);
console.log(result);
String.prototype.render = function(obj) {
// 利用了ES6的解构、对象keys新方法,在函数内部解构并自动展开变量
eval(`var {${Object.keys(obj).join(',')}} = obj`)
// 利用eval使字符串直接作为ES6解析
return eval('`' + this + '`')
}
String.prototype.render = function (obj) {
with(obj) {
return eval('`' + this + '`');
}
}
用 setTimeout 实现 setInterval
function myInterval(callback, timeout, number) {
const interval = function interval() {
if (typeof timeout === 'undefined' || number-- > 0) {
setTimeout(interval, timeout);
try {
callback.call(null);
} catch(e) {
number = 0;
throw e.toString();
}
}
}
setTimeout(interval, timeout)
}
myInterval(() => {
console.log(1);
}, 2000, 5)
function myInterval(callback, timeout, number) {
function interval() {
if (typeof number === 'undefined' || number -- > 0) {
setTimeout(interval, timeout);
try {
callback.call(null);
} catch (e) {
number = 0;
throw e.toString();
}
}
}
setTimeout(interval, timeout)
}
代码暂停指定的时间后在执行
class Sleep {
constructor(timeout) {
this.timeout = timeout;
}
then(resolve, reject) {
const startTime = Date.now();
setTimeout(() => {
resolve(Date.now() - startTime);
}, this.timeout)
}
}
(async () => {
// await命令后面是一个thenable对象(即定义了then方法的对象),那么await会将其等同于 Promise 对象。
const sleepTime = await new Sleep(1000);
console.log(sleepTime);
})()
代码隔一秒执行一次
function sleep(timeout) {
return new Promise((resolve) => {
setTimeout(resolve, timeout);
})
}
async function oneTimeRun() {
for(let i = 1; i <= 5; i++) {
console.log(i);
await sleep(1000);
}
}
异步模拟红绿灯
function sleep(target) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(target.color);
}, target.delay);
});
}
async function lightTransform(lights, number) {
const length = lights.length;
while(number > 0) {
for(let i = 0; i < length; i++) {
const item = lights[i];
const res = await sleep(item);
console.log(res);
}
}
number--;
}
//数据封装式的调用
lightTransform([
{color:"red",delay:1000},
{color:"green",delay:2000},
{color:"yellow",delay:3000}
], 3)
function red() {
console.log("red");
}
function green() {
console.log("green");
}
function yellow() {
console.log("yellow");
}
function sleep(callback, timeout) {
return new Promise((resolve, reject) => {
setTimeout(() => {
callback && callback();
resolve();
}, timeout);
});
}
function step() {
Promise.resolve()
.then(() => {
return sleep(red, 3000);
})
.then(() => {
return sleep(green, 2000);
})
.then(() => {
return sleep(yellow, 1000);
})
.then(() => {
step();
})
}
step();
写一个异步代码重试
function sleep(timeout) {
return new Promise((resolve) => {
setTimeout(resolve, timeout);
})
}
async function retry(request, timeout, number) {
try {
return await request();
} catch (e) {
console.log(e);
if (--number) {
await sleep(timeout);
retry(request, timeout, number);
}
}
}
retry(() => {
console.log(1);
}, 1000, 4);
retry(() => {
throw(new Error(1))
}, 1000, 4);
顺序合并 Promise 函数
const time = (timer) => {
return new Promise(resolve => {
setTimeout(() => {
resolve()
}, timer)
})
}
const ajax1 = () => time(2000).then(() => {
console.log(1);
return 1
})
const ajax2 = () => time(1000).then(() => {
console.log(2);
return 2
})
const ajax3 = () => time(1000).then(() => {
console.log(3);
return 3
})
function mergePromise (arrayAjax = []) {
// 在这里写代码
let promise = Promise.resolve();
const res = [];
arrayAjax.forEach((ajax) => {
promise = promise.then(ajax).then((v) => {
res.push(v);
return res;
});
});
return promise;
}
mergePromise([ajax1, ajax2, ajax3]).then(data => {
console.log("done");
console.log(data); // data 为 [1, 2, 3]
});
// 要求分别输出
// 1
// 2
// 3
// done
// [1, 2, 3]
封装一个异步加载加载图片的方法
funciton loadImg(url) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => {
resolve(img);
};
img.onerror = () => {
reject(new Error('Could not load image at' + url));
};
img.src = url;
});
}
限制异步操作的并发个数并尽可能快的完成全部
var urls = [
"https://p3-passport.byteimg.com/img/user-avatar/c37efaa9dc98a8e2ee6a9479579adbd2~180x180.awebp",
"https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/2/28/1708bf0e48b21309~tplv-t2oaga2asx-zoom-crop-mark:3024:3024:3024:1702.awebp",
"https://s0.lgstatic.com/i/image6/M01/5D/43/Cgp9HWFtEEOAFyUSAAHr8jHcqUk904.png",
"https://s0.lgstatic.com/i/image6/M00/5D/4C/CioPOWFtEDKABYx8AAHyO84vGUI482.png",
"https://p3-passport.byteimg.com/img/user-avatar/c37efaa9dc98a8e2ee6a9479579adbd2~180x180.awebp",
"https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/2/28/1708bf0e48b21309~tplv-t2oaga2asx-zoom-crop-mark:3024:3024:3024:1702.awebp",
"https://s0.lgstatic.com/i/image6/M01/5D/43/Cgp9HWFtEEOAFyUSAAHr8jHcqUk904.png",
"https://s0.lgstatic.com/i/image6/M00/5D/4C/CioPOWFtEDKABYx8AAHyO84vGUI482.png",
"https://p3-passport.byteimg.com/img/user-avatar/c37efaa9dc98a8e2ee6a9479579adbd2~180x180.awebp",
"https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/2/28/1708bf0e48b21309~tplv-t2oaga2asx-zoom-crop-mark:3024:3024:3024:1702.awebp",
"https://s0.lgstatic.com/i/image6/M01/5D/43/Cgp9HWFtEEOAFyUSAAHr8jHcqUk904.png",
"https://s0.lgstatic.com/i/image6/M00/5D/4C/CioPOWFtEDKABYx8AAHyO84vGUI482.png",
];
function loadImg(url) {
return new Promise((resolve, reject) => {
const timeout = 1000;
setTimeout(() => {
const img = new Image();
img.onload = function() {
console.log("一张图片加载完成", url);
resolve(img);
};
img.onerror = function() {
reject(new Error('Could not load image at' + url));
};
img.src = url;
}, timeout);
});
}
function limitLoad(urls, load, limit) {
return Promise.resolve().then(async() => {
let queue = [].concat(urls);
let promises = queue.slice(0, limit).map((url, index) => {
return load(url).then(() => {
return index;
})
});
let halfQueue = queue.slice(limit);
while(halfQueue.length > 0) {
console.log(halfQueue);
const fastIndex = await Promise.race(promises);
const url = halfQueue.shift();
promises[fastIndex] = load(url).then(() => {
return fastIndex;
});
}
return promises;
}).then(async (promises) => {
await Promise.all(promises);
}).catch((err) => {
console.log(err);
});
}
limitLoad(urls, loadImg, 3).then(() => {
console.log('图片全部加载完毕');
})
class limitPromise {
constructor(max) {
this._max = max;
this._taskQueue= []
}
addTask (tasks) {
this._taskQueue.push(...tasks)
}
run() {
if(this._taskQueue.length === 0) {
return
}
let min = Math.min(this._taskQueue.length,this._max);
for(let i = 0;i<min; i++) {
this._max--;
let task = this._taskQueue.shift()
task().then(res=>{
console.log(res)
}).finally(()=>{
// 任务结束开始下一轮
this._max++;
this.run()
})
}
}
}
const limitPromiseObj = new limitPromise(5);
limitPromiseObj.add([xxxxxxxx]);
解决倒计时误差
function myInterval(ms = 10000, time = 1000) {
var count = 0;
var startTime = new Date().getTime();
var timeCounter;
if (ms >= 0) {
timeCounter = setTimeout(countDownStart, time);
}
function countDownStart() {
count++;
var offset = new Date().getTime() - (startTime + count * time);
var nextTime = time - offset;
if (nextTime < 0 ) nextTime = 0;
ms -= time;
console.log('误差:' + offset + 'ms,下一次执行:' + nextTime + 'ms后,离活动开始还有:' + ms + 'ms');
if (ms < 0) {
clearTimeout(timeCounter);
} else {
timeCounter = setTimeout(countDownStart, nextTime);
}
}
}
手动实现 Promise
function resolvePromise(promise2,x,resolve,reject){
//判断x是不是promise
//规范中规定:我们允许别人乱写,这个代码可以实现我们的promise和别人的promise 进行交互
if(promise2 === x){//不能自己等待自己完成
return reject(new TypeError('循环引用'));
};
// x是除了null以外的对象或者函数
if(x !=null && (typeof x === 'object' || typeof x === 'function')){
let called;//防止成功后调用失败
try{//防止取then是出现异常 object.defineProperty
let then = x.then;//取x的then方法 {then:{}}
if(typeof then === 'function'){//如果then是函数就认为他是promise
//call第一个参数是this,后面的是成功的回调和失败的回调
then.call(x,y => {//如果Y是promise就继续递归promise
if(called) return;
called = true;
resolvePromise(promise2,y,resolve,reject)
},r => { //只要失败了就失败了
if(called) return;
called = true;
reject(r);
});
}else{//then是一个普通对象,就直接成功即可
resolve(x);
}
}catch (e){
if(called) return;
called = true;
reject(e)
}
}else{//x = 123 x就是一个普通值 作为下个then成功的参数
resolve(x)
}
}
class Promise {
constructor (executor){
//默认状态是等待状态
this.status = 'panding';
this.value = undefined;
this.reason = undefined;
//存放成功的回调
this.onResolvedCallbacks = [];
//存放失败的回调
this.onRejectedCallbacks = [];
let resolve = (data) => {//this指的是实例
if(this.status === 'pending'){
this.value = data;
this.status = "resolved";
this.onResolvedCallbacks.forEach(fn => fn());
}
}
let reject = (reason) => {
if(this.status === 'pending'){
this.reason = reason;
this.status = 'rejected';
this.onRejectedCallbacks.forEach(fn => fn());
}
}
try{//执行时可能会发生异常
executor(resolve,reject);
}catch (e){
reject(e);//promise失败了
}
}
then(onFuiFilled,onRejected){
//防止值得穿透
onFuiFilled = typeof onFuiFilled === 'function' ? onFuiFilled : y => y;
onRejected = typeof onRejected === 'function' ? onRejected : err => {throw err;}
let promise2;// 作为下一次then方法的promise
if(this.status === 'resolved'){
promise2 = new Promise((resolve,reject) => {
setTimeout(() => {
try{
// 成功的逻辑 失败的逻辑
let x = onFuiFilled(this.value);
// 看x是不是promise 如果是promise取他的结果 作为promise2成功的的结果
// 如果返回一个普通值,作为promise2成功的结果
// resolvePromise可以解析x和promise2之间的关系
// 在resolvePromise中传入四个参数,第一个是返回的promise,第二个是返回的结果,第三个和第四个分别是resolve()和reject()的方法。
resolvePromise(promise2,x,resolve,reject)
}catch(e){
reject(e);
}
},0)
});
}
if(this.status === 'rejected'){
promise2 = new Promise((resolve,reject) => {
setTimeout(() => {
try{
let x = onRejected(this.reason);
//在resolvePromise中传入四个参数,第一个是返回的promise,第二个是返回的结果,第三个和第四个分别是resolve()和reject()的方法。
resolvePromise(promise2,x,resolve,reject)
}catch(e){
reject(e);
}
},0)
});
}
//当前既没有完成也没有失败
if(this.status === 'pending'){
promise2 = new Promise((resolve,reject) => {
//把成功的函数一个个存放到成功回调函数数组中
this.onResolvedCallbacks.push( () =>{
setTimeout(() => {
try{
let x = onFuiFilled(this.value);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
},0)
});
//把失败的函数一个个存放到失败回调函数数组中
this.onRejectedCallbacks.push( ()=>{
setTimeout(() => {
try{
let x = onRejected(this.reason);
resolvePromise(promise2,x,resolve,reject)
}catch(e){
reject(e)
}
},0)
})
})
}
return promise2;//调用then后返回一个新的promise
}
catch (onRejected) {
// catch 方法就是then方法没有成功的简写
return this.then(null, onRejected);
}
}
Promise.all = function (promises) {
//promises是一个promise的数组
return new Promise(function (resolve, reject) {
let arr = []; //arr是最终返回值的结果
let i = 0; // 表示成功了多少次
function processData(index, data) {
arr[index] = data;
if (++i === promises.length) {
resolve(arr);
}
}
for (let i = 0; i < promises.length; i++) {
promises[i].then(function (data) {
processData(i, data)
}, reject)
}
})
}
Promise.allSeted = function allSeted(promises) {
return new Promise((resolve, reject) => {
let result = [];
let resolveCount = 0;
let length = promises.length;
for (let i = 0; i < length; i++) {
Promise.resolve(promise[i])
.then((data) => {
resolveCount++;
result[i] = {
status: 'fullfilled',
value: data
};
}, (reason) => {
resolveCount++;
result[i] = {
status: 'rejected',
reason
};
})
.finally(() => {
if (resolveCount >= i) {
resolve(result);
}
});
}
});
}
// 只要有一个promise成功了 就算成功。如果第一个失败了就失败了
Promise.race = function (promises) {
return new Promise((resolve, reject) => {
for (var i = 0; i < promises.length; i++) {
promises[i].then(resolve, reject)
}
})
}
// 生成一个成功的promise
Promise.resolve = function(value){
return new Promise((resolve,reject) => resolve(value);
}
// 生成一个失败的promise
Promise.reject = function(reason){
return new Promise((resolve,reject) => reject(reason));
}
// 代码重试
Promise.retry = function(fn, times, delay){
return new Promise((resolve, reject) => {
function retry(){
fn().then(() => {
resolve();
}).catch(() => {
times --;
(times <= 0) && reject();
setTimeout(retry, delay)
})
}
retry();
})
}
Promise.defer = Promise.deferred = function () {
let dfd = {};
dfd.promise = new Promise( (resolve, reject) => {
dfd.resolve = resolve;
dfd.reject = reject;
});
return dfd
}
module.exports = Promise;
Reduce 实现 map
//使用reduce实现map
//思路:1、判断传入的fn是否是一个函数,如果不是则抛出异常
//2、使用reduce进行拼接调用,最后返回
//3、this指向的是调用map的数组
Array.prototype.myMap = function(fn,thisArg = []){
//如果fn传入的不是一个函数则抛出异常
if(typeof fn != 'function'){
throw new Error(`${fn} is not a function`);
}
return this.reduce((pre,cur,index,arr) => {
return pre.concat(fn.call(thisArg,cur,index,arr));
},[])
}
const arr = [2,3,1,5];
const temp = arr.myMap(item => item * 2);
console.log(temp);
大数相乘
var multiply = function(num1, num2) {
const array = new Array(num1.length + num2.length).fill(0);
for (let i = 0; i < num1.length; i++) {
const n1 = Number(num1[num1.length - 1 - i]);
for(let j = 0; j < num2.length;j++) {
const n2 = Number(num2[num2.length - 1 -j]);
const x = array[i + j] + n1*n2;
array[i + j] = x % 10;
array[i + j + 1] += Math.floor(x / 10);
}
}
return array.reverse().join("").replace(/^0*/, "") || '0';
};
大数相加
let a = '9007199254740991';
let b = '1234567899999999999';
function add(a, b) {
let maxLength = Math.max(a.length, b.length);
a = a.padStart(maxLength, 0);
b = b.padStart(maxLength, 0);
// 进位存储
let f = 0;
let t = 0;
let sum = '';
for (let i = maxLength - 1; i >= 0; i--) {
// debugger;
t = parseInt(a[i]) + parseInt(b[i]) + f;
f = Math.floor(t / 10);
sum = t % 10 + sum;
// console.log(sum);
}
if (f == 1) {
sum = '1' + sum;
}
return sum;
}
console.log(add(a, b));
对象转换为平级 JSON
function flatten(obj) {
var res = {};
function func(obj, prop) {
var toString = Object.prototype.toString;
if (toString.call(obj).slice(8, -1) === 'Object') {
var isEmpty = true;
for (var key in obj) {
isEmpty = false;
func(obj[key], prop ? prop + '.' + key : key);
}
isEmpty && prop && (res[prop] = {});
} else if (toString.call(obj).slice(8, -1) === 'Array') {
var len = obj.length;
if (len > 0) {
obj.forEach((item, index) => {
func(item, prop ? prop + '.[' + index + ']' : index);
});
} else {
res[prop] = [];
}
} else {
res[prop] = obj;
}
}
func(obj, '');
return res;
}
Object.flatten = flatten;
数组转树
function listToTree(list) {
let map = new Map();
let result = [];
list.forEach((item) => {
if (!item.children) {
item.children = [];
}
map.set(item.id, item);
});
list.forEach((item) => {
const { pid } = item;
if (map.has(pid)) {
const value = map.get(pid);
value.children.push(item);
map.set(pid, value);
} else {
result.push(item);
}
});
return result;
}
树转数组
function treeToArray(tree) {
const obj = []
tree.forEach((item) => {
if (item.children) {
obj.push( item, ...item.children )
// ES6新增的 删除对象的属性 Reflect.deleteProperty(对象,属性名)
Reflect.deleteProperty(item,'children')
} else {
obj.push(item)
}
})
return obj
}
数组转换为千分位字符
let num = "15628954"; //=>"15,628,954" 千分符
// 把字符串倒过来加
num = num.split('').reverse().join('');
for (let i = 2; i < num.length - 1; i += 4) {
let prev = num.substring(0, i + 1),
next = num.substring(i + 1);
num = prev + "," + next;
}
num = num.split('').reverse().join('');
console.log(num);
function millimeter() {
return this.replace(/\d{1,3}(?=(\d{3})+$)/g, content => content + ',');
}
let number = 123450000;
let tag = number < 0;
number = Math.abs(number);
let record = [];
while(number > 1 ) {
let r = `000${number % 1000}`;
record.unshift(r.slice(-3));
number = Math.floor(number / 1000);
}
let res = `${tag ? '-' : ''}${record.join(',')}`;
console.log(res);
一个盒子从中间开始,碰到最左边的边界往右移动,碰到最右边的边界往左移动,如此循环,问怎么做?
<style>
body {
position: relative;
}
#box {
width: 50px;
height: 50px;
border: 5px solid black;
position: absolute;
left: 50%;
/* 为了实现水平居中,所以需要移动自身的50%宽度 */
transform: translateX(-50%);
animation: move linear 6s infinite;
}
@keyframes move {
0% {
left: 50%;
}
25% {
left: 0;
/* 必须覆盖上面的 translateX(-50%) */
transform: translateX(0);
}
75% {
left: 100%;
/* 如果不向左平移盒子的100%宽度,盒子就会超出屏幕 */
transform: translateX(-100%);
}
100% {
left: 50%;
}
}
body {display: flex;justify-content: center;}
#box {width: 50px;height: 50px;border: 5px solid black;animation: move 6s infinite linear;}
@keyframes move {
0% {transform: translateX(0);}
25% {transform: translateX(calc(-50vw + 50%));}
75% {transform: translateX(calc(50vw - 50%));}
100% {transform: translateX(0);}
}
<script>
const element = document.getElementById("box");
const bodyWidth = document.body.clientWidth;
const boxWidth = element.getBoundingClientRect().width;
let distance = Math.floor((bodyWidth - boxWidth) / 2);
console.log(distance);
let moveValue = 0;
let moveFlag = false;
function step() {
if (moveValue === -distance) {
moveFlag = true;
}
if (moveValue === distance) {
moveFlag = false;
}
if (moveFlag) {
moveValue += 1;
} else {
moveValue -= 1;
}
element.style.transform = "translateX(" + moveValue + "px)";
window.requestAnimationFrame(step);
}
window.requestAnimationFrame(step);
</script>
RGB 转 16 进制
const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8}|[0-9a-fA-f]{6}[0-9]{2})$/;
const rgbStr = 'rgb(000,255,255, 000)';
const str16 = '#ffffff';
if (reg.test(rgbStr)) {
// return rgbStr;
} else {
let strHex = "#";
const rgbArray = rgbStr.match(/([0-9])+/g);
console.log(rgbArray);
for(let i = 0; i < rgbArray.length; i++) {
const value = rgbArray[i];
if (i !== 3) {
if (value === '0') {
strHex+= "00";
} else {
let newItem = Number(value).toString(16);
if (newItem.length < 2) {
newItem = "0" + newItem;
}
strHex += newItem;
}
} else {
strHex += value == "0" ? "" : Number(value) * 100
}
}
console.log(strHex);
}
// 进制转换问题
var arr = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'];
function transform(str, base) {
var num = parseInt(str);
if (Object.is(num, NaN)) {
return '';
}
var res_arr = [];
while(num > 0) {
var res = num % base;
console.log(num);
num = Math.floor(num / base);
res_arr.unshift(res);
}
var res_str = '00';
res_arr.forEach(v => {
res_str += arr[v];
});
return res_str.slice(-2);
}
16进制转 RGB
set16ToRgb(str){
var reg = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/
if(!reg.test(str)){return;}
let newStr = (str.toLowerCase()).replace(/\#/g,'')
let len = newStr.length;
if(len == 3){
let t = ''
for(var i = 0; i < len; i++){
t += newStr.slice(i, i+1).concat(newStr.slice(i, i+1))
}
newStr = t
}
let arr = []; //将字符串分隔,两个两个的分隔
for(var i = 0;i < 6; i = i+2){
let s = newStr.slice(i, i+2)
arr.push(parseInt("0x" + s))
}
return 'rgb(' + arr.join(",") + ')';
}
set16ToRgb('#ffffff'); // rgb(255,255,0)
找出一个字符串中字符重复最多的次数
function maxContinueTimes(str){
if(str.length < 2) return str.length;
let maxTimes = 0, start = 0, str_map = new Map();
while(start < str.length){
let char = str[start];
let times = 1;
if(str_map.has(char)){
if(start > 0 && char === str[start - 1]){
times = str_map.get(char) + 1;
}
}
str_map.set(char, times);
maxTimes = Math.max(maxTimes, times);
start ++;
}
return maxTimes;
}
实现对象的可迭代
// 简单实现一个对象可迭代
// 在对象的原型上添加一个迭代器接口,使该对象可迭代
Object.prototype[Symbol.iterator] = function () {
return Object.values(this)[Symbol.iterator]();
};
let obj = {
name: "小红",
age: 18,
gender: "male",
bool: true,
num: 123,
};
for (let v of obj) {
console.log(v); // "小红" 18 "male" true 123
}
转载自:https://juejin.cn/post/7283403001494569001