js理解和常用方法

451 阅读7分钟

js常用的几种数据转换方法

/* 16进制转bufer */
function hex2ab(hex) {
  let typedArray = new Uint8Array(hex.match(/[\da-f]{2}/gi).map(function(h) {
    return parseInt(h, 16)
  }))

  let buffer = typedArray.buffer
  return buffer
}

/* ArrayBuffer转16进度字符串示例 */
function ab2hex(buffer) {
  const hexArr = Array.prototype.map.call(
    new Uint8Array(buffer),
    function(bit) {
      return ('00' + bit.toString(16)).slice(-2)
    }
  )
  return hexArr.join('')
}
/* 16进制转ASCII码 */
function hexCharCodeToStr(hexCharCodeStr) {
  //前面干掉aa550200ed,后面干掉660a
  var trimedStr = hexCharCodeStr.trim();
  var rawStr = trimedStr.substr(0, 2).toLowerCase() === "0x" ? trimedStr.substr(2) : trimedStr;
  var len = rawStr.length;
  if (len % 2 !== 0) {
    console.log("存在非法字符!");
    return "";
  }
  var curCharCode;
  var resultStr = [];
  for (var i = 0; i < len; i = i + 2) {
    curCharCode = parseInt(rawStr.substr(i, 2), 16);
    resultStr.push(String.fromCharCode(curCharCode));
  }
  return resultStr.join("");
}
// 字符串转byte
function stringToBytes(str) {
  var bytes = [];
  var len, c;
  len = str.length;
  for (var i = 0; i < len; i++) {
    c = str.charCodeAt(i);
    if (c >= 0x010000 && c <= 0x10FFFF) {
      bytes.push(((c >> 18) & 0x07) | 0xF0);
      bytes.push(((c >> 12) & 0x3F) | 0x80);
      bytes.push(((c >> 6) & 0x3F) | 0x80);
      bytes.push((c & 0x3F) | 0x80);
    } else if (c >= 0x000800 && c <= 0x00FFFF) {
      bytes.push(((c >> 12) & 0x0F) | 0xE0);
      bytes.push(((c >> 6) & 0x3F) | 0x80);
      bytes.push((c & 0x3F) | 0x80);
    } else if (c >= 0x000080 && c <= 0x0007FF) {
      bytes.push(((c >> 6) & 0x1F) | 0xC0);
      bytes.push((c & 0x3F) | 0x80);
    } else {
      bytes.push(c & 0xFF);
    }
  }
  return bytes;

}
// byte转字符串
function byteToString(arr) {
  if (typeof arr === 'string') {
    return arr;
  }
  var str = '',
    _arr = arr;
  for (var i = 0; i < _arr.length; i++) {
    var one = _arr[i].toString(2),
      v = one.match(/^1+?(?=0)/);
    if (v && one.length == 8) {
      var bytesLength = v[0].length;
      var store = _arr[i].toString(2).slice(7 - bytesLength);
      for (var st = 1; st < bytesLength; st++) {
        store += _arr[st + i].toString(2).slice(2);
      }
      str += String.fromCharCode(parseInt(store, 2));
      i += bytesLength - 1;
    } else {
      str += String.fromCharCode(_arr[i]);
    }
  }
  return str;
}
// 中文转utf8byte
function writeUTF(str, isGetBytes = true) {
  var back = [];
  var byteSize = 0;
  for (var i = 0; i < str.length; i++) {
    var code = str.codePointAt(i);
    if (0x00 <= code && code <= 0x7f) {
      byteSize += 1;
      back.push(code);
    } else if (0x80 <= code && code <= 0x7ff) {
      byteSize += 2;
      back.push((192 | (31 & (code >> 6))));
      back.push((128 | (63 & code)))
    } else if ((0x800 <= code && code <= 0xd7ff)
      || (0xe000 <= code && code <= 0xffff)) {
      byteSize += 3;
      back.push((224 | (15 & (code >> 12))));
      back.push((128 | (63 & (code >> 6))));
      back.push((128 | (63 & code)))
    } else if ((0x10000 <= code && code <= 0x10ffff)) {
      byteSize += 4;
      back.push((240 | (7 & (code >> 18))));
      back.push((128 | (63 & (code >> 12))));
      back.push((128 | (63 & (code >> 6))));
      back.push((128 | (63 & (code))));
    }
  }
  for (i = 0; i < back.length; i++) {
    back[i] &= 0xff;
  }
  if (isGetBytes) {
    return back
  }
  if (byteSize <= 0xff) {
    return [0, byteSize].concat(back);
  } else {
    return [byteSize >> 8, byteSize & 0xff].concat(back);
  }
}
// byte换字符串支持中文版
function utf8ByteToUnicodeStr(utf8Bytes){
    var unicodeStr ="";
    for (var pos = 0; pos < utf8Bytes.length;){
        var flag= utf8Bytes[pos];
        var unicode = 0 ;
        if ((flag >>>7) === 0 ) {
            unicodeStr+= String.fromCharCode(utf8Bytes[pos]);
            pos += 1;

        } else if ((flag &0xFC) === 0xFC ){
            unicode = (utf8Bytes[pos] & 0x3) << 30;
            unicode |= (utf8Bytes[pos+1] & 0x3F) << 24;
            unicode |= (utf8Bytes[pos+2] & 0x3F) << 18;
            unicode |= (utf8Bytes[pos+3] & 0x3F) << 12;
            unicode |= (utf8Bytes[pos+4] & 0x3F) << 6;
            unicode |= (utf8Bytes[pos+5] & 0x3F);
            unicodeStr+= String.fromCharCode(unicode) ;
            pos += 6;

        }else if ((flag &0xF8) === 0xF8 ){
            unicode = (utf8Bytes[pos] & 0x7) << 24;
            unicode |= (utf8Bytes[pos+1] & 0x3F) << 18;
            unicode |= (utf8Bytes[pos+2] & 0x3F) << 12;
            unicode |= (utf8Bytes[pos+3] & 0x3F) << 6;
            unicode |= (utf8Bytes[pos+4] & 0x3F);
            unicodeStr+= String.fromCharCode(unicode) ;
            pos += 5;

        } else if ((flag &0xF0) === 0xF0 ){
            unicode = (utf8Bytes[pos] & 0xF) << 18;
            unicode |= (utf8Bytes[pos+1] & 0x3F) << 12;
            unicode |= (utf8Bytes[pos+2] & 0x3F) << 6;
            unicode |= (utf8Bytes[pos+3] & 0x3F);
            unicodeStr+= String.fromCharCode(unicode) ;
            pos += 4;

        } else if ((flag &0xE0) === 0xE0 ){
            unicode = (utf8Bytes[pos] & 0x1F) << 12;;
            unicode |= (utf8Bytes[pos+1] & 0x3F) << 6;
            unicode |= (utf8Bytes[pos+2] & 0x3F);
            unicodeStr+= String.fromCharCode(unicode) ;
            pos += 3;

        } else if ((flag &0xC0) === 0xC0 ){ //110
            unicode = (utf8Bytes[pos] & 0x3F) << 6;
            unicode |= (utf8Bytes[pos+1] & 0x3F);
            unicodeStr+= String.fromCharCode(unicode) ;
            pos += 2;

        } else{
            unicodeStr+= String.fromCharCode(utf8Bytes[pos]);
            pos += 1;
        }
    }
    return unicodeStr;
}
// arraybuffer -> blob
const blob = new Blob([new Uint8Array(buffer, byteOffset, length)]);
// ### **ArrayBuffer → base64**
const base64 = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));
// ### **base64 → blob**
const base64toBlob = (base64Data, contentType, sliceSize) => {
  const byteCharacters = atob(base64Data);
  const byteArrays = [];

  for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
    const slice = byteCharacters.slice(offset, offset + sliceSize);

    const byteNumbers = new Array(slice.length);
    for (let i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i);
    }

    const byteArray = new Uint8Array(byteNumbers);
    byteArrays.push(byteArray);
  }

  const blob = new Blob(byteArrays, {type: contentType});
  return blob;
}
// ### **blob → ArrayBuffer**
function blobToArrayBuffer(blob) { 
  return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = () => resolve(reader.result);
      reader.onerror = () => reject;
      reader.readAsArrayBuffer(blob);
  });
}
// ### **blob → base64**
function blobToBase64(blob) {
  return new Promise((resolve) => {
    const reader = new FileReader();
    reader.onloadend = () => resolve(reader.result);
    reader.readAsDataURL(blob);
  });
}
// ### **blob → Object URL**
const objectUrl = URL.createObjectURL(blob);

js/小程序判断地图坐标点是否在多边形区域内

function IsPtInPoly(aLat, aLon, pointList) {
    /* 
    :param aLon: double 经度 
    :param aLat: double 纬度 
    :param pointList: list [{latitude: 22.22, longitude: 113.113}...] 多边形点的顺序需根据顺时针或逆时针,不能乱 
    */
    var iSum = 0  
    var iCount = pointList.length
      
    if(iCount < 3) {
        return false 
    }
    for(var i = 0; i < iCount;i++) {
        var pLat1 = pointList[i].latitude  
        var pLon1 = pointList[i].longitude
        if(i == iCount - 1) {
            var pLat2 = pointList[0].latitude
            var pLon2 = pointList[0].longitude
        } else {
            var pLat2 = pointList[i + 1].latitude  
            var pLon2 = pointList[i + 1].longitude
        }
        if (((aLat >= pLat1) && (aLat < pLat2)) || ((aLat>=pLat2) && (aLat < pLat1))) {
            if (Math.abs(pLat1 - pLat2) > 0) {
                var pLon = pLon1 - ((pLon1 - pLon2) * (pLat1 - aLat)) / (pLat1 - pLat2);  
                if(pLon < aLon) {
                    iSum += 1 
                }
            }
        } 
    }
    if(iSum % 2 != 0) {
        return true  
    }else {
        return false 
    }  
}
module.exports = {
    IsPtInPoly: IsPtInPoly,
};

js计算两个经纬度之间的距离

// 方法定义 lat,lng 
function GetDistance( lat1,  lng1,  lat2,  lng2){
    var radLat1 = lat1*Math.PI / 180.0;
    var radLat2 = lat2*Math.PI / 180.0;
    var a = radLat1 - radLat2;
    var  b = lng1*Math.PI / 180.0 - lng2*Math.PI / 180.0;
    var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2) +
    Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2),2)));
    s = s *6378.137 ;// EARTH_RADIUS;
    s = Math.round(s * 10000) / 10000;
    return s;
}
// 调用 return的距离单位为km
GetDistance(10.0,113.0,12.0,114.0)

ArrayBuffer

理解地址

图片链接转base64方法

var xhr = new XMLHttpRequest()
xhr.open('get', this.dataForm.base64, true)
xhr.responseType = 'blob'
xhr.onload = function() {
  if (this.status === 200) {
    console.log(this)
    var blob = this.response // this.response也就是请求的返回就是Blob对象
    var reader = new FileReader()
    reader.readAsDataURL(blob)
    reader.onload = function(e) {
      // reader.result // 读取到的base64文件流
      that.imageUrl = reader.result
      that.dataForm.base64 = that.imageUrl.split(',')[1]
    }
    console.log(blob, 281)
  }
}
xhr.send()

element-ui上传图片转base64

handleAvatarSuccess(res, file) {
  var that = this
  console.log(res, file)
  console.log(URL.createObjectURL(file.raw))
  var reader = new FileReader()
  reader.readAsDataURL(file.raw)
  reader.onload = function(e) {
    // reader.result // 读取到的base64文件流
    that.imageUrl = reader.result
    that.dataForm.base64 = that.imageUrl.split(',')[1]
  }
  // console.log(reader, 200)
}

js获取截图的数据并转换为图片

原创链接

html

<div
  ref="paste"
  type="text"
  contenteditable="true"
  @paste.stop.prevent="pasteImg($event)"
/>

js

pasteImg(e) {
  console.log('获得剪切板的内容', e)
  const cbd = e.clipboardData
    const ua = window.navigator.userAgent
    // 如果是 Safari 直接 return
    if (!(e.clipboardData && e.clipboardData.items)) {
      return
    }
    if (cbd.items && cbd.items.length === 2 && cbd.items[0].kind === 'string' && cbd.items[1].kind === 'file' &&
        cbd.types && cbd.types.length === 2 && cbd.types[0] === 'text/plain' && cbd.types[1] === 'Files' &&
        ua.match(/Macintosh/i) && Number(ua.match(/Chrome\/(\d{2})/i)[1]) < 49) {
        return
    }
    for (let i = 0; i < cbd.items.length; i++) {
        const item = cbd.items[i]
        if (item.kind == 'file') {
          // blob 就是从剪切板获得的文件,可以进行上传或其他操作
          const blob = item.getAsFile()
          console.log('获得blob', blob)
          if (blob.size === 0) {
            return
          }
          const reader = new FileReader()
          const imgs = new Image()
          imgs.file = blob
          reader.onload = (function(aImg) {
            return function(e) {
              console.log('图片内容', e)
              console.log('获得粘贴的结果', e.target.result)
              aImg.src = e.target.result
            }
          })(imgs)
          reader.readAsDataURL(blob)
          this.$refs.paste.appendChild(imgs)
        }
    }
}

unicode 转换

// 转为unicode 编码  
function encodeUnicode(str) {  
    var res = [];  
    for ( var i=0; i<str.length; i++ ) {  
    res[i] = ( "00" + str.charCodeAt(i).toString(16) ).slice(-4);  
    }  
    return "\\u" + res.join("\\u");  
}  
  
// 解码  
function decodeUnicode(str) {  
    str = str.replace(/\\/g, "%");
    //转换中文
   str = unescape(str);
    //将其他受影响的转换回原来
   str = str.replace(/%/g, "\\");
    //对网址的链接进行处理
   str = str.replace(/\\/g, "");
   return str;
}

js前面自动补零

/**
* num传入的数字,n需要的字符长度
*/
function PrefixInteger(num, n) {
    return (Array(n).join(0) + num).slice(-n);
}

图片上传压缩js方法

/**
 * 图片压缩
 * @param {HTMLElement} image 创建的图片元素
 * @param {File} file File对象
 * @param {number} quality 图片压缩质量 0-1
 * @returns {Blob} Blob对象
 */
export function compressUpload(image, file, quality) {
  const canvas = document.createElement('canvas')
  const ctx = canvas.getContext('2d')
  const { width, height } = image
  canvas.width = width
  canvas.height = height
  ctx.fillStyle = '#fff'
  ctx.fillRect(0, 0, canvas.width, canvas.height)
  ctx.drawImage(image, 0, 0, width, height)
  const compressData = canvas.toDataURL('image/jpeg', quality || 0.7)
  const blobImg = dataURLtoBlob(compressData)
  return blobImg
}
/**
 * base64转换为Blob对象
 * @param {string} dataurl
 * @returns Blob
 */
export function dataURLtoBlob(dataurl) {
  var arr = dataurl.split(',')
  var mime = arr[0].match(/:(.*?);/)[1]
  // 解密base64
  var bstr = atob(arr[1])
  var n = bstr.length
  const u8arr = new Uint8Array(n)
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  return new Blob([u8arr], { type: mime })
}

CustomEvent

CustomEvent 事件是由程序创建的,可以有任意自定义功能的事件。

CustomEvent是一个构造函数, 可以创建一个自定义事件,可以用 window.dispatchEvent去主动触发这个自定义事件
使用示例:
实现localStorage 监听

  • localStorage.setItem监听:自定义事件 setItemEvent
  • localStorage.getItem监听:自定义事件 getItemEvent
  • localStorage.removeItem监听:自定义事件 removeItemEvent

//监听自定义事件 setItemEvent
localStorage.setItem = (Orgin=>{
    return function(key,value){
        let setItemEvent = new CustomEvent('setItemEvent',{detail:{setKey:key,value}})
        window.dispatchEvent(setItemEvent)
        Orgin.call(this,key,typeof value == 'string'? value : JSON.stringify(value))
    }
})(localStorage.setItem)

//监听自定义事件 getItemEvent
localStorage.getItem = (Orgin=>{
    return function(key){
        let result = JSON.parse(Orgin.call(this,key))
        let getItemEvent = new CustomEvent('getItemEvent',{detail:{getKey:key,value:result}})
        window.dispatchEvent(getItemEvent)
        return result 
    }
})(localStorage.getItem)


//监听自定义事件 removeItemEvent
localStorage.removeItem = (Orgin=>{
    return function(key){
        let removeItemEvent = new CustomEvent('removeItemEvent',{detail:{removeKey:key}})
        window.dispatchEvent(removeItemEvent)
        Orgin.call(this,key)
    }
})(localStorage.removeItem)

以上示例,我们对localStoragesetItemgetItemremoveItem在不影响本身的功能前提下进行了重写,让我们有了对这localStorage的这三个操作进行了监听的功能。
引用如有侵权请联系删除

前端原生js模拟form表单提交

function fromPost(URL, PARAMS) {
   var temp = document.createElement("form");
   temp.action = URL;
   temp.method = "post";
   temp.style.display = "none";
   temp.target="_blank" // 在另一个窗口打开
   for (var x in PARAMS) {
       var opt = document.createElement("textarea");
       opt.name = x;
       opt.value = PARAMS[x];
       opt.type="hidden"
       // alert(opt.name)
       temp.appendChild(opt);
   }
   document.body.appendChild(temp);
   temp.submit();
   return temp;
}