HTML图像在页面加载和异步等待事件之后没有正确更新



我期望的流程:

  1. 在页面加载时,渲染图像的轮廓
  2. 在文本字段中输入猜测,或点击按钮显示轮廓中的图像
  3. 获取新图像并使用新图像的轮廓重新渲染页面

问题是渲染的剪影是前一个图像的剪影,而不是当前api响应中的图像
当页面加载时很明显,因为剪影&图片第一次是空白的
当你点击下一个时,新的轮廓没有显示,因为旧的轮廓没有消失

任一:

  1. 异步等待逻辑和语法中存在错误
  2. 由于异步,DOMdiv没有得到正确更新
  3. 图像元素的行为存在一些问题
  4. 设置和获取HTML对象时出现问题
  5. 我看不出还有其他问题

我尝试过的:

在代码中,我尝试在async之后直接设置document.getElementById("sourceImg")document.getElementById("silhouetteImg"),而不是在第59行和第69行设置它们的varssourceImgsilhouetteImg,这似乎没有改变任何

此外,我没有为异步回调中的最后一个函数setTimeout,这对没有影响

此外,我尝试过在HTML中自动刷新图像,但没有什么不同

api有一些不完整的数据,如果您得到的是null/breaked image
(在整页中打开的纯javascript(,请在测试期间跳过所有null响应

<!DOCTYPE html>
<head>
<style>
body {
font-family: monospace;
}
.centered {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 24px;
}
#footer {
position: fixed;
bottom:0;
left: 0;
right:0;
text-align: center;
}
</style>
<script>
var id
var name
var sourceImg = document.createElement('img');
sourceImg.setAttribute('id', "sourceImg");
sourceImg.setAttribute('crossorigin', "anonymous");
var silhouetteImg = document.createElement('img');
silhouetteImg.setAttribute('id', "silhouetteImg");
silhouetteImg.setAttribute('crossorigin', "anonymous");
// + "?" + new Date().getTime() crossorigin="anonymous"
function randomInteger(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function getSilhouette(){
var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');
if (sourceImg.width != 0){
//credit: https://dominoc925.blogspot.com/2012/08/javascript-example-code-to-create.html
canvas.width = sourceImg.width;
canvas.height = sourceImg.height;
ctx.drawImage(sourceImg,0,0);
var imgData = ctx.getImageData(0,0,canvas.width,canvas.height);
var pix = imgData.data;
//convert the image into a silhouette
for (var i=0, n = pix.length; i < n; i+= 4){
//set red to 0
pix[i] = 0;
//set green to 0
pix[i+1] = 0;
//set blue to 0
pix[i+2] = 0;
//retain the alpha value
pix[i+3] = pix[i+3];
}
ctx.putImageData(imgData,0,0);
silhouetteImg.src = canvas.toDataURL();
}
};
async function getPokemon() {
let response = await fetch('https://pokeapi.co/api/v2/pokemon/' + randomInteger(1,809));
let data = await response.json();
//if (null == data["sprites"]["other"]["official-artwork"]["front_default"]){getPokemon()}
id = data["id"]
name = data["name"]
sourceImg.src = data["sprites"]["other"]["official-artwork"]["front_default"];
console.log("new: " + id + " " + name + " " + sourceImg.src + " " + sourceImg.width + " " + sourceImg.height);
};
async function showOrNext(){
if (document.getElementById("showOrNext").innerHTML == "Show"){
// reveal the pokemon
document.getElementById("pokemon").src = sourceImg.src;
document.getElementById("answer").innerHTML = name + " ";
document.getElementById("link").innerHTML = "View on Bulbapedia";
document.getElementById("link").href = "https://bulbapedia.bulbagarden.net/wiki/" + name + "_(Pok%C3%A9mon)";
document.getElementById("result").innerHTML = "";
document.getElementById("myInput").type = "hidden";
document.getElementById("showOrNext").innerHTML = "Next";
document.getElementById("showOrNext").focus();
} else {
// get a new pokemon
await getPokemon().then(getSilhouette()).then(setTimeout(function(){
document.getElementById("pokemon").src = silhouetteImg.src;
document.getElementById("answer").innerHTML = "";
document.getElementById("link").innerHTML = "";
document.getElementById("result").innerHTML = "";
document.getElementById("myInput").type = "text";
document.getElementById("myInput").value = "";
document.getElementById("myInput").focus();
document.getElementById("showOrNext").innerHTML = "Show";
}), 1)
};
}
window.onload = function() {
showOrNext()
};
window.addEventListener("keyup", function(e) {
if (e.keyCode === 13 && document.getElementById("myInput").type != "hidden") {
if (name === document.getElementById("myInput").value){
showOrNext();
document.getElementById("result").innerHTML = "<span style='color: green;'>Correct</span>";
} else {
document.getElementById("result").innerHTML = "<span style='color: red;'>Wrong</span>";
}
}
}, false);
</script>

</head>
<body>
<div class="centered">
<img id="pokemon" crossorigin="anonymous">
<center>
<p><label id="answer"></label><a id="link" target="_blank"></a></p>
<input id="myInput" type="text" onblur="this.focus()" autofocus>
<button id="showOrNext" onclick="showOrNext()"></button>
<p><label id="result"></label></p>
</center>
</div>
<div id="footer">Pokémon and Pokémon character names are trademarks of Nintendo. This site is not affiliated with Nintendo.</div>
</body>

<!DOCTYPE html>
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
<style>
body {
font-family: monospace;
}
.centered {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 24px;
}
#footer {
position: fixed;
bottom: 0;
left: 0;
right: 0;
text-align: center;
}
#pokemon {
width: 40px;
height: 40px;
}
</style>
<script>
var id;
var name;
var sourceImg = document.createElement("img");
sourceImg.setAttribute("id", "sourceImg");
sourceImg.setAttribute("crossorigin", "anonymous");
var silhouetteImg = document.createElement("img");
silhouetteImg.setAttribute("id", "silhouetteImg");
silhouetteImg.setAttribute("crossorigin", "anonymous");
function randomInteger(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function getSilhouette() {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = sourceImg.width;
canvas.height = sourceImg.height;
ctx.drawImage(sourceImg, 0, 0);
var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var pix = imgData.data;
for (var i = 0, n = pix.length; i < n; i += 4) {
//set red to 0
pix[i] = 0;
//set green to 0
pix[i + 1] = 0;
//set blue to 0
pix[i + 2] = 0;
//retain the alpha value
pix[i + 3] = pix[i + 3];
}
ctx.putImageData(imgData, 0, 0);
silhouetteImg.src = canvas.toDataURL();
silhouetteImg.onload = () => {
document.getElementById("pokemon").src = silhouetteImg.src;
document.getElementById("answer").innerHTML = "";
document.getElementById("link").innerHTML = "";
document.getElementById("result").innerHTML = "";
document.getElementById("myInput").type = "text";
document.getElementById("myInput").value = "";
document.getElementById("myInput").focus();
document.getElementById("showOrNext").innerHTML = "Show";
};
}
async function getPokemon() {
let response = await fetch(
"https://pokeapi.co/api/v2/pokemon/" + randomInteger(1, 809)
);
let data = await response.json();
//if (null == data["sprites"]["other"]["official-artwork"]["front_default"]){getPokemon()}
id = data["id"];
name = data["name"];
sourceImg.src =
data["sprites"]["other"]["official-artwork"]["front_default"];
sourceImg.onload = () => {
getSilhouette();
};
}
function showOrNext() {
if (document.getElementById("showOrNext").innerHTML === "Show") {
// reveal the pokemon
document.getElementById("pokemon").src = sourceImg.src;
document.getElementById("answer").innerHTML = name + " ";
document.getElementById("link").innerHTML = "View on Bulbapedia";
document.getElementById("link").href =
"https://bulbapedia.bulbagarden.net/wiki/" +
name +
"_(Pok%C3%A9mon)";
document.getElementById("result").innerHTML = "";
document.getElementById("myInput").type = "hidden";
document.getElementById("showOrNext").innerHTML = "Next";
document.getElementById("showOrNext").focus();
} else {
// get a new pokemon
getPokemon();
}
}
window.addEventListener(
"keyup",
function (e) {
if (
e.keyCode === 13 &&
document.getElementById("myInput").type !== "hidden"
) {
if (name === document.getElementById("myInput").value) {
showOrNext();
document.getElementById("result").innerHTML =
"<span style='color: green;'>Correct</span>";
} else {
document.getElementById("result").innerHTML =
"<span style='color: red;'>Wrong</span>";
}
}
},
false
);
window.addEventListener("DOMContentLoaded", (event) => {
console.log("DOM fully loaded and parsed");
showOrNext();
});
</script>
</head>
<body>
<div class="centered">
<img id="pokemon" crossorigin="anonymous" />
<center>
<p>
<label id="answer"></label>
<a id="link" target="_blank"></a>
</p>
<input id="myInput" type="text" onblur="this.focus()" autofocus />
<button id="showOrNext" onclick="showOrNext()"></button>
<p><label id="result"></label></p>
</center>
</div>
<div id="footer">
Pokémon and Pokémon character names are trademarks of Nintendo. This site
is not affiliated with Nintendo.
</div>
</body>
</html>

最新更新