js

作者: Young_Jeff | 来源:发表于2019-06-04 15:57 被阅读0次
(1)inputinput输入长度与限制内容
  • 生效的:
    <input type="text" maxlength="10" />
    <input type="tel" maxlength="10" />
// 允许由中文、数字、英文字母、标点符号组成
    event.target.value = event.target.value.replace(/[^0-9a-zA-Z\~!()_ +<>?:%,./;’,。、‘:“《?~!……()"'\u4E00-\u9FA5]/g, '')
    this.setState({
      data:event.target.value
    })
  • 未生效的
    <input type="number" maxlength="10" />
    解决办法:js控制
    <input type="number" oninput="if(value.length>10) value=value.slice(0,10)" />
(2)判断客户端是安卓或者ios
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
(3)判断访问终端
//判断访问终端
var browser={
    versions:function(){
        var u = navigator.userAgent, app = navigator.appVersion;
        return {
            trident: u.indexOf('Trident') > -1, //IE内核
            presto: u.indexOf('Presto') > -1, //opera内核
            webKit: u.indexOf('AppleWebKit') > -1, //苹果、谷歌内核
            gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1,//火狐内核
            mobile: !!u.match(/AppleWebKit.*Mobile.*/), //是否为移动终端
            ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios终端
            android: u.indexOf('Android') > -1 || u.indexOf('Adr') > -1, //android终端
            iPhone: u.indexOf('iPhone') > -1 , //是否为iPhone或者QQHD浏览器
            iPad: u.indexOf('iPad') > -1, //是否iPad
            webApp: u.indexOf('Safari') == -1, //是否web应该程序,没有头部与底部
            weixin: u.indexOf('MicroMessenger') > -1, //是否微信 (2015-01-22新增)
            qq: u.match(/\sQQ/i) == " qq" //是否QQ
        };
    }(),
    language:(navigator.browserLanguage || navigator.language).toLowerCase()
}
(4)判断一个对象是否为空

Object.keys()方法会返回一个由一个给定对象的自身可枚举属性组成的数组

var a = {}
Object.keys(a) // []
(5)pc动态设置容器高度
//生命周期里监听
componentWillMount() {
    window.addEventListener("resize", this.onResize);
  }
  componentWillUnmount() {
    window.removeEventListener("resize", this.onResize);
  }
//监听屏幕变化,延迟半秒执行,通过不断地删除定时器,达到只执行半秒内的最后一次高度获取并更新state
  onResize = () => {
    clearTimeout(this.st);
    this.st = setTimeout(() => {
      this.setState({
        height: getContentBoxHeight()
      });
    }, 500);
    return;
  };
//获取高度
function getContentBoxHeight() {
  return document.body.offsetHeight;
}
(6)js获取图片的真实宽高
let img = new Image();
img.src = url;  //  图片的url
img.onload = () => {
    let width = img.width;
    let height = img.height;
    console.log(width,height)
};
(7) js实现深拷贝
var deepCopy = function(obj) {
    if (typeof obj !== 'object') return;
    // // 根据obj的类型判断是新建一个数组还是对象
    var newObj = obj instanceof Array ? [] : {};
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
        }
    }
    return newObj;
}
(8) js前端加密文章

https://blog.csdn.net/qq_37346607/article/details/85237368

(9)js监听手机端点击物理返回键或js监听pc端点击浏览器返回键
setTimeout(() => {
    if (!(window.history.state && window.history.state.target === 'Final')) {
        window.history.pushState({ target: 'MeanSure', random: Math.random() }, '');
        window.history.pushState({ target: 'Final', random: Math.random() }, '');
      }
      window.addEventListener('popstate', ()=>{
          if (e.state && e.state.target === 'MeanSure') {
          //这里处理自己的逻辑
          }
      } false);
    }, 500);
(10)h5获取相机功能 and 拿到图片路径
  <input 
  onChange={this.getVlaue} 
  ref={(res) => this.input = res}  //  react非受控组件获取值
  type="file" accept="image/*" capture="camera">
  </input>
  getVlaue= () => {
   let refValue = this.input.files[0]  //  因为this.input.files拿到的是一个集合
  }

拿到的是一个对象,如图
然后把结果发送给服务器,获得一个线上绝对路径的图片地址


image.png
(11) h5调取数字键盘

<input type='tel' />
<input type='number' /> 针对ios或android可能不生效
所以,尝试加上pattern
<input type="number" pattern="\d">
<input type="number" pattern="[0-9]*">

(12) 基于axios的formData请求
import axios from 'axios';
export function getValue({payload}) {
  let formData = new FormData();  //  new出一个formData实例
  formData.append('file', value);  //  把值添加进去
  let instance = axios.create({ 
    headers: {
      'Content-Type': 'multipart/form-data'
    }
  });
  let result = instance.post('/api/upload, formData)
    .then(function (res) {
      if (res.data.code === 0) {
        return res
      } else {
        console.log('上传失败')
      }
    })
    .catch(function (error) {
      console.log(error);
    });
  return result
}

(13) 查看formData的值

formData.get("file")

(14) 覆盖antd Mobile默认样式

示例:InputItem

  • 打开控制台到Elements,找到要修改元素的当前节点

  • 查看其外层自动渲染的所有节点类型,和节点上的class控制器(即非自主手写的元素)

    image.png
  • 然后复制到本项目节点的外层

<div className='am-list-line'>
  <div className='am-input-control am-list-item '>
    <InputItem
        style={styleListInput}
    />
  </div>
</div>
  • 最后css文件中在这些 类选择器 上写样式即可(注意权重问题)
input {
  color: '#C2C2C2';
  padding-bottom: 10px;
}
.am-list-line {
  border: none;
  display: inline-block;
  width: 205px;
}
.am-input-control {
  display: inline-block;
  width: 205px;
  padding-bottom: 0;
  height: '55px';
  padding-left: 0;
}
.am-list-item .am-input-item {
  padding-left: 0;
  border: none;
}
.am-list-item .am-input-control input {
  padding-left: 0;
  font-size: 15px;
  color: #c2c2c2;
  border: none;
}
(15) 自适应布局
<script type="text/javascript">
      !(function(designWidth) {
        if (/Android(?:\s+|\/)(\d+\.\d+)?/.test(navigator.userAgent)) {
          var version = parseFloat(RegExp.$1);
          if (version > 2.3) {
            var phoneScale = parseInt(window.screen.width) / designWidth;
            document.write(
              '<meta name="viewport" content="width=' +
                designWidth +
                ',minimum-scale=' +
                phoneScale +
                ',maximum-scale=' +
                phoneScale +
                ', target-densitydpi=device-dpi">'
            );
          } else {
            document.write(
              '<meta name="viewport" content="width=' +
                designWidth +
                ',target-densitydpi=device-dpi">'
            );
          }
        } else {
          document.write(
            '<meta name="viewport" content="width=' +
              designWidth +
              ',user-scalable=no,target-densitydpi=device-dpi,minimal-ui,viewport-fit=cover">'
          );
        }
      })(375);
    </script>
(16) 引入高德地图API
  • index.html中引入
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=375, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
    />
    <title>demo</title>
    <style>
      #container {
        width: 100%;
        height: 100%;
      }
    </style>
  </head>
  <body>
    <div id="root"></div>
    <div id="container"></div>
    <script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.14&key=xxx"></script>
    <script src="index.js"></script>
  </body>
</html>
  • src下的js文件使用
    注意:js文件中通过window. 的方式才能拿到AMap对象!!!
componentDidMount() {
    var map = new window.AMap.Map('container', {
      resizeEnable: true
    });
    window.AMap.plugin('AMap.Geolocation', () => {
      var geolocation = new window.AMap.Geolocation({
          enableHighAccuracy: true,//是否使用高精度定位,默认:true
          timeout: 10000,          //超过10秒后停止定位,默认:5s
      });
      map.addControl(geolocation);
      geolocation.getCurrentPosition((status,result) => {
          if(status=='complete'){
              this.onComplete(result)
          }else{
              this.onError(result)
          }
      });
    });
    //解析定位结果
    this.onComplete = (data) => {
      this.props.dispatch({
        type: 'beginApply/getPostionInfo',
        payload: {
          positionInfo:data.position
        }
      });
    }
    //解析定位错误信息
    this.onError =( data) => {
      console.log('定位失败');
      this.setState({
        positionError: !this.state.positionError
      })
    }
  }
(17) 根据对象的属性值进行排序
2.png
(18) a标签调取手机通话功能
<a href="tel:10086">10086</a>
(19) 图片验证码的实现

点击图片 or 仓库状态改变而导致的页面重新渲染都会刷新图片验证码
HTML代码

<img src={`https://baidu.com:80/upload?randomString=${RandNum}`} alt="图片错误" />

js代码

// 随机数存到仓库里
    *getCheckCodePhoto({ payload }, { call, put }) {
      let RandNum = '';
      for (var i = 0; i < 12; i++) {
        RandNum += Math.floor(Math.random() * 10);
      }
      yield put({
        type: 'save',
        payload: {
          RandNum
        }
      })
    },

效果

image.png
(20) 监听浏览器的前进倒退按钮
window.addEventListener("popstate", function (e) { 
let a = 0; 
console.log('倒退按钮进来了', a++) 
 }, false);
(21) 监听手机物理键后退
setTimeout(() => {
      if (!(window.history.state && window.history.state.target === 'Final')) {
        window.history.pushState(
          { target: 'MeanSure', random: Math.random() },
          ''
        );
        window.history.pushState(
          { target: 'Final', random: Math.random() },
          ''
        );
      }
      window.addEventListener('popstate', backLJ, false);
    }, 500);
    return () => {
      window.removeEventListener('popstate', backLJ, false);
    };
const backLJ = (e: any) => {
    if (e.state && e.state.target === 'MeanSure') {
      props.history.push('/');
    }
  };
(22) js导出表格
import exportExcel from './exportExcel';
  const initColumn = [
  {
    title: "日期",
    dataIndex: "time",
    key: "time",
  },
  {
    title: "净值",
    dataIndex: "netValue",
    key: "netValue",
  },
  {
    title: "收益率(%)",
    dataIndex: "yieldRate",
    key: "yieldRate",
  },
];
// sourceData 原始数据 Arr
<Button
      type="primary"
      onClick={() => exportExcel(initColumn, sourceData)}>
      导出
</Button>
export function exportExcel(headers, data, fileName = "产品净值.xlsx") {
  const _headers = headers
    .map((item, i) =>
      Object.assign(
        {},
        {
          key: item.key,
          title: item.title,
          position: String.fromCharCode(65 + i) + 1,
        }
      )
    )
    .reduce(
      (prev, next) =>
        Object.assign({}, prev, {
          [next.position]: { key: next.key, v: next.title },
        }),
      {}
    );

  const _data = data
    .map((item, i) =>
      headers.map((key, j) =>
        Object.assign(
          {},
          {
            content: item[key.key],
            position: String.fromCharCode(65 + j) + (i + 2),
          }
        )
      )
    )
    // 对刚才的结果进行降维处理(二维数组变成一维数组)
    .reduce((prev, next) => prev.concat(next))
    // 转换成 worksheet 需要的结构
    .reduce(
      (prev, next) =>
        Object.assign({}, prev, { [next.position]: { v: next.content } }),
      {}
    );

  // 合并 headers 和 data
  const output = Object.assign({}, _headers, _data);
  // 获取所有单元格的位置
  const outputPos = Object.keys(output);
  // 计算出范围 ,["A1",..., "H2"]
  const ref = `${outputPos[0]}:${outputPos[outputPos.length - 1]}`;

  // 构建 workbook 对象
  const wb = {
    SheetNames: ["mySheet"],
    Sheets: {
      mySheet: Object.assign({}, output, {
        "!ref": ref,
        "!cols": [
          { wpx: 45 },
          { wpx: 100 },
          { wpx: 200 },
          { wpx: 80 },
          { wpx: 150 },
          { wpx: 100 },
          { wpx: 300 },
          { wpx: 300 },
        ],
      }),
    },
  };

  // 导出 Excel
  XLSX.writeFile(wb, fileName);
}
(23) 防抖截流
// 节流,一定时间内只执行一次,第一个人说了算
const throttle = (func, wait = 500) => {
 let lastTime = 0;
 return function (...args) {
   let now = new Date();
   if (now - lastTime > wait) {
     lastTime = now;
     func.apply(this,args);
   }
 };
};
// 防抖,完成后再统一执行,最后一个人说了算
const debounce = (func, wait = 500) => {
 let timer = 0;
 return function (...args) {
   if (timer) clearTimeout(timer);
   timer = setTimeout(() => {
     func.apply(this,args);
   }, wait);
 };
};

(24) 排序算法
// 冒泡排序
function bubbleSort(arr) {
  // 思路就是遍历数组,每次和右边的数字比大小,比之大就交换位置
  let length = arr.length;
  for (let i = 0; i <= length - 2; i++) {
    for (let j = i + 1; j <= length - 1; j++) {
      if (arr[i] > arr[j]) {
        [arr[i], arr[j]] = [arr[j], arr[i]];
      }
    }
  }
  return arr;
}
// console.log(bubbleSort(arr));
// 快速排序,利用二分法
// 会占用额外空间,不是最优解
function quickSort(arr) {
  // 1.找一个标志位
  // 2.数组切成两半
  // 3.对left和right,递归使用相同条件
  // 终止条件
  if (arr.length <= 1) return arr;
  let flag = arr.shift();
  let left = [];
  let right = [];
  for (let i = 0; i < arr.length; i++) {
    console.log(arr[i]);
    if (arr[i] < flag) {
      left.push(arr[i]);
    } else {
      right.push(arr[i]);
    }
  }
  return quickSort(left).concat(flag, quickSort(right));
}

// 原地快排,不会占用额外空间
let quickSort2 = (arr, low = 0, high = arr.length - 1) => {
  let left = low;
  let right = high;
  let flag = arr[left];
  if (low > high) return arr;
  while (left < right) {
    while (left < right && arr[right] > flag) {
      right--;
    }
    arr[left] = arr[right];
    while (left < right && arr[left] < flag) {
      left++;
    }
    arr[right] = arr[left];
  }
  arr[left] = flag;
  quickSort2(arr, low, left - 1);
  quickSort2(arr, left + 1, high);
  return arr;
};

相关文章

网友评论

      本文标题:js

      本文链接:https://www.haomeiwen.com/subject/egfrxctx.html