img.height问题(每次返回0)



我有以下html代码:

<body>
<div class="img-section">
</div>
</body>

和javascript

const init = function () {
var pic = document.createElement("img");
pic.src = "soflogo.png";
var src = document.getElementsByClassName("img-section")[0];
src.appendChild(pic);
let image = document.querySelector("img");
image.addEventListener("load", function() {
height = pic.height;
console.log(height);//this usually returns right value
})
console.log(pic.height);//this always returns 0
console.log(height);//this returns error (not defined for sure)
}
document.addEventListener("DOMContentLoaded", init);

我需要处理图像的高度。在javascript代码中,我想在页面上添加图像,然后我想对img.height做点什么。我尝试使用load事件,它通常很好(每10次刷新console.log(height(;返回奇怪的值,如0或完全不返回(。所以我需要修复控制台.log(pic.height(;始终返回0(位于加载事件的正下方(。非常感谢。(对不起我英语不好(

编辑:谢谢你的回答。但随之而来的是另一个问题。上面的代码只是我的项目的一个例子。主要任务是将图像放入三个div标记中。我希望,高度问题的修复会修复它,但它没有。所以,这是我的主要项目:

const init = function () {
let allGalleryData = [{
galleryName: "Terénní seminář 2015",
galleryThumbnailUrl: "gallery/Fotoseminar2015/",
galleryFullSizeUrl: "gallery/Fotoseminar2015/big",
galleryImages: [
{ url: '01.jpg', title: 'something', stars: 2.5, people: 91 },
{ url: '02.jpg', title: 'something', stars: 2.9, people: 42 },
{ url: '03.jpg', title: 'something', stars: 5, people: 19 },
{ url: '04.jpg', title: 'something', stars: 1.6, people: 31 },
{ url: '05.jpg', title: 'something', stars: 3.2, people: 20 },
{ url: '06.jpg', title: 'something', stars: 4.1, people: 43 },
{ url: '07.jpg', title: 'something', stars: 2.2, people: 21 },
{ url: '08.jpg', title: 'something', stars: 3.1, people: 82 },
{ url: '09.jpg', title: 'something', stars: 3.7, people: 18 },
{ url: '10.jpg', title: 'something', stars: 2.1, people: 58 },
{ url: '11.jpg', title: 'something', stars: 4.8, people: 98 },
{ url: '12.jpg', title: 'something', stars: 1.8, people: 25 },
{ url: '13.jpg', title: 'something', stars: 2.5, people: 41 },
{ url: '14.jpg', title: 'something', stars: 4.4, people: 33 },
{ url: '15.jpg', title: 'something', stars: 4.1, people: 28 },
{ url: '16.jpg', title: 'something', stars: 2.1, people: 53 },
{ url: '17.jpg', title: 'something', stars: 2.7, people: 24 },
{ url: '18.jpg', title: 'something', stars: 1.1, people: 72 },
{ url: '19.jpg', title: 'something', stars: 3.5, people: 96 },
{ url: '20.jpg', title: 'something', stars: 2.4, people: 3 },
{ url: '21.jpg', title: 'something', stars: 4.6, people: 32 },
{ url: '22.jpg', title: 'something', stars: 3.1, people: 45 },
{ url: '23.jpg', title: 'something', stars: 3.2, people: 23 },
{ url: '24.jpg', title: 'something', stars: 4.8, people: 19 },
{ url: '25.jpg', title: 'something', stars: 3.8, people: 13 },
{ url: '26.jpg', title: 'something', stars: 4.7, people: 71 },
{ url: '27.jpg', title: 'something', stars: 2.3, people: 96 },
{ url: '28.jpg', title: 'something', stars: 1.5, people: 84 },
{ url: '29.jpg', title: 'something', stars: 1.3, people: 13 }
]
},
{
galleryName: "Skotsko 2014",
galleryThumbnailUrlS: "gallery/Skotsko/",
galleryFullSizeUrl: "gallery/Skotsko/big",
galleryImagesNameUrl: [
{ url: 'Sk2014_01.JPG', title: 'Kanál v Amsterodamu', stars: 1.1, people: 24 },
{ url: 'Sk2014_02.JPG', title: 'Amsterodam (pobřeží)', stars: 3.4, people: 36 },
{ url: 'Sk2014_03.JPG', title: 'Trajekt do UK', stars: 1.3, people: 16 },
{ url: 'Sk2014_04.JPG', title: 'Pobřeží Skotska', stars: 3, people: 35 },
{ url: 'Sk2014_05.JPG', title: 'Urquhart Castle', stars: 2.3, people: 38 },
{ url: 'Sk2014_06.JPG', title: 'Břeh jezera', stars: 2.4, people: 50 },
{ url: 'Sk2014_07.JPG', title: 'Eilean Donan Castle', stars: 3.1, people: 31 },
{ url: 'Sk2014_08.JPG', title: 'Skotský skot', stars: 3.1, people: 40 },
{ url: 'Sk2014_09.JPG', title: 'The Old Man of Storr, Skye', stars: 2.9, people: 68 },
{ url: 'Sk2014_10.JPG', title: 'The Old Man of Storr, Skye', stars: 5, people: 71 },
{ url: 'Sk2014_11.JPG', title: 'Culloden', stars: 3.6, people: 45 },
{ url: 'Sk2014_12.JPG', title: 'Cawdor Castle', stars: 3.7, people: 31 },
{ url: 'Sk2014_13.JPG', title: 'Cairn Gorm', stars: 4.8, people: 77 },
{ url: 'Sk2014_14.JPG', title: 'Cairngorms National Park', stars: 4.8, people: 64 },
{ url: 'Sk2014_15.JPG', title: 'Tower Bridge', stars: 2.9, people: 61 },
{ url: 'Sk2014_16.JPG', title: 'Butler's Wharf', stars: 3.7, people: 78 },
{ url: 'Sk2014_17.JPG', title: 'London Eye', stars: 1.4, people: 85 },
{ url: 'Sk2014_18.JPG', title: 'Covent garden market - London', stars: 1.4, people: 76 },
{ url: 'Sk2014_19.JPG', title: 'Buckinghamský palác', stars: 2.4, people: 24 },
{ url: 'Sk2014_20.JPG', title: 'Big Ben London', stars: 4.2, people: 91 },
{ url: 'Sk2014_21.JPG', title: 'Big Ben London', stars: 3.5, people: 39 },
{ url: 'Sk2014_22.JPG', title: 'Big Ben London', stars: 3.7, people: 83 }
]
}
]
let column1Lenth = 0;
let column2Lenth = 0;
let column3Lenth = 0;
let height;
let source;
let path;
let image;
for (const i of allGalleryData) {
let seminar = i.galleryThumbnailUrl;
let skotsko = i.galleryThumbnailUrlS;
if (i.galleryImages) {
for (const img of i.galleryImages) {
path = seminar + img.url;
let pic = document.createElement("img");
pic.src = path;
image = document.querySelector("img");
image.addEventListener("load", function () {
height = pic.height;
if ((column1Lenth <= column2Lenth) && (column1Lenth <= column3Lenth)) {
column1Lenth += height;
source = document.getElementsByClassName("column1")[0];
source.appendChild(pic);
}
else if (((column2Lenth < column1Lenth) && (column2Lenth <= column3Lenth))) {
column2Lenth += height;
source = document.getElementsByClassName("column2")[0];
source.appendChild(pic);
}
else if ((column3Lenth < column1Lenth) && (column3Lenth < column2Lenth)) {
column3Lenth += height;
source = document.getElementsByClassName("column3")[0];
source.appendChild(pic);
}
})
}
}
else {
for (const img of i.galleryImagesNameUrl) {
path = skotsko + img.url;
let pic = document.createElement("img");
pic.src = path;
image = document.querySelector("img");
image.addEventListener("load", function () {
height = pic.height;
if ((column1Lenth <= column2Lenth) && (column1Lenth <= column3Lenth)) {
column1Lenth += height;
source = document.getElementsByClassName("column1")[0];
source.appendChild(pic);
}
else if (((column2Lenth < column1Lenth) && (column2Lenth <= column3Lenth))) {
column2Lenth += height;
source = document.getElementsByClassName("column2")[0];
source.appendChild(pic);
}
else if ((column3Lenth < column1Lenth) && (column3Lenth < column2Lenth)) {
column3Lenth += height;
source = document.getElementsByClassName("column3")[0];
source.appendChild(pic);
}
})
}
}
}
}
document.addEventListener("DOMContentLoaded", init);

尽管如此,如果我刷新网站,高度仍然为0的可能性很大。即使我使用加载事件。实际上,我在下面的javascript代码(//this USSUALLY returns right value(中提到了这个问题。那么,有人知道如何解决这个问题吗?(我是javascript的新手,大约三个月了,所以我不理解promise和async(

您可以尝试将init更改为async,并创建一个函数,该函数在加载事件完成后基本上返回一个promise,而await则返回该promise,如:

const loadPromise = url => new Promise((resolve, reject) => {
const img = new Image();
img.addEventListener('load', () => resolve(img));
img.src = url;
})
const init = async function () {
var pic = document.createElement("img");
pic.src = "https://www.w3schools.com/html/pic_trulli.jpg";
var src = document.getElementsByClassName("img-section")[0];
src.appendChild(pic);
const img = await loadPromise(pic.src);
//height = pic.height;
console.log(img.height);
}
document.addEventListener("DOMContentLoaded", init);
<div class="img-section"></div>

异步模式是您在任何JavaScript中都需要习惯的模式。等待加载映像只是异步发生的一个例子。几乎每次你都有这种模式:

doSomethingAsync(..., function() {
// Thing A
});
// Thing B

事物B将先于事物A。doSomethingAsync中的函数被称为回调,直到异步事件发生时才调用它。

您无法在JavaScript中处理异步性。要使事情B发生在事情a之后,请将事情B放在同一回调中:

image.addEventListener("load", function() {
height = pic.height;
// Do something with height
});

或者将异步的东西包装在Promise中,这将使你以一种可能感觉更自然或直观的方式对事情进行排序,此外还可以降低代码中的嵌套级别。

function waitForEvent(obj, eventName) {
return new Promise(resolve => obj.addEventListener(eventName, resolve));
}
async function getImageHeight(image) {
await waitForEvent(image, 'load');
return image.height;
}
// Chaining style
getImageHeight(pic)
.then(height => {
// Do something with height
return nextAsyncThing();
})
.then(dataFromOtherAsyncThing => {
// ...
});

或者更好的是,使用异步函数:

document.addEventListener("DOMContentLoaded", async () => {
const pic = document.createElement("img");
pic.src = "soflogo.png";
document.getElementsByClassName("img-section")[0].appendChild(pic);
const height = await getImageHeight(pic)
console.log(height);  // Should have the height
});

Onload是在实际加载图像之前打印高度之后调用的,因此是零高度的原因。

最新更新