codeErr_getComputedStyle无法立即获取createElement创造的元素的属性

错误代码

    <div id="div"></div>
    <script>
        var imgEle = document.createElement('img');
        imgEle.src = "../318bb51754058e0b9d9e8c6455d146f2.jpg";
        imgEle.id = 'img';
        var $div = document.getElementById('div');
        $div.appendChild(imgEle);
        console.log(getComputedStyle(imgEle));//CSSStyleDeclaration
        console.log(getComputedStyle(document.getElementById('img')).width);//0
        console.log(getComputedStyle(imgEle).width);//0

如上代码所示:通过js代码在html中创建了一个img标签,并给其赋值了图片地址。但是无法通过getComputedStyle立即获取图片的宽高。

给代码添加异步处理

        var imgEle = document.createElement('img');
        imgEle.src = "../318bb51754058e0b9d9e8c6455d146f2.jpg";
        imgEle.id = 'img';
        var $div = document.getElementById('div');
        $div.appendChild(imgEle);
        setTimeout(() => {
            console.log(getComputedStyle(imgEle));
            console.log(getComputedStyle(document.getElementById('img')).width);//1920px
            console.log(getComputedStyle(imgEle).width);//1920px
        },100);

即因为添加的img标签渲染需要时间,无法立即通过访问文档获得其属性。

修改代码

    选择文件: <input type="file" name="file1" id="file1"><br>
    <input type="button" value="读取" onclick="show()">
    <div id="result"></div>
    <script>
        function readFile() {
            var p1 = new Promise((resolve, reject) => {
                var reader = new FileReader();
                var file1 = document.getElementById('file1').files[0];

                if (/image\/\w+/.test(file1.type)) {
                    reader.readAsDataURL(file1);
                    reader.onload = event => {
                        resolve(reader.result);
                    }
                } else {
                    reject('该文件不是图片文件');
                }
            });
            return p1;
        }

        function show() {
            readFile().then(
                data => {
                    new Promise((resolve, reject) => {
                        var imgEle = document.createElement('img');
                        imgEle.src = data;
                        imgEle.id = 'newCreateImg';
                        document.getElementById('result').appendChild(imgEle);
                        resolve(imgEle);
                    }).then(
                        data => {
                            console.log(getComputedStyle(data).width);
                            console.log(getComputedStyle(data).height);
                        }
                    )


                },
                reason => {
                    var pEle = document.createElement('p');
                    pEle.innerText = reason;
                    document.getElementById('result').appendChild(pEle);
                }
            )
        }

通过promise异步处理,创建标签完成后再调用resolve传递对象获取属性。

改写代码:链式调用then方法来改变图片的显示大小

    选择文件: <input type="file" name="file1" id="file1"><br>
    <input type="button" value="读取" onclick="show()"><br>
    <div id="result"></div>
    <script>
        var count = 0;

        function readFile() {
            count++;
            var p1 = new Promise((resolve, reject) => {
                var reader = new FileReader();
                var file1 = document.getElementById('file1').files[0];
                console.log(file1.type);
                if (/image\/\w+/.test(file1.type) || file1.type == '') {
                    reader.readAsDataURL(file1);
                    reader.onload = event => {
                        resolve(reader.result);
                    }
                } else {
                    reject('该文件不是图片文件');
                }
            });
            return p1;
        }

        function show() {
            readFile().then(
                data => {
                    var imgEle = document.createElement('img');
                    imgEle.src = data;
                    imgEle.id = `createImg${count}`;//动态创建id属性
                    console.log(imgEle.id);
                    document.getElementById('result').appendChild(imgEle);
                    var brEle = document.createElement('br');
                    document.getElementById('result').appendChild(brEle);
                    return imgEle;
                },
                reason => {
                    var pEle = document.createElement('p');
                    pEle.innerText = reason;
                    document.getElementById('result').appendChild(pEle);
                }
            ).then(
                data => {
                    var imgWidth = getComputedStyle(data).width.match(/\d+(.\d+)?/)[0];//注意不能直接用toString()方法转字符串,因为会被转成带逗号的字符串
                    var imgHeight = getComputedStyle(data).height.match(/\d+(.\d+)?/)[0];
                    var WHrate = (parseFloat(imgWidth) / parseFloat(imgHeight)).toFixed(2);//长宽比
                    var getImgElement = document.getElementById(`createImg${count}`);
                    console.log(getImgElement);
                    if (WHrate < 1 && imgHeight > 500) {
                        console.log('第一判定true');
                        getImgElement.style.height = '500px';
                        getImgElement.style.width = 500 * WHrate + 'px';
                    } else if (WHrate > 1 && imgWidth > 500) {
                        console.log('第二判定true');
                        getImgElement.style.width = '500px';
                        getImgElement.style.height = 500 / WHrate + 'px';
                    } else if (WHrate == 1 && imgWidth == 500) {
                        console.log('第三判定true');
                        getImgElement.style.width = '500px';
                        getImgElement.style.height = '500px';
                    }
                    console.log(``);
                }
            );
        }
    </script>

创建图片文件并把它加入到文档的最后面,但并不急着读取图片的属性,调用then方法读取属性,并修改图片的大小,限定在500X500之内并维持长宽比。

再改:使用catch方法传递rejiect的值,与then不同的是resolve传递出错的话同样会调用catch方法,而不是直接报错。

    <span class="col-2 text-right">浏览文件:</span>
    <input type="file" name="" id="file1" class="col-4 btn btn-light btn-outline-dark">
    <p></p>
    <input type="button" value="获取图片" class="btn btn-light btn-outline-dark col-4" onclick='show()'>
    <p></p>
    <figure class="figure">
        <figcaption class="figure-caption text-center">图片区</figcaption>
    </figure>
    <script>
        var count = 0;

        function fileRead() {
            count++;
            var p = new Promise((resolve, reject) => {
                var reader = new FileReader();
                var file1 = document.getElementById('file1').files[0];
                if (/image\/\w+/.test(file1.type)) {
                    reader.readAsDataURL(file1);
                    reader.onload = event => {
                        resolve(reader.result);
                    }
                } else {
                    reject('该文件不是图片文件');
                }
            });
            return p;
        }

        function show() {
            fileRead().then(
                data => {
                    var imgEle = document.createElement('img');
                    imgEle.src = data;
                    imgEle.id = `createImg${count}`;
                    document.getElementsByTagName('figure')[0].appendChild(imgEle);
                    return imgEle;
                }
            ).catch(
                reason => {
                    var pEle = document.createElement('p');
                    pEle.innerText = reason;
                    document.body.replaceChild(pEle, document.getElementsByTagName('figure')[0]);
                }
            ).then(
                data => {
                    var getImgEle = document.getElementById(`createImg${count}`)
                    var imgWidth = parseFloat(getComputedStyle(data).width.match(/\d+(.\d+)?/)[0]);
                    var imgHeight = parseFloat(getComputedStyle(data).height.match(/\d+(.\d+)?/)[0]);
                    var WHratio = imgWidth / imgHeight;
                    if (WHratio > 1 && imgWidth > 500) {
                        console.log('判定一成功');
                        getImgEle.style.width = '500px';
                        getImgEle.style.height = 500 / WHratio + 'px';
                        getImgEle.className = 'figure-img rounded';
                    } else if (WHratio < 1 && imgHeight > 500) {
                        console.log('判定二成功');
                        getImgEle.style.height = '500px';
                        getImgEle.style.width = 500 * WHratio + 'px';
                        getImgEle.className = 'figure-img rounded';
                    } else if (WHratio == 1 && imgWidth > 500) {
                        console.log('判定三成功');
                        getImgEle.style.width = getImgEle.style.height = 500 + 'px';
                        getImgEle.className = 'figure-img rounded';
                    } else {
                        console.log('判定四成功');
                        getImgEle.className = 'figure-img rounded';
                    }
                }
            )
        }
    </script>

再改:使用all方法获取所有的图片地址信息,并对所上传文件进行检测,一旦有一个文件不合格即弹出错误。如果全部文件格式正确即在html模板上创建图片

<body>
    上传图片: <input type="file" name="" id="file1" multiple>
    <input type="button" value="获取信息" onclick='show()'><br>
    <figure>
        <figcaption>图片区</figcaption>
    </figure>
    <script>
        function readFile(file) {
            var p = new Promise((resolve, reject) => {
                var reader = new FileReader();
                if (/image\/\w+/.test(file.type)) {
                    reader.readAsDataURL(file);
                    reader.onload = event => {
                        resolve(reader.result);
                    }
                } else {
                    reject('所上传文件包含不符合的文件格式');
                }
            });
            return p;
        }

        function readAll() {
            var file1 = document.getElementById('file1').files;
            var all = [];
            for (let i = 0; i < file1.length; i++) {
                all.push(readFile(file1[i]));
            }
            return all; //返回由图片地址组成的数组
        }

        function show() {
            Promise.all(readAll()).then(
                data => {
                    var count = 0;
                    var imgEle;
                    var imgEles = [];
                    for (let i = 0; i < data.length; i++) {
                        imgEle = document.createElement('img');
                        imgEle.src = data[i];
                        imgEle.id = count++;
                        document.getElementsByTagName('figure')[0].appendChild(imgEle);
                        imgEles.push(imgEle);
                    }
                    return imgEles;
                }
            ).catch(
                reason => {
                    alert(reason);
                    return '';
                }
            ).then(
                data => {
                    console.log(data);
                    var imgWidth, imgHeight, whRatio;
                    for (let i = 0; i < data.length; i++) {
                        imgWidth = parseFloat(getComputedStyle(data[i]).width.match(/\d+(.\d+)?/)[0]);
                        imgHeight = parseFloat(getComputedStyle(data[i]).height.match(/\d+(.\d+)?/)[0]);
                        whRatio = imgWidth / imgHeight;

                        if (whRatio > 1) {
                            data[i].style.width = '500px';
                            data[i].style.height = 500 / whRatio + 'px';
                        } else if (whRatio < 1) {
                            data[i].style.height = '500px';
                            data[i].style.width = 500 * whRatio + 'px';
                        } else if (whRatio == 1) {
                            data[i].style.height = data[i].style.width = '500px';
                        }
                    }
                },
                reason => {}
            )
        }
    </script>
</body>

再改写:使用race方法,传入多个promise对象

<body>
    <input type="file" name="" id="file1" multiple>
    <input type="button" value="获取信息" onclick="show()">
    <figure>
        <figcaption>图片区</figcaption>
    </figure>
    <script>
        function show() {
            function readFile(file) {
                //file 接收单个文件
                var reader = new FileReader();
                var p = new Promise((resolve, reject) => {
                    if (/image\/\w+/.test(file.type)) {
                        reader.readAsDataURL(file);
                        reader.onload = event => {
                            resolve(reader.result);
                        }
                    } else {
                        reject('所传文件格式不正确');
                    }
                });
                return p;
            }

            function readAll() {
                var proArr = [];
                var file1 = document.getElementById('file1').files;
                for (let i = 0; i < file1.length; i++) {
                    proArr.push(readFile(file1[i]));
                }
                return proArr;
                //返回promise对象数组
            }

            Promise.race(readAll()).then(
                data => {
                    //data是图片base64地址,只有一个
                    var imgEle = document.createElement('img');
                    imgEle.src = data;
                    document.getElementsByTagName('figure')[0].appendChild(imgEle);
                    return imgEle;
                }
            ).catch(
                reason => {
                    alert(reason);
                    return '';
                }
            ).then(
                data => {
                    var imgWidth = parseFloat(getComputedStyle(data).width.match(/\d+(.\d+)/)[0]);
                    var imgheight = parseFloat(getComputedStyle(data).height.match(/\d+(.\d+)/)[0]);
                    var whRatio = imgWidth / imgheight;
                    if (whRatio > 1) {
                        data.style.width = '500px';
                        data.style.height = 500 / whRatio + 'px';
                    } else if (whRatio < 1) {
                        data.style.height = '500px';
                        data.style.width = 500 * whRatio + 'px';
                    } else {
                        data.style.width = data.style.height = '500px';
                    }
                },
                reason => {

                }
            )
        }
    </script>
</body>
posted @ 2020-07-16 11:04  Syinho  阅读(277)  评论(0编辑  收藏  举报