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>