Skip to content

bigsea 前端工具箱 秒懂源码 开箱即用!(欢迎加入维护)

Notifications You must be signed in to change notification settings

seateam/bigsea.js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

  • 2021 年 8 月 15 日 更新

加入 bigsea.d.ts typescript 声明文件

bigsea.js

直接在浏览器 中使用

<script src="https://cdn.jsdelivr.net/npm/bigsea@latest/bigsea.js"></script>

安装

npm install bigsea --save

Vue 中使用

// 推荐在 main.js 中引用,可以直接生成全局对象 window.Sea
import 'bigsea'

import Sea from 'bigsea'

Node.Js 中使用

const Sea = require('bigsea')

示例

DOM 操作

接口设计同 jQuery

事件监听

Sea('body').on('click', function () {
  log('点击 body')
})

事件委托

Sea('body').on('click', '.user', function () {
  log('点击 body 中的 .user 元素')
})

一次性事件

Sea('body').one('click', function () {
  log('点击 body 后,自动销毁该监听')
})

移除所有事件

Sea('body').off()
Sea('body').ob(
  {
    childList: true, // 子元素的变动
    attributes: true, // 属性的变动
    characterData: true, // 节点内容或节点文本的变动
    subtree: true, // 所有下属节点(包括子节点和子节点的子节点)的变动
    attributeOldValue: true, // 需要记录变动前的属性值
    characterDataOldValue: true, // 需要记录变动前的数据值
    attributesFilter: ['class', 'str'], // 值为一个数组,表示需要观察的特定属性
  },
  function (event) {
    log(event)
  },
)

打开新网页

Sea.open('https://www.baidu.com')

浮点数运算

// 在 js 中
// 0.1 + 0.2 返回 0.30000000000000004
// 1 - 0.9 返回 0.09999999999999998
Sea.float(0.1 + 0.2) // 返回 0.3
Sea.float(1 - 0.9) // 返回 0.1

静态方法

返回 a-b 的随机数

// 不包括 b
// 举例:生成 4 位随机数
Sea.random(1000, 10000)

正则 特殊字符转义

Sea.re('.*+?^=!:${}()') // 返回 /\.\*\+\?\^\=\!\:\$\{\}\(\)/g

json 解析

// 不会报错,无法解析则返回本身
Sea.json(`{"test": 123}`)
// 返回对象 {test: 123}
Sea.json(`{test: 456}`)
// 返回字符串 {test: 456}

返回数据类型

// 原生 typeof null 会返回 "object" 妥妥的BUG
Sea.type(null) // 返回 "null"
Sea.type('') // 返回 "string"
Sea.type([1, 2, 3]) //返回"array"
Sea.type(1, 2, 3) //返回"number"
// 支持所有数据类型

url 解析 & 构建

let url = Sea.url('https://sea.team/book?id=110')
// 支持修改的参数 origin path query hash
url.path = '/mine'
url.query.id = '120'
Sea.urlFormat(url)
// 返回 https://sea.team/mine?id=120
Sea.open() // 打开新网页
Sea.float() // 浮点数运算
Sea.random() // 返回 a-b 的随机数
Sea.re() // 正则 特殊字符转义
Sea.json() // json 解析
Sea.type() // 返回数据类型
Sea.url() // url 解析
Sea.urlFormat() // url 构建
Sea.Ajax() // Ajax
Sea.css() // 生成样式 String
Sea.query() // 生成 query
Sea.has() // Object 检查
Sea.get() // Object 获取
Sea.set() // 数组去重
Sea.localStorage() // 本地存储
Sea.deepCopy() // 深拷贝
Sea.static = {
  openUrl(url) {
    // 默认 https
    if (url.startsWith('http')) {
      // 不处理 https http
    } else if (url.startsWith('//')) {
      url = 'http:' + url
    } else if (url.startsWith('/')) {
      // 不处理
    } else {
      url = 'https://' + url
    }
    return url
  },
  // 打开新网页
  open(url, replace) {
    const s = this.openUrl(url)
    if (replace) {
      window.location = s
    } else {
      window.open(s)
    }
  },
  // 浮点数运算
  float(n, digit = 10) {
    return parseFloat(n.toFixed(digit))
  },
  // 测试
  ensure(bool, message) {
    if (!bool) {
      log('测试失败:', message)
    }
  },
  // 循环 n 次后断点
  cut(n) {
    if (this.cut.count) {
      this.cut.count--
      if (this.cut.count === 1) {
        delete this.cut.count
        throw `断点:${n}次`
      }
    } else if (n > 1) {
      this.cut.count = n
    } else {
      throw `断点`
    }
  },
  // 返回 a-b 的随机数
  random(a, b) {
    return parseInt(Math.random() * (b - a) + a)
  },
  // 正则 特殊字符转义
  re(s, flag) {
    return new RegExp(
      s.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$&'),
      flag || 'g',
    )
  },
  // json 解析
  json(s) {
    try {
      return JSON.parse(s)
    } catch (err) {
      return s
    }
  },
  // 返回数据类型
  type(obj) {
    return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase()
  },
  // url 解析
  url(url) {
    const obj = {}
    let arr = []
    // url
    obj.url = url
    // protocol
    arr = url.split('://')
    obj.protocol = arr[1] ? arr[0] : ''
    url = arr[1] || arr[0]
    // host
    arr = url.split('/')
    obj.host = arr[0]
    url = arr.slice(1).join('/')
    // port
    obj.port = obj.host.split(':')[1] || 80
    // hash
    arr = url.split('#')
    obj.hash = arr[1] || ''
    url = arr[0]
    // query
    arr = url.split('?')
    obj.query = this.query(arr[1])
    url = arr[0]
    // path
    obj.path = '/' + url
    // origin
    obj.origin = obj.host
    if (obj.protocol && obj.host) {
      obj.origin = obj.protocol + '://' + obj.host
    }
    // href
    obj.href = obj.origin + obj.path
    return obj
  },
  // Ajax
  Ajax(request) {
    // 直接 GET 请求
    if (typeof request === 'string') {
      request = { url: request }
    }
    const req = {
      method: (request.method || 'GET').toUpperCase(),
      url: request.url || '',
      data: request.data || {},
      query: request.query || {},
      header: request.header || {},
      callback: request.callback,
      hash: request.hash || '',
      timeout: request.timeout,
    }
    // 默认参数
    if (typeof this.Ajax.default === 'function') {
      req.data = Object.assign(this.Ajax.default() || {}, req.data)
    }
    // host
    if (!req.url.startsWith('http')) {
      // 默认域名
      req.url = (this.Ajax.HOST || '') + req.url
    }
    // url 解析
    const url = this.url(req.url)
    req.url = url.origin + url.path
    // query 请求
    let query = Object.assign(url.query, req.query)
    if (req.method === 'GET') {
      query = Object.assign(query, req.data)
    }
    const search = this.query(query)
    if (search) {
      req.url += '?' + search
    }
    // hash 锚点
    const hash = req.hash || url.hash
    if (hash) {
      req.url += '#' + hash
    }
    // promise
    return new Promise((resolve, reject) => {
      const r = new XMLHttpRequest()
      // 跨域请求 cookie
      if (this.Ajax.withCredentials) {
        r.withCredentials = true
      }
      // 设置超时
      if (req.timeout) {
        r.timeout = req.timeout
      }
      r.open(req.method, req.url, true)
      // default json
      if (req.method !== 'GET' && !req.header['Content-Type']) {
        req.header['Content-Type'] = 'application/json'
      }
      for (const key in req.header) {
        r.setRequestHeader(key, req.header[key])
      }
      r.onreadystatechange = () => {
        if (r.readyState === 4) {
          let res = this.json(r.response)
          if (r.status !== 200) {
            if (typeof this.Ajax.fail === 'function') {
              this.Ajax.fail(r)
            }
          }
          // 回调函数
          if (typeof req.callback === 'function') {
            req.callback(res)
          }
          // Promise 成功
          resolve(res)
        }
      }
      r.onerror = (err) => {
        // Promise 失败
        reject(err)
      }
      if (req.method === 'GET') {
        r.send()
      } else {
        // POST
        if (typeof req.data === 'string') {
          r.send(req.data)
        }
        // default json
        r.send(JSON.stringify(req.data))
      }
    })
  },
  // 生成样式 String
  css(css, obj) {
    // this.css('top:hover', {'display':'block', 'cursor':'zoom-in'})
    if (typeof css === 'object') {
      obj = css
    }
    let s = ''
    for (const key in obj) {
      const val = obj[key]
      s += `${key}:${val};`
    }
    if (typeof css === 'string') {
      s = `${css}{${s}}`
    }
    return s
  },
  // 生成 query
  query(obj) {
    if (typeof obj === 'string') {
      const result = {}
      let start = obj.indexOf('?')
      let end = obj.indexOf('#')
      if (start === -1) {
        start = 0
      } else {
        start += 1
      }
      if (end === -1) {
        end = obj.length
      }
      obj = obj.slice(start, end)
      if (obj) {
        for (const e of obj.split('&')) {
          const arr = e.split('=')
          result[arr[0]] = decodeURIComponent(arr[1]) || ''
        }
      }
      return result
    } else {
      const arr = []
      for (const key in obj) {
        const val = obj[key]
        arr.push([key, val].join('='))
      }
      let s = ''
      if (arr.length) {
        s = arr.join('&')
      }
      return s
    }
  },
  // 检查 Object
  has(obj, path) {
    if (this.get(obj, path) === null) {
      return false
    }
    return true
  },
  // 获取 Object
  get(obj, path) {
    // 小海聚聚的完美回答
    path = path.replace(/\[/g, '.').replace(/\]/g, '')
    // path = path.replace(/\[(.+?)\]/g, '.$1')
    if (obj && path) {
      const arr = path.split('.')
      for (const k of arr) {
        if (typeof obj === 'object' && k in obj) {
          obj = obj[k]
        } else {
          return null
        }
      }
      return obj
    }
    return undefined
  },
  // 数组去重
  set(arr, path) {
    const result = []
    const dict = {}
    for (const item of arr) {
      if (typeof item === 'object') {
        const key = this.get(item, path)
        // 没找到不去重
        if (key === null) {
          result.push(item)
        } else if (dict[key] !== true) {
          dict[key] = true
          result.push(item)
        }
      } else if (dict[item] !== true) {
        dict[item] = true
        result.push(item)
      }
    }
    return result
  },
  // 本地存储
  localStorage(key, val) {
    if (val === undefined) {
      return this.json(window.localStorage.getItem(key))
    } else if (val === '') {
      window.localStorage.removeItem(key)
    } else {
      window.localStorage.setItem(key, JSON.stringify(val))
    }
  },
  // 深拷贝
  deepCopy(data) {
    return this.json(JSON.stringify(data))
  },
}

联系作者

大海团队 https://mp.sea.team

About

bigsea 前端工具箱 秒懂源码 开箱即用!(欢迎加入维护)

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published