前端开发中实用的工具方法

5,098 阅读3分钟

基于最近遇到的问题的部分总结,后续遇到的问题解决方法会继续补充

动态添加css文件

应用场景:

  • 换肤功能
  • 一套代码不同地区使用,不同地区不同风格
  • 一套代码不同用户使用,用户个性化设置功能

那么如何动态添加不同的css文件呢?

 /**
 * @param {String} cssName : css 名称 不带后缀
 * @param {String} prefix  :css 前缀
 */
function dynamicAddCss(cssName,prefix=""){
    let link = document.createElement('link')
    link.setAttribute('href',prefix+cssName+'.css')
    link.setAttribute('type','text/css')
    document.getElementsByTagName('head')[0].appendChild(link)
}
dynamicAddCss('a','http://www.baidu.com/app/a/')
dynamicAddCss('b','http://www.baidu.com/app/b/')

动态添加 js文件

有时候,我们前端开发中,有些数据文件是存到我们的服务器上,需要我们去获取这个数据再去做一些操作,比如 banner 配置数据,或是一些其他数据。

服务器上存放的 banner.js

const Config = {
    banner:[
        {img:'www.baidu.com/1.png',id:"1"},
        {img:'www.baidu.com/2.png',id:"2"},
        {img:'www.baidu.com/3.png',id:"3"},
        {img:'www.baidu.com/4.png',id:"4"},
    ]
}

服务器上存放的 json.js

var list = [1,2,3,4,5]

方法:

 /**
 * @param {Array} scriptUrlArr : 需求动态添加的脚本URL数组
 * @param {Function} callback : 回调函数
 */
function dynamicAddScript(scriptUrlArr,callback){
    scriptUrlArr.forEach(scriptUrl=>{
        let script = document.createElement('script')
        script.setAttribute('src',scriptUrl)
        document.body.appendChild(script) 
    })
    window.onload = function(){
        callback && callback()
    }
}

使用:

 dynamicAddScript(['http://moxiaofei.com/banner.js','http://moxiaofei.com/json.js'],() =>{
    console.log(Config)  //{banner: Array(3)}
    console.log(list)    //[1, 2, 3, 4, 5]
})

存在服务器上的数据文件变量,建议用 let 或是 const 声明,用 var会覆盖前面脚本中相同变量

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)

监听:

//localStorage.setItem监听
window.addEventListener('setItemEvent',function(e){
    console.log(e.detail)
})

//localStorage.getItem监听
window.addEventListener('getItemEvent',function(e){
    console.log(e.detail)
}) 

//localStorage.removeItem监听
window.addEventListener('removeItemEvent',function(e){
    console.log(e.detail)
})

主动触发DOM身上存在的方法

function trigger(Node,EventType) {
    if(EventType in Node)Node[EventType]()
}

主动触发自定义方法

let oDiv = document.querySelector('#div')

oDiv.addEventListener('DefineMethod', function(){
    alert('自定义方法生效了')
})

function fireEvent(node,type) {
    var event = document.createEvent('Event');
    event.initEvent(type, true, true);
    node.dispatchEvent(event)
}

fireEvent(oDiv,'DefineMethod')

重写数组方法

重写数组原型部分方法

const oldArrayProto = Array.prototype
const newArrayProto = Object.create(oldArrayProto)
const rewriteMethod = ['push','splice']
const instenceArr = []
instenceArr.__proto__ = newArrayProto
rewriteMethod.forEach(method=>{
    let orgin = newArrayProto[method]
    newArrayProto[method] = function(){
        orgin.apply(this,arguments)
        notify(method,...arguments)
    }
})
function notify () {
    let [method,...rest] = [...arguments]
    console.log(method)
    console.log(rest)
}

示例重写了数组的两个方法,pushsplice,并在重写方法里面添加执行了一个 通知方法notify,当你对 数组instenceArr 进行 pushsplice 操作时,notify 会监听到

重写console.log

需求:第一个参数如果是对象,就输出 字符串JSON,不影响其他功能

console.log = (orgin=>{
    return function(){
        //如果是对象 就转成 字符串JSON
        arguments[0] =  typeof arguments[0] == 'string'?arguments[0]:JSON.stringify(arguments[0])
        orgin.call(console,...arguments)
    }
})(console.log)

只执行一次函数

2020/4/14 更新

函数重写置空

function RunOnce(fn){
    fn()
    RunOnce = function(){} 
}

RunOnce(function(){
    console.log(111)
})
RunOnce(function(){//不执行
    console.log(111)
})

函数对象属性挂载

function RunOnce(fn){
    if(!RunOnce[fn]){
        fn()
        RunOnce[fn] = true 
    }
}

let a1 = function(){
    console.log(11)
}
let b1 = function(){
    console.log(22)
}
RunOnce(a1)//11
RunOnce(a1)//不执行
RunOnce(b1)//22
RunOnce(b1)//不执行

Tip:此种方法不适合匿名函数

持续更新...

结语

如果你有更好的点子,或者没有找到你想要的工具函数,欢迎留言

文中若有不准确或错误的地方,欢迎指出

往期文章:前端代码优化实用篇