JavaScript - 未捕获的类型错误:类型错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11540041/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JavaScript - Uncaught TypeError: Type error
提问by test
I am trying to break a spritesheet and well, it's not putting it into a 2D array like it should. At the end of my code, near the console.log, it spits out ImageData...but when it tries to putImageData... I get Uncaught TypeError: Type error
我试图打破一个 spritesheet,好吧,它并没有像它应该的那样将它放入一个 2D 数组中。在我的代码末尾,在 console.log 附近,它吐出 ImageData...但是当它尝试 putImageData...我得到Uncaught TypeError: Type error
Help?
帮助?
and here's my code:
这是我的代码:
$(document).ready(function () {
console.log("Client setup...");
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
canvas.tabIndex = 0;
canvas.focus();
console.log("Client focused.");
var imageObj = new Image();
imageObj.src = "./images/all_tiles.png";
imageObj.onload = function() {
context.drawImage(imageObj, imageWidth, imageHeight);
};
var allLoaded = 0;
var tilesX = ImageWidth / tileWidth;
var tilesY = ImageHeight / tileHeight;
var totalTiles = tilesX * tilesY;
var tileData = [totalTiles]; // Array with reserved size
for(var i=0; i<tilesY; i++)
{
for(var j=0; j<tilesX; j++)
{
// Store the image data of each tile in the array.
tileData.push(context.getImageData(j*tileWidth, i*tileHeight, tileWidth, tileHeight));
allLoaded++;
}
}
if (allLoaded == totalTiles) {
console.log("All done: " + allLoaded);
console.log(tileData[1]);
context.putImageData(tileData[0], 0 ,0); // Sample paint
}
});
error happens at context.putImageData(tileData[0], 0 ,0); // Sample paint
错误发生在 context.putImageData(tileData[0], 0 ,0); // Sample paint
Here is example fiddle of code above http://jsfiddle.net/47XUA/
这是http://jsfiddle.net/47XUA/上面代码的示例小提琴
回答by apsillers
Your problem is that the first element of tileData
is not an ImageData
object, it's a plain number! When you initialized your array you used:
你的问题是第一个元素tileData
不是一个ImageData
对象,它是一个普通的数字!当你初始化你的数组时,你使用了:
var tileData = [totalTiles];
This means that tileData[0]
is equal to the value of totalTiles
, which is the number 483
. You are providing a number instead of an ImageData
object to putImageData
, and the browser is throwing an error in confusion. If you look at any other element in the rest of your array, you'll see it is successfully being populated with ImageData
objects as you expect; only the first element in the array is a number.
这意味着tileData[0]
等于 的值totalTiles
,即数字483
。您正在向 提供数字而不是ImageData
对象putImageData
,并且浏览器在混淆中抛出错误。如果您查看数组其余部分中的任何其他元素,您会发现它已ImageData
按预期成功填充了对象;只有数组中的第一个元素是数字。
You probably meant to do:
你可能打算这样做:
var tileData = new Array(totalTiles);
which would create an array with the specified length
property, instead of setting the first value in the array to a number. Personally, I would run some performance tests to see if that is even useful; you may be just as well using var tileData = [];
这将创建一个具有指定length
属性的数组,而不是将数组中的第一个值设置为数字。就个人而言,我会运行一些性能测试,看看这是否有用;你也可以使用var tileData = [];
回答by Dave Tameside
A type error is caused when a variable or object passed into a statement is not of a type that is expected for that command and can't be converted into something that is valid.
当传递给语句的变量或对象不是该命令预期的类型并且无法转换为有效的类型时,会导致类型错误。
See herefor a full definition of the error.
有关错误的完整定义,请参见此处。
So most likely that context or tileData is in an incorrect format or is null or undefined
所以很可能 context 或 tileData 的格式不正确,或者为 null 或未定义
回答by devnull69
It might be a racing condition. You are using drawImage only when the image ./images/all_tiles.png
has been loaded. But you are using the image data on the context beforethe onload fired. Try to move everything which is after the onload handler into the onload handler.
这可能是一种赛车状况。仅在./images/all_tiles.png
加载图像时才使用 drawImage 。但是您在 onload 触发之前在上下文中使用图像数据。尝试将 onload 处理程序之后的所有内容移动到 onload 处理程序中。
回答by Aesthete
The problem here is that the imageObj.onload()
function is being called AFTER the rest of the script is executed.
这里的问题是在imageObj.onload()
执行脚本的其余部分之后调用该函数。
This means that queries to getImageData()
are returning undefined, as there is no image data in the canvas when called.
这意味着查询getImageData()
返回未定义,因为在调用时画布中没有图像数据。
A simple way to fix this is to encapuslate the remaining script in the imageObj.onload
function, like so:
解决此问题的一个简单方法是将剩余的脚本封装在imageObj.onload
函数中,如下所示:
$(document).ready(function () {
console.log("Client setup...");
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
canvas.tabIndex = 0;
canvas.focus();
console.log("Client focused.");
var imageObj = new Image();
imageObj.src = "./images/all_tiles.png";
imageObj.onload = function() {
context.drawImage(imageObj, 0, 0);
var allLoaded = 0;
var tilesX = imageWidth / tileWidth;
var tilesY = imageHeight / tileHeight;
var totalTiles = tilesX * tilesY;
var tileData = new Array(); // Array with NO reserved size
for(var i=0; i<tilesY; i++)
{
for(var j=0; j<tilesX; j++)
{
// Store the image data of each tile in the array.
tileData.push(context.getImageData(j*tileWidth, i*tileHeight, tileWidth, tileHeight));
allLoaded++;
}
}
context.putImageData(tileData[0], 0 ,0); // Sample paint
}; // End 'imageObj.onload()' scope.
}); // End document ready function scope.
This ensures that any calls to getImageData()
are made after context.drawImage()
这可确保getImageData()
在之后进行任何调用context.drawImage()
You may also have a problem here that you are not drawing the image to cover the canvas. Change the line:
您可能还会在这里遇到问题,即您没有绘制图像来覆盖画布。更改行:
context.drawImage(imageObj, imageWidth, imageHeight);
to
到
context.drawImage(imageObj, 0, 0);
EDIT: You also had ImageWidth
and imageWidth
(same for height). Rename these.
编辑:你也有ImageWidth
和imageWidth
(身高相同)。重命名这些。
EDIT: Reserving the Array size here with new Array(totalTiles)
was causing an issue. When we pushed new tile images to the array, it pushed to the end of the pre-allocated array (starting at tileData[totalTiles]
). This is easily fixed by removing the size argument. Otherwise instead of using push()
we could copy the image data into the array in a loop, eg: tileData[n] = getImageData(...)
, starting at tileData[0]
.
编辑:在此处保留数组大小new Array(totalTiles)
导致了问题。当我们将新的切片图像推送到数组时,它推送到预分配数组的末尾(从 开始tileData[totalTiles]
)。这可以通过删除 size 参数轻松解决。否则,push()
我们可以将图像数据复制到循环中的数组中,例如:tileData[n] = getImageData(...)
,从 开始,而不是使用tileData[0]
。
回答by Lorenzo De Tomasi
I'm using Chrome.
我正在使用 Chrome。
context.drawImage(spritesheet.image, 0, 0, 4608, 768);// Works
context.drawImage(spritesheet.image, 768, 0, 768, 768, 4608, 768); // Doesn't work: Uncaught TypeError: Type error
Thank you!
谢谢!