原生js实现上传图片和视频的功能(支持预览和删除),已验证

最近有一个需求,需要用原生js做一个上传视频和图片的功能

具体需求是这样的

        1. 上传之后可预览,可删除

        2. 无论是视频还是图片最多上传9个

实现效果如下:

可上传,并且可回显,不过回显的内容目前是在本地写死的,可以做相应的改造

注意点:

        1. 用到了promise的相关知识,实现了并发请求,因为上传视频的时候需要用到第一帧的信息,所以把封面也上传了视频

        2. 还用到了ajax的相关知识

        3. 由于上传视频和图片不是同一个地址,所以我用类型判断了一下,具体使用过程中地址是一个的话,可以不用这么麻烦

接下来看一下具体的代码实现:

html部分:

<div class="wrap">
        <!-- 预览的地方 -->
        <div class="preview-box"></div>
        <div class="card">
            <input id="upload" type="file" accept=".jpg, .jpeg, .png, .mp4 , .gif, .webp" />
            <div class="view">
                <!-- 上传成功前 -->
                <span id="icon">+</span>
                <span id="loading">加载中……</span>
            </div>
        </div>
    </div>
    <button class="btn">上传</button>
    <button class="edit-btn">回显</button>
    <!-- 预览图片的 modal 框 -->
    <div id="modal">
        <span id="closeIcon">关闭</span>
        <div class="content">
            <img id="modalImg">
            <video id="modalVideo">
        </div>
    </div>

js部分:

<script>
    const upload = document.getElementById('upload');
    const icon = document.getElementById('icon');
    const loading = document.getElementById('loading');
    const previewBox = document.querySelector(".preview-box")
    const cardEle = document.querySelector(".card")
    let isLoading = false

    let imgVideoUrl = '';
    let imgVideoType = ""
    let file = []    //上传的字符串文件列表
    let coverList = []  //封面列表

    upload.onchange = function (value) {
        let fileObj = {
            url: "",
            width: "",
            height: "",
            duration: "",
            cover: ""
        }
        const fileList = value.target.files;
        imgVideoType = fileList[0].type

        // 发送请求获得url
        if (fileList[0].type == "video/mp4") {
            let p1 = new Promise((resolve, reject) => {
                // 获取视频信息
                loadVideo(value.target.files[0]).then(video => {
                    let tempFileObj = {
                        duration: "",
                        width: "",
                        height: "",
                        cover: ""
                    }
                    // 时长
                    tempFileObj.duration = video.duration
                    // 宽
                    tempFileObj.width = video.videoWidth
                    // 高
                    tempFileObj.height = video.videoHeight
                    // 拿到第一帧封面图
                    const canvasElem = document.createElement('canvas')
                    const { videoWidth, videoHeight } = video
                    canvasElem.width = videoWidth
                    canvasElem.height = videoHeight
                    canvasElem.getContext('2d').drawImage(video, 0, 0, videoWidth, videoHeight)
                    // 导出成blob文件
                    canvasElem.toBlob(blob => {
                        // 将blob文件转换成png文件
                        const thumbFile = toThumbFile(blob)
                        let cover_formdata = new FormData();
                        cover_formdata.append("file", thumbFile)
                        const xhr = new XMLHttpRequest()
                        xhr.open('post', 'https://api.t-uzx.com/uc/upload/oss/image', true)
                        xhr.send(cover_formdata)
                        xhr.addEventListener('readystatechange', function () {
                            if (xhr.readyState === 4 && xhr.status == 200) {
                                let res = JSON.parse(xhr.response)
                                if (res.code == 0) {
                                    tempFileObj.cover = res.data
                                    resolve(tempFileObj)
                                } else {
                                    tempFileObj.cover = ""
                                }
                            }
                        })
                    }, 'image/png')
                })

            })
            let p2 = new Promise((resolve, reject) => {
                let tempFileObj = {
                    url: ""
                }
                let video_formdata = new FormData();
                video_formdata.append("file", value.target.files[0])
                const video_xhr = new XMLHttpRequest()
                video_xhr.open('post', 'https://api.t-uzx.com/uc/upload/oss/video')
                video_xhr.send(video_formdata)
                video_xhr.addEventListener('readystatechange', function () {
                    if (video_xhr.readyState === 4 && video_xhr.status == 200) {
                        let res = JSON.parse(video_xhr.response)
                        if (res.code == 0) {
                            let tempPreviewItem = document.createElement("div")
                            tempPreviewItem.className = "preview-item"
                            let tempPreviewMask = document.createElement("div")
                            tempPreviewMask.className = "preview-mask"
                            let tempShowImg = document.createElement("span")
                            tempShowImg.className = "showImg"
                            tempShowImg.innerText = "查看"
                            tempPreviewItem.setAttribute('dataindex', previewBox.childElementCount)
                            let tempDelImg = document.createElement("span")
                            tempDelImg.className = "delImg"
                            tempDelImg.innerText = "删除"
                            imgVideoUrl = res.data
                            tempFileObj.url = res.data
                            // 创建video标签插入到预览元素
                            let tempVideo = document.createElement("video")
                            tempVideo.src = imgVideoUrl
                            tempVideo.style.objectFit = "fill"
                            tempPreviewMask.appendChild(tempShowImg)
                            tempPreviewMask.appendChild(tempDelImg)
                            tempPreviewItem.appendChild(tempPreviewMask)
                            tempPreviewItem.appendChild(tempVideo)
                            previewBox.appendChild(tempPreviewItem)
                            if (previewBox.childElementCount >= 9) {
                                cardEle.style.display = "none"
                            }
                            resolve(tempFileObj)
                        }
                    }
                })
            })

            icon.style.display = "none"
            loading.style.display = "block"
            isLoading = true
            Promise.all([p1, p2]).then((results) => {
                icon.style.display = "block"
                loading.style.display = "none"
                isLoading = false
                fileObj = { ...results[0], ...results[1] }
                file.push(fileObj)
            }).catch(e => { // 失败的时候则返回最先被reject失败状态的值
                console.log("error", e)
                icon.style.display = "block"
                loading.style.display = "none"
                isLoading = false
            })
        } else {
            let p = new Promise((resolve, reject) => {
                let tempObj = {
                    url: "",
                    width: "",
                    height: ""
                }
                loadImg(value.target.files[0]).then(img => {
                    tempObj.width = img.width
                    tempObj.height = img.height
                })
                let formdata = new FormData();
                formdata.append("file", value.target.files[0])
                const xhr = new XMLHttpRequest()
                xhr.open('post', 'https://api.t-uzx.com/uc/upload/oss/image', true)
                xhr.send(formdata)
                xhr.addEventListener('readystatechange', function () {
                    if (xhr.readyState === 4 && xhr.status == 200) {
                        let res = JSON.parse(xhr.response)
                        if (res.code == 0) {
                            let tempPreviewItem = document.createElement("div")
                            tempPreviewItem.className = "preview-item"
                            let tempPreviewMask = document.createElement("div")
                            tempPreviewMask.className = "preview-mask"
                            let tempShowImg = document.createElement("span")
                            tempShowImg.className = "showImg"
                            tempShowImg.innerText = "查看"
                            tempPreviewItem.setAttribute('dataindex', previewBox.childElementCount)
                            let tempDelImg = document.createElement("span")
                            tempDelImg.className = "delImg"
                            tempDelImg.innerText = "删除"
                            tempObj.url = res.data
                            imgVideoUrl = res.data
                            let tempImg = document.createElement("img")
                            tempImg.src = imgVideoUrl
                            tempPreviewMask.appendChild(tempShowImg)
                            tempPreviewMask.appendChild(tempDelImg)
                            tempPreviewItem.appendChild(tempPreviewMask)
                            tempPreviewItem.appendChild(tempImg)
                            previewBox.appendChild(tempPreviewItem)
                            if (previewBox.childElementCount >= 9) {
                                cardEle.style.display = "none"
                            }
                            resolve(tempObj)
                        }
                    }
                })

            })
            icon.style.display = "none"
            loading.style.display = "block"
            isLoading = true
            p.then(results => {
                icon.style.display = "block"
                loading.style.display = "none"
                isLoading = false
                fileObj = { ...results }
                file.push(fileObj)
            }).catch(err => {
                icon.style.display = "block"
                loading.style.display = "none"
                isLoading = false
            })
        }
        value.target.value = ""
    }



    const showImg = document.querySelector('.showImg');
    const modal = document.getElementById('modal');
    const modalImg = document.getElementById('modalImg');
    const modalVideo = document.getElementById('modalVideo');
    const closeIcon = document.getElementById('closeIcon');
    const previewItem = document.querySelector(".preview-item")


    // 利用事件委托 点击预览图片
    previewBox.onclick = function (event) {
        if (event.target.parentElement.parentElement.attributes.dataindex) {
            // 查询当前点击的索引
            let index = event.target.parentElement.parentElement.attributes.dataindex.value
            let currentIndex
            Array.from(event.target.parentElement.parentElement.parentElement.children).forEach((item, jindex) => {
                if (index == item.getAttribute("dataindex")) {
                    currentIndex = jindex
                    return item
                }
            })
            // 判断点击的是查看还是删除
            if (event.target.innerText == "查看") {
                let previewSrc = event.target.parentElement.parentElement.children[1].src
                imgVideoType = event.target.parentElement.parentElement.lastChild.localName
                modal.style.width = '100%';
                modal.style.height = '100%';
                if (imgVideoType == "video/mp4" || imgVideoType == "video") {
                    modalImg.style.display = "none"
                    modalVideo.style.display = "block"
                    modalVideo.src = previewSrc;
                    modalVideo.controls = true
                    modalVideo.loop = true
                    modalVideo.autoplay = true
                } else {
                    modalVideo.style.display = "none"
                    modalImg.style.display = "block"
                    modalImg.src = previewSrc;
                }
            } else if (event.target.innerText == "删除") {
                this.removeChild(Array.from(previewBox.children)[currentIndex])
                file.splice(currentIndex, 1)
                if (file.length < 9) {
                    cardEle.style.display = "block"
                }
            }
        }

    }

    // 关闭 modal 框
    closeIcon.onclick = function () {
        modal.style.width = '0';
        modal.style.height = '0';
        modalImg.src = '';
    }
    modal.onclick = function () {
        modal.style.width = '0';
        modal.style.height = '0';
        modalImg.src = '';
    }


    const btn = document.querySelector(".btn")
    btn.onclick = function () {
        console.log(JSON.stringify(file), "文件")
    }
    const editBtn = document.querySelector(".edit-btn")
    let filelist = ["https://uzx.oss-cn-hongkong.aliyuncs.com/2023/12/19//063ee6bb-68ed-4909-9b58-8a38059d9350.png", "https://uzx.oss-cn-hongkong.aliyuncs.com/2023/12/19//0fb187fb-867d-4ad8-83d6-5d9a88d5df17.jpg",]
    editBtn.onclick = function () {
        filelist.forEach(item => {
            let tempPreviewItem = document.createElement("div")
            tempPreviewItem.className = "preview-item"
            let tempPreviewMask = document.createElement("div")
            tempPreviewMask.className = "preview-mask"
            let tempShowImg = document.createElement("span")
            tempShowImg.className = "showImg"
            tempShowImg.innerText = "查看"
            tempPreviewItem.setAttribute('dataindex', previewBox.childElementCount)
            let tempDelImg = document.createElement("span")
            tempDelImg.className = "delImg"
            tempDelImg.innerText = "删除"
            if (file.length >= 9) {
                cardEle.style.display = "none"
                return
            }
            file.push(item)
            imgVideoUrl = item
            // 判断是视频还是图片
            if (item.endsWith(".mp4")) {
                let tempVideo = document.createElement("video")
                tempVideo.src = imgVideoUrl
                tempPreviewMask.appendChild(tempShowImg)
                tempPreviewMask.appendChild(tempDelImg)
                tempPreviewItem.appendChild(tempPreviewMask)
                tempPreviewItem.appendChild(tempVideo)

                previewBox.appendChild(tempPreviewItem)
            } else {
                let tempImg = document.createElement("img")
                tempImg.src = imgVideoUrl
                tempPreviewMask.appendChild(tempShowImg)
                tempPreviewMask.appendChild(tempDelImg)
                tempPreviewItem.appendChild(tempPreviewMask)
                tempPreviewItem.appendChild(tempImg)
                previewBox.appendChild(tempPreviewItem)
            }

        })
        if (file.length >= 9) {
            cardEle.style.display = "none"
            return
        }

    }


    // 获取视频信息
    function loadVideo(file) {
        return new Promise(function (resolve, reject) {
            const videoElem = document.createElement('video')
            const dataUrl = URL.createObjectURL(file)
            // 当前帧的数据是可用的
            videoElem.onloadeddata = function () {
                resolve(videoElem)
            }
            videoElem.onerror = function () {
                reject('video 后台加载失败')
            }
            // 设置 auto 预加载数据, 否则会出现截图为黑色图片的情况
            videoElem.setAttribute('preload', 'auto')
            videoElem.src = dataUrl
        })
    }

    // 获取图片信息
    function loadImg(file) {
        return new Promise(function (resolve, reject) {
            const imgElem = document.createElement('img')
            const dataUrl = URL.createObjectURL(file)
            imgElem.src = dataUrl
            // 当前帧的数据是可用的
            imgElem.onload = function () {
                console.log("加载采购")
                resolve(imgElem)
            }
            imgElem.onerror = function () {
                reject('img 后台加载失败')
            }
        })
    }
    // blob文件转成file文件
    function toThumbFile(blob) {
        return new File([blob], 'thumb__img.png')
    }

</script>

完整代码:

<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>上传组件</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .wrap {
            display: flex;
        }

        .btn {
            margin-top: 30px;
        }

        .preview-box {
            width: auto;
            height: 80px;
            border-radius: 6px;
            display: flex;
        }

        .preview-box .preview-item {
            width: 80px;
            height: 100%;
            position: relative;
            overflow: hidden;
            cursor: pointer;
            border: 1px dashed #d9d9d9;
            padding: 5px;
            margin-right: 10px;
        }

        .preview-box .preview-item img {
            display: block;
            width: 100%;
            height: 100%;
            border-radius: 6px;
            position: absolute;
            top: 0;
            left: 0;
            z-index: 0;
        }

        .preview-box .preview-item video {
            display: block;
            width: 100%;
            height: 100%;
            border-radius: 6px;
            position: absolute;
            top: 0;
            left: 0;
            z-index: 0;
        }

        .preview-box .preview-item .preview-mask {
            width: 100%;
            height: 100%;
            position: absolute;
            left: 0;
            top: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            transition: all .3s;
            z-index: 10;
        }

        .preview-box .preview-item:hover .preview-mask {
            background-color: rgba(0, 0, 0, .3);
        }

        .preview-box .preview-item:hover .preview-mask span {
            display: block;

        }

        .preview-box .preview-item .preview-mask:hover {
            background-color: rgba(0, 0, 0, .3);
        }

        .preview-box .preview-item .preview-mask span {
            color: #fff;
            font-size: 14px;
            display: none;
            transition: all .3s;

        }

        .preview-box .preview-item .preview-mask span:first-child {
            margin-right: 10px;
        }

        .card {
            position: relative;
            width: 80px;
            height: 80px;
            padding: 5px;
            /* margin-right: 20px; */
            border: 1px dashed #d9d9d9;
            border-radius: 6px;

        }

        .card input {
            position: absolute;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            opacity: 0;
            cursor: pointer;
        }

        .card .view {
            width: 100%;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .card .view #icon {
            display: inline-block;
            font-size: 30px;
        }


        /* modal 样式 */
        #modal {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 0;
            height: 0;
            box-shadow: 0 0 10px #d9d9d9;
            background: rgba(0, 0, 0, .3);
            transition: all .1s ease-in-out;
            overflow: hidden;
            z-index: 100;
        }

        #modal .content {
            box-sizing: border-box;
            width: 100%;
            height: 100%;
            padding: 45px 20px 20px;
            display: flex;
            justify-content: center;
        }

        #modal #modalImg {
            height: 100%;
        }

        #modal #closeIcon {
            position: absolute;
            top: 10px;
            right: 10px;
            cursor: pointer;
        }

        #loading {
            font-size: 13px;
            display: none;
        }
    </style>
</head>

<body>
    <div class="wrap">
        <!-- 预览的地方 -->
        <div class="preview-box"></div>
        <div class="card">
            <input id="upload" type="file" accept=".jpg, .jpeg, .png, .mp4 , .gif, .webp" />
            <div class="view">
                <!-- 上传成功前 -->
                <span id="icon">+</span>
                <span id="loading">加载中……</span>
            </div>
        </div>
    </div>
    <button class="btn">上传</button>
    <button class="edit-btn">回显</button>
    <!-- 预览图片的 modal 框 -->
    <div id="modal">
        <span id="closeIcon">关闭</span>
        <div class="content">
            <img id="modalImg">
            <video id="modalVideo">
        </div>
    </div>
</body>
<script>
    const upload = document.getElementById('upload');
    const icon = document.getElementById('icon');
    const loading = document.getElementById('loading');
    const previewBox = document.querySelector(".preview-box")
    const cardEle = document.querySelector(".card")
    let isLoading = false

    let imgVideoUrl = '';
    let imgVideoType = ""
    let file = []    //上传的字符串文件列表
    let coverList = []  //封面列表

    upload.onchange = function (value) {
        let fileObj = {
            url: "",
            width: "",
            height: "",
            duration: "",
            cover: ""
        }
        const fileList = value.target.files;
        imgVideoType = fileList[0].type

        // 发送请求获得url
        if (fileList[0].type == "video/mp4") {
            let p1 = new Promise((resolve, reject) => {
                // 获取视频信息
                loadVideo(value.target.files[0]).then(video => {
                    let tempFileObj = {
                        duration: "",
                        width: "",
                        height: "",
                        cover: ""
                    }
                    // 时长
                    tempFileObj.duration = video.duration
                    // 宽
                    tempFileObj.width = video.videoWidth
                    // 高
                    tempFileObj.height = video.videoHeight
                    // 拿到第一帧封面图
                    const canvasElem = document.createElement('canvas')
                    const { videoWidth, videoHeight } = video
                    canvasElem.width = videoWidth
                    canvasElem.height = videoHeight
                    canvasElem.getContext('2d').drawImage(video, 0, 0, videoWidth, videoHeight)
                    // 导出成blob文件
                    canvasElem.toBlob(blob => {
                        // 将blob文件转换成png文件
                        const thumbFile = toThumbFile(blob)
                        let cover_formdata = new FormData();
                        cover_formdata.append("file", thumbFile)
                        const xhr = new XMLHttpRequest()
                        xhr.open('post', 'https://api.t-uzx.com/uc/upload/oss/image', true)
                        xhr.send(cover_formdata)
                        xhr.addEventListener('readystatechange', function () {
                            if (xhr.readyState === 4 && xhr.status == 200) {
                                let res = JSON.parse(xhr.response)
                                if (res.code == 0) {
                                    tempFileObj.cover = res.data
                                    resolve(tempFileObj)
                                } else {
                                    tempFileObj.cover = ""
                                }
                            }
                        })
                    }, 'image/png')
                })

            })
            let p2 = new Promise((resolve, reject) => {
                let tempFileObj = {
                    url: ""
                }
                let video_formdata = new FormData();
                video_formdata.append("file", value.target.files[0])
                const video_xhr = new XMLHttpRequest()
                video_xhr.open('post', 'https://api.t-uzx.com/uc/upload/oss/video')
                video_xhr.send(video_formdata)
                video_xhr.addEventListener('readystatechange', function () {
                    if (video_xhr.readyState === 4 && video_xhr.status == 200) {
                        let res = JSON.parse(video_xhr.response)
                        if (res.code == 0) {
                            let tempPreviewItem = document.createElement("div")
                            tempPreviewItem.className = "preview-item"
                            let tempPreviewMask = document.createElement("div")
                            tempPreviewMask.className = "preview-mask"
                            let tempShowImg = document.createElement("span")
                            tempShowImg.className = "showImg"
                            tempShowImg.innerText = "查看"
                            tempPreviewItem.setAttribute('dataindex', previewBox.childElementCount)
                            let tempDelImg = document.createElement("span")
                            tempDelImg.className = "delImg"
                            tempDelImg.innerText = "删除"
                            imgVideoUrl = res.data
                            tempFileObj.url = res.data
                            // 创建video标签插入到预览元素
                            let tempVideo = document.createElement("video")
                            tempVideo.src = imgVideoUrl
                            tempVideo.style.objectFit = "fill"
                            tempPreviewMask.appendChild(tempShowImg)
                            tempPreviewMask.appendChild(tempDelImg)
                            tempPreviewItem.appendChild(tempPreviewMask)
                            tempPreviewItem.appendChild(tempVideo)
                            previewBox.appendChild(tempPreviewItem)
                            if (previewBox.childElementCount >= 9) {
                                cardEle.style.display = "none"
                            }
                            resolve(tempFileObj)
                        }
                    }
                })
            })

            icon.style.display = "none"
            loading.style.display = "block"
            isLoading = true
            Promise.all([p1, p2]).then((results) => {
                icon.style.display = "block"
                loading.style.display = "none"
                isLoading = false
                fileObj = { ...results[0], ...results[1] }
                file.push(fileObj)
            }).catch(e => { // 失败的时候则返回最先被reject失败状态的值
                console.log("error", e)
                icon.style.display = "block"
                loading.style.display = "none"
                isLoading = false
            })
        } else {
            let p = new Promise((resolve, reject) => {
                let tempObj = {
                    url: "",
                    width: "",
                    height: ""
                }
                loadImg(value.target.files[0]).then(img => {
                    tempObj.width = img.width
                    tempObj.height = img.height
                })
                let formdata = new FormData();
                formdata.append("file", value.target.files[0])
                const xhr = new XMLHttpRequest()
                xhr.open('post', 'https://api.t-uzx.com/uc/upload/oss/image', true)
                xhr.send(formdata)
                xhr.addEventListener('readystatechange', function () {
                    if (xhr.readyState === 4 && xhr.status == 200) {
                        let res = JSON.parse(xhr.response)
                        if (res.code == 0) {
                            let tempPreviewItem = document.createElement("div")
                            tempPreviewItem.className = "preview-item"
                            let tempPreviewMask = document.createElement("div")
                            tempPreviewMask.className = "preview-mask"
                            let tempShowImg = document.createElement("span")
                            tempShowImg.className = "showImg"
                            tempShowImg.innerText = "查看"
                            tempPreviewItem.setAttribute('dataindex', previewBox.childElementCount)
                            let tempDelImg = document.createElement("span")
                            tempDelImg.className = "delImg"
                            tempDelImg.innerText = "删除"
                            tempObj.url = res.data
                            imgVideoUrl = res.data
                            let tempImg = document.createElement("img")
                            tempImg.src = imgVideoUrl
                            tempPreviewMask.appendChild(tempShowImg)
                            tempPreviewMask.appendChild(tempDelImg)
                            tempPreviewItem.appendChild(tempPreviewMask)
                            tempPreviewItem.appendChild(tempImg)
                            previewBox.appendChild(tempPreviewItem)
                            if (previewBox.childElementCount >= 9) {
                                cardEle.style.display = "none"
                            }
                            resolve(tempObj)
                        }
                    }
                })

            })
            icon.style.display = "none"
            loading.style.display = "block"
            isLoading = true
            p.then(results => {
                icon.style.display = "block"
                loading.style.display = "none"
                isLoading = false
                fileObj = { ...results }
                file.push(fileObj)
            }).catch(err => {
                icon.style.display = "block"
                loading.style.display = "none"
                isLoading = false
            })
        }
        value.target.value = ""
    }



    const showImg = document.querySelector('.showImg');
    const modal = document.getElementById('modal');
    const modalImg = document.getElementById('modalImg');
    const modalVideo = document.getElementById('modalVideo');
    const closeIcon = document.getElementById('closeIcon');
    const previewItem = document.querySelector(".preview-item")


    // 利用事件委托 点击预览图片
    previewBox.onclick = function (event) {
        if (event.target.parentElement.parentElement.attributes.dataindex) {
            // 查询当前点击的索引
            let index = event.target.parentElement.parentElement.attributes.dataindex.value
            let currentIndex
            Array.from(event.target.parentElement.parentElement.parentElement.children).forEach((item, jindex) => {
                if (index == item.getAttribute("dataindex")) {
                    currentIndex = jindex
                    return item
                }
            })
            // 判断点击的是查看还是删除
            if (event.target.innerText == "查看") {
                let previewSrc = event.target.parentElement.parentElement.children[1].src
                imgVideoType = event.target.parentElement.parentElement.lastChild.localName
                modal.style.width = '100%';
                modal.style.height = '100%';
                if (imgVideoType == "video/mp4" || imgVideoType == "video") {
                    modalImg.style.display = "none"
                    modalVideo.style.display = "block"
                    modalVideo.src = previewSrc;
                    modalVideo.controls = true
                    modalVideo.loop = true
                    modalVideo.autoplay = true
                } else {
                    modalVideo.style.display = "none"
                    modalImg.style.display = "block"
                    modalImg.src = previewSrc;
                }
            } else if (event.target.innerText == "删除") {
                this.removeChild(Array.from(previewBox.children)[currentIndex])
                file.splice(currentIndex, 1)
                if (file.length < 9) {
                    cardEle.style.display = "block"
                }
            }
        }

    }

    // 关闭 modal 框
    closeIcon.onclick = function () {
        modal.style.width = '0';
        modal.style.height = '0';
        modalImg.src = '';
    }
    modal.onclick = function () {
        modal.style.width = '0';
        modal.style.height = '0';
        modalImg.src = '';
    }


    const btn = document.querySelector(".btn")
    btn.onclick = function () {
        console.log(JSON.stringify(file), "文件")
    }
    const editBtn = document.querySelector(".edit-btn")
    let filelist = ["https://uzx.oss-cn-hongkong.aliyuncs.com/2023/12/19//063ee6bb-68ed-4909-9b58-8a38059d9350.png", "https://uzx.oss-cn-hongkong.aliyuncs.com/2023/12/19//0fb187fb-867d-4ad8-83d6-5d9a88d5df17.jpg",]
    editBtn.onclick = function () {
        filelist.forEach(item => {
            let tempPreviewItem = document.createElement("div")
            tempPreviewItem.className = "preview-item"
            let tempPreviewMask = document.createElement("div")
            tempPreviewMask.className = "preview-mask"
            let tempShowImg = document.createElement("span")
            tempShowImg.className = "showImg"
            tempShowImg.innerText = "查看"
            tempPreviewItem.setAttribute('dataindex', previewBox.childElementCount)
            let tempDelImg = document.createElement("span")
            tempDelImg.className = "delImg"
            tempDelImg.innerText = "删除"
            if (file.length >= 9) {
                cardEle.style.display = "none"
                return
            }
            file.push(item)
            imgVideoUrl = item
            // 判断是视频还是图片
            if (item.endsWith(".mp4")) {
                let tempVideo = document.createElement("video")
                tempVideo.src = imgVideoUrl
                tempPreviewMask.appendChild(tempShowImg)
                tempPreviewMask.appendChild(tempDelImg)
                tempPreviewItem.appendChild(tempPreviewMask)
                tempPreviewItem.appendChild(tempVideo)

                previewBox.appendChild(tempPreviewItem)
            } else {
                let tempImg = document.createElement("img")
                tempImg.src = imgVideoUrl
                tempPreviewMask.appendChild(tempShowImg)
                tempPreviewMask.appendChild(tempDelImg)
                tempPreviewItem.appendChild(tempPreviewMask)
                tempPreviewItem.appendChild(tempImg)
                previewBox.appendChild(tempPreviewItem)
            }

        })
        if (file.length >= 9) {
            cardEle.style.display = "none"
            return
        }

    }


    // 获取视频信息
    function loadVideo(file) {
        return new Promise(function (resolve, reject) {
            const videoElem = document.createElement('video')
            const dataUrl = URL.createObjectURL(file)
            // 当前帧的数据是可用的
            videoElem.onloadeddata = function () {
                resolve(videoElem)
            }
            videoElem.onerror = function () {
                reject('video 后台加载失败')
            }
            // 设置 auto 预加载数据, 否则会出现截图为黑色图片的情况
            videoElem.setAttribute('preload', 'auto')
            videoElem.src = dataUrl
        })
    }

    // 获取图片信息
    function loadImg(file) {
        return new Promise(function (resolve, reject) {
            const imgElem = document.createElement('img')
            const dataUrl = URL.createObjectURL(file)
            imgElem.src = dataUrl
            // 当前帧的数据是可用的
            imgElem.onload = function () {
                resolve(imgElem)
            }
            imgElem.onerror = function () {
                reject('img 后台加载失败')
            }
        })
    }
    // blob文件转成file文件
    function toThumbFile(blob) {
        return new File([blob], 'thumb__img.png')
    }

</script>


</html>

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是用原生js实现表单非空判断、新增和删除功能的代码: HTML代码: ```html <form id="myForm"> <input type="text" id="inputName" placeholder="Name"> <input type="email" id="inputEmail" placeholder="Email"> <button type="button" id="addButton">Add</button> </form> <ul id="list"></ul> ``` JavaScript代码: ```javascript // 获取表单元素和列表元素 var form = document.getElementById('myForm'); var inputName = document.getElementById('inputName'); var inputEmail = document.getElementById('inputEmail'); var list = document.getElementById('list'); // 添加按钮点击事件 document.getElementById('addButton').addEventListener('click', function() { // 判断表单是否为空 if (inputName.value.trim() === '' || inputEmail.value.trim() === '') { alert('Please fill in all fields!'); return; } // 创建列表项 var li = document.createElement('li'); var text = document.createTextNode(inputName.value + ' - ' + inputEmail.value); li.appendChild(text); // 创建删除按钮 var deleteButton = document.createElement('button'); deleteButton.innerHTML = 'Delete'; deleteButton.addEventListener('click', function() { list.removeChild(li); }); li.appendChild(deleteButton); // 添加到列表中 list.appendChild(li); // 清空表单 inputName.value = ''; inputEmail.value = ''; }); // 阻止表单提交 form.addEventListener('submit', function(event) { event.preventDefault(); }); ``` 这段代码实现了以下功能: 1. 判断表单是否为空,如果为空则弹出提示框。 2. 创建列表项和删除按钮,并添加到列表中。 3. 清空表单。 4. 阻止表单提交事件的默认行为。 这样,就可以在表单中输入姓名和电子邮件地址,点击“Add”按钮添加到列表中,点击“Delete”按钮删除列表项。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值