前端常用代码片段

412 阅读3分钟

倒计时

window.onload = function(){
   showtime();
   function addZero(i){
       if(i<10){
           i = "0" + i;
       }return i;
   }
   function showtime() {
       var nowtime = new Date();
       var endtime = new Date("2016/05/20,20:20:20");
       var lefttime = parseInt((endtime.getTime() - nowtime.getTime()) / 1000);
       var d = parseInt(lefttime / (24 * 60 * 60));
       var h = parseInt(lefttime / (60 * 60) % 24);
       var m = parseInt(lefttime / 60 % 60);
       var s = parseInt(lefttime % 60);
       h = addZero(h);
       m = addZero(m);
       s = addZero(s);
       document.getElementById("contdown").innerHTML = "倒计时    " + d + ":" + h + ":" + m + ":" + s;
       if(lefttime<=0){
           document.getElementById("contdown").innerHTML = "活动已结束";
           return;
       } 
       setTimeout(showtime,1000);
   }
}

前端排序

let array=[
  {
    "id": 52354541,
    "name": "比率",
    "value": "55"
},
{
    "id": 43563123,
    "name": "比率比率",
    "value": "88"
},
{
    "id": 32525763,
    "name": "满意比率",
    "value": "76"
}];
array.sort(function(a, b){return a.value < b.value})[0].id ; // 52354541

代理对象

const ICONS = new Proxy({
  1: "iconfont iconassignsender",
  8: "iconfont iconhandle",
  16: "iconfont iconinspect1",
  32: "iconfont iconcomplete1"
}, {
  get(target, props) {
    if (!(props in target)) {
      return {}
    }
    return target[props];
  }
})
// 规定礼物的数据结构由type和value组成
const present = {
    type: '巧克力',
    value: 60,
}
 
// 为用户增开presents字段存储礼物
const girl = {
  // 姓名
  name: '小美',
  // 自我介绍
  aboutMe: '...'(大家自行脑补吧)
  // 年龄
  age: 24,
  // 职业
  career: 'teacher',
  // 假头像
  fakeAvatar: 'xxxx'(新垣结衣的图片地址)
  // 真实头像
  avatar: 'xxxx'(自己的照片地址),
  // 手机号
  phone: 123456,
  // 礼物数组
  presents: [],
  // 拒收50块以下的礼物
  bottomValue: 50,
  // 记录最近一次收到的礼物
  lastPresent: present,
}
 
// 掘金婚介所推出了小礼物功能
const JuejinLovers = new Proxy(girl, {
  get: function(girl, key) {
    if(baseInfo.indexOf(key)!==-1 && !user.isValidated) {
        alert('您还没有完成验证哦')
        return
    }
 
    //...(此处省略其它有的没的各种校验逻辑)
 
    // 此处我们认为只有验证过的用户才可以购买VIP
    if(user.isValidated && privateInfo.indexOf(key) && !user.isVIP) {
        alert('只有VIP才可以查看该信息哦')
        return
    }
  }
 
  set: function(girl, key, val) {
 
    // 最近一次送来的礼物会尝试赋值给lastPresent字段
    if(key === 'lastPresent') {
      if(val.value < girl.bottomValue) {
          alert('sorry,您的礼物被拒收了')
          return
      }
 
      // 如果没有拒收,则赋值成功,同时并入presents数组
      girl[lastPresent] = val
      girl[presents] = [...presents, val]
    }
  }
 
})
 

星期映射

function previewWeek(i){
    let weeksMap = new Map([
        [1, '一'],
        [2, '二'],
        [3, '三'],
        [4, '四'],
        [5, '五'],
        [6, '六'],
        [7, '日']
    ]);
    return weeksMap.get(i)?'星期'+weeksMap.get(i):''
}

生成月份

 [...new Array(13).keys()].slice(1).map(v => `${v}月`)

优化策略

function getPosition(direction){
    return ({
        left:"左",
        right:"右",
        top:"上",
        bottom:"下"
    })[direction] || "未知"
}

187****0573

console.log(String(new Date().getMonth() + 1));
let month = String(new Date().getMonth() + 1).padStart(2, '0');
console.log(month);

const centerPad = (c, n, f) => {
    const len = c.length;
    if (n < len) return c;

    return c.padStart(Math.floor((n - len) / 2) + len, f).padEnd(n, f.slice(-(Math.floor((n - len) / 2))));
}

console.log(centerPad('****',11,'18725510573'));

颜色

darken

/**
 *
 * @param color 16# rgb rgba color
 * @param pre 0.0 - 1.0
 * @return rgba
 */
const darken = (color: string, pre: number) => {
  if (typeis(color) !== 'string' || typeis(pre) !== 'number' || pre > 1) return color;

  const MAP = {
    'a': 10,
    'b': 11,
    'c': 12,
    'd': 13,
    'e': 14,
    'f': 15,
  }
  if (color.startsWith('#')) {
    if (color.length === 4) color = `#${color.slice(1).repeat(2)}`
    if (color.length !== 7) return color;

    const tmp = color
      .slice(1)
      .split('')
      .map(v => typeis(MAP[v.toLocaleLowerCase()]) === 'number' ? MAP[v.toLocaleLowerCase()] : +v)

    return `rgba(${[tmp[1]+ tmp[0] * 16, tmp[3]+ tmp[2] * 16, tmp[5]+ tmp[4] * 16, 1 - pre < 0 ? pre : 1 - pre].join(',')})`
  } else {
    const tmp = color.replace(/[^,.0-9]/ig,"").split(',').map(v => +v)
    const arr = tmp.length === 4 ? [...tmp, tmp[3] - pre < 0 ? pre : tmp[3] - pre] : [...tmp, 1 - pre < 0 ? pre : 1-pre]

    return `rgba(${arr.join(',')})`
  }
}

用法

const Base = ({ level, checked, handleClick }: P) => {
  return (
    <View
      className='level-btn-simple'
      onClick={() => { handleClick && handleClick(level) }}
      style={{
        color: getColor(LEVEL[level].color, checked),
        border: `1px solid ${getColor(LEVEL[level].color, checked)}`,
        background: darken(getColor(LEVEL[level].color, checked, '#f5f6f8'), checked ? 0.8 : 0),
      }}
    >
      <IconFont name={LEVEL[level].icon} color={getFaceColor(getColor(LEVEL[level].color, checked), '#fff')} size={50} />
      <Text>{LEVEL[level].type}{!!LEVEL[level].none ? '' : `(${LEVEL[level].tip})`}</Text>
    </View>
  )
}

export default Base;

React Hooks获取服务端数据

  useEffect(() => {
    const fetchData = async () => {
      try {
        const res = await queryBuildList({ ownerId })
        if (deviceId) {
          const ans = await detailBaidu(deviceId)

          setData(d => ({ ...d, ...ans.data }))
        }
        setTags(Array.isArray(res.data) ? res.data.map(v => ({ id: v.id, name: v.name })) : [])
      } catch (e) {
        Taro.showToast({
          "title": `${e.code}: ${e.errorMsg}`,
          icon: 'none',
          duration: 1500
        })
      }
    };
    fetchData();
  }, [ownerId, deviceId]);

简易的数据校验(提交表单全必填)

定义interface

export interface Item {
  serialNumber: string
  networkAddr: string
  fireHostPictures: Array<any>
  transmissionPictures: Array<any>
  installationAddr: string
  buildName: string
  floorName: string
  parsingRule: '1' | '2' | ''
}

定义给后端的字段

const KEY = [
  'serialNumber',
  'networkAddr',
  'fireHostPictures',
  'transmissionPictures',
  'buildName',
  'floorName',
  'installationAddr',
  'parsingRule'
]

校验

  const checkValid = (v) => {
    return KEY.map(r => v[r]).every(u => Array.isArray(u) ? u.length > 0 : !!u)
  }
     <View style={{ padding: '20px', marginTop: '10px' }}>
        <AtButton disabled={!checkValid(data)} type='primary' onClick={submit}>保存</AtButton>
      </View>

过滤无效值(undefined null等深过滤)

function dataType(obj) {
    if (obj === null) return "Null";
    if (obj === undefined) return "Undefined";
    return Object.prototype.toString.call(obj).slice(8, -1);
  };
  
  function dealElement(obj) {
    let param = {};
    if (obj === null || obj === undefined || obj === "") {
      return param;
    }
    for (let key in obj) {
      if (dataType(obj[key]) === "Object") {
        param[key] = dealElement(obj[key]);
      } else if (obj[key] !== null && obj[key] !== undefined && obj[key] !== "") {
        param[key] = obj[key];
      }
    }
    return param;
  };

图片

getURLParameters

const getURLParameters = url =>
  (url.match(/([^?=&]+)(=([^&]*))/g) || []).reduce(
    (a, v) => ((a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1)), a),
    {}
  );

result

objectToQueryString

const objectToQueryString = queryParameters => {
  return queryParameters
    ? Object.entries(queryParameters).reduce((queryString, [key, val], index) => {
      const symbol = queryString.length === 0 ? '?' : '&';
      queryString += typeof val === 'string' ? `${symbol}${key}=${val}` : '';
      return queryString;
    }, '')
    : '';
};

result

parseCookie

const parseCookie = str =>
  str
    .split(';')
    .map(v => v.split('='))
    .reduce((acc, v) => {
      acc[decodeURIComponent(v[0].trim())] = decodeURIComponent(v[1].trim());
      return acc;
    }, {});

result

参考链接