Skip to content

JS常用方法

简述

整理常用的JS方法,做此记录

获取两个数组中不同的部分

js
function getdifferent(arrData1, arrData2) {
  return arrData1.concat(arrData2).filter((v, i, arr) => arr.indexOf(v) === arr.lastIndexOf(v));
}

将文件保存到本地

图片

js
    const aTag= document.createElement('a'); // 创建a标签
    aTag.download = 'test' + "." + 'jpg'; // 文件名和文件类型,可从File中获取
    aTag.href =base64; // 文件地址,图片base64也可
    aTag.click(); // 触发

文本

js
  const aTag = document.createElement('a') // 创建a标签
  aTag.download = 'style' + '.' + 'json' // 文件名和文件类型,可从File中获取
  aTag.href = 'data:text/plain;charset=utf-8,' + escape(JSON.stringify(style))
  aTag.click() // 触发

PS 2022.5.16 使用保存文本发生乱码问题,没有排查处哪里有问题,于是百度到了另一种方式,两者都保留,重复使用时,可以按情况都试一试

js
const aTag = document.createElementNS("http://www.w3.org/1999/xhtml", "a"); // 创建a标签
    aTag.download = "test1" + "." + "txt"; // 文件名和文件类型,可从File中获取
    aTag.href = window.URL.createObjectURL(new Blob([JSON.stringify(newData)]))
    aTag.click(); // 触发

json文件

js
					function saveAs(blob, fileName){
						// 创建隐藏的可下载链接
						const eleLink = document.createElement('a');
						eleLink.download = fileName;
						eleLink.style.display = 'none';
						// 字符内容转变成blob地址
						eleLink.href = URL.createObjectURL(blob);
						// 触发点击
						document.body.appendChild(eleLink);
						eleLink.click();
						// 然后移除
						document.body.removeChild(eleLink);
					}
          const blob = new Blob([JSON.stringify(res)], {
            type: "text/plain;charset=utf-8",
          });
          saveAs(blob, "fileName.json");

pdf文件

由于pdf文件会在部分浏览器上以直接打开的方式代替了原有的a标签下载的逻辑,所以上述触发a标签下载的方式并不适用全部浏览器

js
// url 为 pdf 地址
  axios.get(url, {
    responseType: 'blob',
    headers: {
      'Content-Type': 'application/octet-stream',
  },
  }).then((res) => {
    const blob = new Blob([res.data], { type: 'application/pdf' })
    const downloadElement = document.createElement('a')
    const href = window.URL.createObjectURL(blob)
    downloadElement.href = href
    downloadElement.download = 'xxx.pdf' // 下载后文件名
    document.body.appendChild(downloadElement)
    downloadElement.click() // 点击下载
    setTimeout(() => {
      document.body.removeChild(downloadElement) // 下载完成移除元素
      window.URL.revokeObjectURL(href) // 释放掉blob对象
    }, 1000);

在ios系统上,可能会出现Safari下载问题:无法完成操作。(webkitblobresource错误%1。) 所以需要在移出释放时添加一个延迟

导入本地文件

input标签获取FileList,取file

参考:FileReader

js
    const fileReader = new FileReader();
    fileReader.readAsDataURL(file); // 将读取以 base64 返回 如果是文本文件,则使用readAsText
    fileReader.onload=(e)=>{
      // do 异步读取后进行业务操作
    }

校验颜色值

校验以#、rgb、argb开头的颜色值是否标准

js
function checkColor(color){
  const color1 = /^#([0-9a-f]{6}|[0-9a-f]{3})$/i
  const color2 = /^rgb\(([0-9]|[0-9][0-9]|25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9])\,([0-9]|[0-9][0-9]|25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9])\,([0-9]|[0-9][0-9]|25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9])\)$/i
  const color3 = /^rgba\(([0-9]|[0-9][0-9]|25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9])\,([0-9]|[0-9][0-9]|25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9])\,([0-9]|[0-9][0-9]|25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9])\,(1|1.0|0.[0-9])\)$/i
  return color1.test(color) || color2.test(color) || color3.test(color);
}

hex值转rgb

该方法将0x开头的hex值转为rgb值,因为css color并不能直接使用这类值

js
const hexRgb = (value) => {
  let hex = value;
  hex = Math.floor(hex);
  const color = { r: '', g: '', b: '' };
  color.r = (hex >> 16 & 255);
  color.g = (hex >> 8 & 255);
  color.b = (hex & 255);
  return `rgb(${color.r},${color.g},${color.b})`;
}

scrollTo 兼容问题

在移动端浏览器中,scrollTo有的并不生效,需要做兼容处理

js
if (!window.scrollTo) {
  window.scrollTo = (option) => {
    window.scrollLeft = option.left;
    window.scrollTop = option.top;
  };
}

if (!document.body.scrollTo) {
  Element.prototype.scrollTo = (option) => {
    this.scrollLeft = option.left;
    this.scrollTop = option.top;
  };
}

经反复测试,上述方法不一定是问题原因的所在,最简的判别办法是给scrollTop加一个延时处理,如果延时能够缩放,那上述方法并不管用,尽管在vue的nextTick中调用它,但他仍有可能在某些浏览器上失效,所以最好的办法是加一个100-200毫秒的延迟 造成这个的原因,个人猜测是nextTick(vue2)在某些浏览器中并不是所有文档流加载完成。

js监听屏幕横竖屏变化

js
//通过监听窗口尺寸变化,判断是否是横竖屏,从而知道是否发生变化
    window.addEventListener('resize', () => {
      const orientation = (window.innerWidth > window.innerHeight) ? 'landscape' : 'portrait';
      if (orientation === 'portrait') {
        console.log('竖屏');
      } else {
        console.log('横屏');
      }
    }, false);
js
// 也可以用这个方法获取横竖屏状态,但是该方法处于实验性技术,兼容较差
var orientation = window.screen.orientation;

判别一些监听事件浏览器是否支持

js
// 利用监听事件是否是为undefined判断
// 比如scrollend在safari里不支持,就可以使用这个去判别
// 要注意的是,没有监听但支持的事件会返回null,用addEventLisnter去监听的返回的也会是null
window.onxxx === undefined; // true 为支持 // false为不支持
// 这里window可以换成其他element
getEventListeners(window) // 返回一个当前正在监听的事件,支持但没有监听的不会显示

滚动到指定位置

考虑到移动端的各种情况,如果直接使用dom元素计算高度可能会出现各种问题,所以建议采用直接获取到要滚动的元素的offsetTop

我的功能场景如下:

  1. 横竖屏切换后定位仍是正确的
  2. 图片的宽高比不一
  3. 适配各机型浏览器
  4. 一进入页面就要定位
js
    // 监听当前浏览的是哪个元素,并在滚动结束事件时记录下来
    // 这样在横竖屏切换时仍能正确找到
    window.addEventListener('scrollend', () => {
        this.viewElement = document.elementFromPoint(window.innerWidth / 2, window.innerHeight / 2)
    })
    // 由于safari浏览器不支持scrollend,需要自己实现
    if (window.onscrollend === undefined) {
      let scrollTime;
      window.addEventListener('scroll', () => {
        if (this.resizeing) return;
        if (scrollTime) {
          clearTimeout(scrollTime);
        }
        scrollTime = setTimeout(() => {
          this.viewElement = document.elementFromPoint(window.innerWidth / 2, window.innerHeight / 2)
        }, 200)
      })
    }
    // 监听横竖屏切换,也可以监听orientationchange
    window.addEventListener('resize', () => {
      const orientation = (window.innerWidth > window.innerHeight) ? 'landscape' : 'portrait';
      if (orientation !== this.orientation) {
        this.orientation = orientation;
        this.resizeing = true;
        // 为了兼容safari浏览器,需要加延迟
        setTimeout(() => {
          this.resizeing = false;
          const height = this.viewElement.offsetTop
          window.scrollTo({
            top: height - 44,
            behavior: 'smooth',
          });
        }, 500)
      }
    }, false);
js

  const height = document.getElementsByClassName('bgImg')[index].offsetTop;
  // 在一些手机浏览器中需要加上延迟,哪怕在vue中写在nextTick里
  setTimeout(() => {
    this.viewElement = document.elementFromPoint(window.innerWidth / 2, window.innerHeight / 2)
    console.log(height)
    window.scrollTo({
      top: height,
      behavior: 'smooth',
    });
  }, 200)

说几个问题,首先是安卓一系列浏览器,这些都没什么大问题,scrollend支持,所以获取没什么问题,但是safari浏览器没有这个监听事件,需要自己去实现,本子案例

移动端web页面按钮点击会变色

css
-webkit-tap-highlight-color:transparent;

不换行省略号

如果不达预期,可以用span包裹

css
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;

多行省略号

css
    display: -webkit-box;
    text-overflow: -o-ellipsis-lastline;
    text-overflow: ellipsis;
    line-clamp: 2;
    -webkit-line-clamp: 2; // 如果是3行改为3,以此类推
    -webkit-box-orient: vertical;
    overflow: hidden;

更新于:

夜茶 2020 ~ 2026