前端黑科技代码(如果有新收藏就更新)

13,420 阅读4分钟

这里给大家看一下我自己收藏的一些黑科技代码,都是我平常工(mo)作(yu)中看到或者用到的(一般用不到),然后收藏起来(有一些是来自掘金,但是文章我已经找不到,如果作者看到,可以和我说一下,我删了或者把原文链接贴上),那献丑了。

部分科技参考的链接

部分参考网站

1. 获取当前页面的滚动位置

const getScrollPosition = (el = window) => ({ 
    x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft, 
    y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop 
}) 
getScrollPosition(); // {x: 0, y: 200}

2. 平滑滚动到页面顶部

const scrollToTop = () => { 
    const c = document.documentElement.scrollTop || document.body.scrollTop 
    if (c > 0) { 
        window.requestAnimationFrame(scrollToTop) 
        window.scrollTo(0, c - c / 8) 
    } 
} 
scrollToTop()

3. 确定设备是移动设备还是台式机/笔记本电脑

const detectDeviceType = () => 
    /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i
    .test(navigator.userAgent) ? 
    'Mobile' : 'Desktop' 
detectDeviceType() // "Mobile" or "Desktop"

4. 带图带事件的桌面通知

function doNotify(title, options = {}, events = {}) {
  const notification = new Notification(title, options)
  for (let event in events) {
    notification[event] = events[event]
  }
}

function notify(title, options = {}, events = {}) {
  if (!('Notification' in window)) {
    return console.error('This browser does not support desktop notification')
  } else if (Notification.permission === 'granted') {
    doNotify(title, options, events)
  } else if (Notification.permission !== 'denied') {
    Notification.requestPermission().then(function (permission) {
      if (permission === 'granted') {
        doNotify(title, options, events)
      }
    })
  }
}
notify(
  '中奖提示',
  {
    icon: 'https://sf1-ttcdn-tos.pstatp.com/img/user-avatar/f1a9f122e925aeef5e4534ff7f706729~300x300.image',
    body: '恭喜你,掘金签到一等奖',
    tag: 'prize'
  },
  {
    onclick(ev) {
      console.log(ev)
      ev.target.close()
      window.focus()
    }
  }
)

5. 数组转树

function treeDataTranslate(data, id = 'id', pid = 'pId') {
  var res = []
  var temp = {}
  for (var i = 0; i < data.length; i++) {
    temp[data[i][id]] = data[i]
  }
  for (var k = 0; k < data.length; k++) {
    if (temp[data[k][pid]] && data[k][id] !== data[k][pid]) {
      if (!temp[data[k][pid]]['children']) {
        temp[data[k][pid]]['children'] = []
      }
      temp[data[k][pid]]['children'].push(data[k])
    } else {
      res.push(data[k])
    }
  }
  return res
}

6. 禁用在浏览器打开控制台

setInterval(function () {
  check()
}, 4000)
var check = function () {
  function doCheck(a) {
    if (('' + a / a)['length'] !== 1 || a % 20 === 0) {
      ;(function () {}['constructor']('debugger')())
    } else {
      ;(function () {}['constructor']('debugger')())
    }
    doCheck(++a)
  }
  try {
    doCheck(0)
  } catch (err) {}
}
check()

7. 函数柯里化

function add() {
  let args = [...arguments]
  function _add() {
      args.push(...arguments)
      return _add
  }
  _add.toString = function () {
      return args.reduce((pre, cur) => {
          return pre + cur
      })
  }
  return _add
}
console.log(add(1, 2)(3, 4)(5)(6)()().toString())

8. toFullScreen:全屏

function toFullScreen() {
  let elem = document.body
  elem.webkitRequestFullScreen
    ? elem.webkitRequestFullScreen()
    : elem.mozRequestFullScreen
    ? elem.mozRequestFullScreen()
    : elem.msRequestFullscreen
    ? elem.msRequestFullscreen()
    : elem.requestFullScreen
    ? elem.requestFullScreen()
    : alert('浏览器不支持全屏')
}

9. exitFullscreen:退出全屏

function exitFullscreen() {
  let elem = parent.document
  elem.webkitCancelFullScreen
    ? elem.webkitCancelFullScreen()
    : elem.mozCancelFullScreen
    ? elem.mozCancelFullScreen()
    : elem.cancelFullScreen
    ? elem.cancelFullScreen()
    : elem.msExitFullscreen
    ? elem.msExitFullscreen()
    : elem.exitFullscreen
    ? elem.exitFullscreen()
    : alert('切换失败,可尝试Esc退出')
}

10. 禁止右键、选择、复制

;['contextmenu', 'selectstart', 'copy'].forEach(function (ev) {
  document.addEventListener(ev, function (event) {
    return (event.returnValue = false)
  })
})

11. 首字母大写

let firstUpperCase = ([first, ...rest]) => first?.toUpperCase() + rest.join('')

12. 数据类型验证

function typeOf(obj) {
  const toString = Object.prototype.toString
  const map = {
    '[object Boolean]': 'boolean',
    '[object Number]': 'number',
    '[object String]': 'string',
    '[object Function]': 'function',
    '[object Array]': 'array',
    '[object Date]': 'date',
    '[object RegExp]': 'regExp',
    '[object Undefined]': 'undefined',
    '[object Null]': 'null',
    '[object Object]': 'object',
    '[object FormData]': 'formData',
    '[object Symbol]': 'symbol', 
    '[object BigInt]': 'bigint'
  }
  return map[toString.call(obj)]
}

13. 复制文本

copyPersonURL(content) {
  let that = this
  if (window.ClipboardData) {
      window.clipboardData.setData('text', content)
  } else {
      ;(function (content) {
          document.oncopy = function (e) {
              e.clipboardData.setData('text', content)
              e.preventDefault()
              document.oncopy = null
          }
      })(content)
      document.execCommand('Copy')
  }
}

14.docx文件转html

部分样式无法实现,所以最好还是后端去实现,后端的比较成熟,这里用vue来演示

需要安装插件mammoth

npm install mammoth --save
    <input type="file" name="file" @change="changeFile" />
    <div id="wordView" v-html="wordText" />
import mammoth from "mammoth"
    //选择本地文件预览
    changeFile(event) {
      // if(event.target.files[0].name.indexOf('docx')>-1){
        let that = this;
        let file = event.target.files[0];
        let reader = new FileReader();
        reader.onload = function (loadEvent) {
          let arrayBuffer = loadEvent.target.result; //arrayBuffer
          mammoth
            .convertToHtml({ arrayBuffer: arrayBuffer })
            // .convertToMarkdown({ arrayBuffer: arrayBuffer })
            .then(that.displayResult)
            .done();
        };
        reader.readAsArrayBuffer(file);
      // }
    },
    //页面渲染
    displayResult(result) {
      console.log(result.value)
      this.wordText = result.value;
    }

15.验证'()'是否成对出现

[..."(())()(()())"].reduce((a,i)=> i === '(' ? a+1 : a-1 , 0);
// 输出0则是 

16.判断当前标签页是否激活

const isTabInView = () => !document.hidden

17.打开浏览器打印框

const showPrintDialog = () => window.print()

18.html转图片

需要安装插件dom-to-image

npm install dom-to-image
import domtoimage from 'dom-to-image';
downLoadPhoto () {
  const node = document.getElementById('table')//对应的html标签id
  domtoimage.toPng(node)
    .then((dataUrl) => {
      const img = new Image()
      img.src = dataUrl
      // 将获取到的base64下载下来
      const imgUrl = img.src
      if (window.navigator.msSaveOrOpenBlob) {
        const bstr = atob(imgUrl.split(',')[1])
        let n = bstr.length
        const u8arr = new Uint8Array(n)
        while (n--) {
          u8arr[n] = bstr.charCodeAt(n)
        }
        const blob = new Blob([u8arr])
        window.navigator.msSaveOrOpenBlob(blob, 'chart-download' + '.' + 'png')
      } else {
        // 这里就按照chrome等新版浏览器来处理
        const a = document.createElement('a')
        a.href = imgUrl
        a.setAttribute('download', 'chart-download')
        a.click()
      }
    })
}

19.字符串转base与base64转字符串

// 加密
function base64EncodeUnicode(str) {
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
        return String.fromCharCode('0x' + p1);
    }));
}
// 解密
function base64DecodeUnicode(str) {
    return decodeURIComponent(atob(str).split('').map(function(c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
    }).join(''));
}

20.图片添加水印

const setWatermark = ({
  url = '',
  textAlign = 'center',
  textBaseline = 'middle',
  font = "20px Microsoft Yahei",
  fillStyle = 'rgba(184, 184, 184, 0.8)',
  content = '水印',
  cb = null,
  textX = 100,
  textY = 30
} = {}) => {
  const img = new Image()
  img.src = url
  img.crossOrigin = 'anonymous'
  img.onload = function () {
    const canvas = document.createElement('canvas')
    // 斜式水印处理
    const _w = img.width
    const _h = img.height
    const clientWidth = document.body.clientWidth
    const proportion = _h / _w

    canvas.width = _w
    canvas.height = _h
    const ctx = canvas.getContext('2d')
    ctx.drawImage(img, 0, 0, clientWidth, clientWidth * proportion)
    ctx.textAlign = textAlign
    ctx.textBaseline = textBaseline
    ctx.font = font
    ctx.fillStyle = fillStyle
    // ctx.fillText(content, _w - textX, _h - textY) // 右下角水印

    // 斜式水印
    ctx.rotate((-15 * Math.PI) / 180)
    for (let i = 0; i < 5; i++) {
      for (let j = 0; j < 7; j++) {
        ctx.fillText(content, i * (clientWidth / 5), j * (clientWidth * proportion / 5))
      }
    }
    const base64Url = canvas.toDataURL()
    cb && cb(base64Url)
  }
}
//  用法
setWatermark({
  url: 'xxxx',
  content: '测试水印',
  cb: (base64Url) => {
    console.log(base64Url)
  }
})

21.获取hh:mm:ss时间

const timeFormat = date => date.toTimeString().slice(0, 8)
timeFormat(new Date())

22.移动端获取软键盘高度

// ios软键盘弹起后 可以修改固定底部的元素bottom的值
visualViewport.addEventListener('resize', () => {
  let keyboardHeight = document.body.clientHeight - visualViewport.height
})

看完后觉得太垃圾,请轻点喷哈,可能是我自己比较菜,才会觉得这些是黑科技。