本期技术分享的内容是(图片上传到服务器+React的ref的使用场景+手写bind+防抖、节流)

543 阅读3分钟

一、图片上传到服务器和图片预览的过程


我用原生js的方式来描述图片上传和预览的原理吧!
首先图片上传也得靠浏览器的支持程度,高版本和低版本的浏览器实现的方式是不一样的
先说高版本的浏览器;
做法:
    <input type="file" onChange=function(){图片上传会触发的回调}/>

原理:
一旦file文件发生了变化,就会触发onChage这个函数,此时我们就可以调用浏览器提供的一个FileReader这个类,在change之后可以调用FileReader.readAsDataURL这个方法,读取到文件的base64的字符串,拿到了base64字符串之后,接下来的操作就好办了
要实现预览,只需要把这个base64的字符串塞到img标签中的src里面即可

    <img src=base64 />

实现保存:只需要把这串base64的字符串发送给后端,让后端保存到服务器上即可

其次是在低版本的浏览器里面怎样实现图片的上传和预览;

预览:在onChange触发的时候,就让input通过表单的形式直接发送给后端,后端在存储完成之后,返回给我一个图片的URL,就可以拿着这个URL放到src里面,从而实现了图片的预览
上传保存:其实在onChange的时候已经给后端发送了关于图片的内容了,在点击保存的时候,已经无需再发送图片的内容,只需要发送其它需要用到的内容给后端即可

二、React中ref的使用场景


说起ref都会想到在操作DOM的时候使用,那会在怎样的场景下使用呢?

我使用它的主要场景有:
1:在页面加载完成的时候,需要获取其的宽度和高度。
2:我这里有一个页面,里面有三个按钮,点击都会跳转到同一个详情页面,详情页面其实就是一大堆的条款,需要你同意才能使用这个app
在点击第一个详情按钮的时候需要跳转到详情页的 (一)xxxxxx 内容的地方
在点击第二个详情按钮的时候需要跳转到详情页的 (二)xxxxxx内容的地方,在滑动页面的时候可以看到全部条款的内容 在点击第三个详情按钮,需求和上面一样

三、手动实现js中的bind


用法:
    function fn(){}
    fn.bind(改变this的对象,参数1,参数2,参数xxxx)

具体实现

    Function.prototype.bind = function(target){
        var fn = this
        return function(){
            fn.apply(target,arguments)
        }
    }

注意点:
prototype的主要作用是共享方法,使用applay是考虑参数问题,arguments得到是一个数组,传递多少个参数个来都可以变成一个数组

防抖


原理:铲除之前发生的事件,只保留最后一次发生的事件
使用场景:
1:window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次
2:页面滚动,onscroll
3:搜索框搜索发送ajax请求

具体实现

    function roll(){
        console.log('记录页面滚动的位置')
    }
    window.onscroll = debounce(roll, 500)
    //防抖函数
    function debounce(cb, delay = 200){
        let t = null
        return function(){
            clearTimeout(t)
            t = setTimeount(()=>{
                cb()
            },delay)
        }
    }

节流


原理:固定单位时间内只触发一次
使用场景:
1:鼠标不断点击触发,mousedown(单位时间内只触发一次)
2:监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断,onscroll
3:搜索框搜索发送ajax请求

具体实现

    function roll(){
        console.log('记录页面滚动的位置')
    }
    window.onscroll = throttle(roll, 500)
    //防抖函数
    function throttle(cb, delay = 200){
        //一进入页面就记录一次时间
        let lasttime = 0;
        return function(){
            //页面滚动时记录时间
            let now = new Date().getTime()
            if(now - lasttime > delay){
                // 如果滚动时间超过了500毫秒则执行roll()
                cb();
                lasttime = now
            }
        }
    }