【问题标题】:Uncaught TypeError cannot set property 'src' of null未捕获的 TypeError 无法将属性“src”设置为 null
【发布时间】:2012-08-01 03:56:02
【问题描述】:

所以在我的谷歌浏览器中的new website 上,我正在尝试使用 setInterval 函数使图像每 5 秒切换一次。这似乎可行,但是我遇到的问题是无法将属性 src 设置为 null。

var images = new Array();
images[0] = "/images/grilled-chicken-large.png";
images[1] = "/images/sizzly-steak.png";
var img = document.getElementById("img");

function changeImage() {
     for (var i = 0; i < 3; i++) {
        img.src = images[i];
        if (i == 2){i = i - 2;};
     }
}

window.onload=setInterval("changeImage()", 5000);

我知道问题是我试图在页面加载完成之前获取 id 为 img 的元素,但我已经有了一个 window.onload,所以我不知道该怎么做。另外,如果我创建一个包含 setInterval 和 img 变量的 init() 函数,页面就会冻结。

有什么想法吗?

【问题讨论】:

  • 您只有images[0]images[1],但您正在尝试访问images[2]
  • 旁注:不要将字符串传递给setInterval,它使用eval。传递函数:setInterval(changeImage, 5000);。此外,window.onload = setInterval(changeImage, 5000); 并没有按照您的想法行事。
  • 是的,刚刚意识到 bfavaretto,谢谢。火箭,你的意思是把它作为changeImage()而不是“changeImage()”传递吗?最后一行没有按照我的想法做是什么意思?
  • @Ilan:对于 cmets 来说有点太多了,请为他们创建单独的问题。最后一行执行setInterval,然后立即将该方法的结果(它是用作ID 的整数)分配给window.onload,这没有意义。看我的回答,我已经添加了onload 的东西。

标签: javascript html


【解决方案1】:

问题是您访问的数组元素 2 只有两个元素(0 和 1)。

但是您的脚本中也存在逻辑错误:您将当前可见图像的索引存储在哪里?您需要一个保存该索引的全局变量。

var currentIndex = 0;
function changeImage() {
    // Switch currentIndex in a loop
    currentIndex++;
    if (currentIndex >= images.length)
        currentIndex = 0;

    var img = document.getElementById("img");
    img.src = images[currentIndex];
}

document.onload = function() {
    setInterval(changeImage, 5000);
}

我已将img 变量移到函数中,以便在加载文档五秒后分配它。

澄清一下:JavaScript 是一种基于事件的编程语言。这意味着每次间隔触发时都会执行幻灯片更改代码,执行一些工作(切换到下一张幻灯片)然后完成,以便浏览器可以呈现页面。如果循环遍历幻灯片,浏览器将无法显示新幻灯片,因为脚本仍在幻灯片之间执行。解决方案就是我发布的内容:定义一个替换循环变量的全局变量,并在每次显示下一张幻灯片时递增它。

【讨论】:

  • Yogu,如果我把它做成 (var i = 0, i
  • Yogu,感谢您的帮助,我在没有 for 循环的情况下以稍微不同的方式找出了代码。
  • 欢迎在我的网站上查看
【解决方案2】:

这里:

window.onload = function () {

    var images = [
        'http://placekitten.com/100/200',
        'http://placekitten.com/200/100',
    ];

    var img = document.getElementById( 'img' );

    setInterval(function () {
        img.src = img.src === images[0] ? images[1] : images[0];
    }, 1000 );

};

现场演示: http://jsfiddle.net/wkqpr/


如果你有两个以上的图片,你可以这样做:

window.onload = function () {

    var images = [
        'http://placekitten.com/100/200',
        'http://placekitten.com/200/100',
        'http://placekitten.com/200/150',
        'http://placekitten.com/150/300'
    ];

    images.current = 0;

    var img = document.getElementById( 'img' );

    setInterval(function () {
        img.src = images[ images.current++ ];
        if ( images.current === images.length ) images.current = 0;       
    }, 1000 );

};

现场演示: http://jsfiddle.net/wkqpr/1/

【讨论】:

  • 为什么在最后一个 if 语句中使用“===”?
  • @IlanBiala 如果计数器等于数组长度,这意味着我必须重置计数器。
  • @IlanBiala == 运算符执行类型强制。强制规则不直观,不容易记住。因此,建议不要执行类型强制。您可以改为使用 === 运算符来做到这一点。
【解决方案3】:

你的 for 循环看起来很奇怪。试试那个循环:

function changeImage(){
  if(!img.attributes["index"]){img.attributes["index"]=0;return;};
  img.attributes["index"]++;
  img.src=images[img.attributes["index"]];
}
window.onload=function(){
  window.img=document.getElementById("img");
  setInterval("changeImage()",5000)
}

应该可以工作。
您会注意到我将图像索引存储在图像的属性中,而不是 一个全局变量。我认为全局稍微快一点,但将其存储在图像中 意味着如果需要,您可以轻松地将其扩展到多个图像。 此外,您的浏览器冻结的问题是以下代码:

for(var i=0;i<3;i++){
  //Some more stuff
  if(i==2){i-=2};
}

这个循环是无限的,因为每当i 到达2 时,i==2 就会变为真,这意味着迭代会将i 重置为0 并重新开始。防止这种情况发生的唯一方法是在某个地方使用break;,我在任何地方都看不到。 提示:在 for 循环中篡改索引变量通常是个坏主意。

【讨论】:

  • 我把它放在那里的原因是图片幻灯片循环播放,因为最终我将在那里有 25-30 张图片,一旦达到 25/30,或者在这种情况下为 2,我希望它循环回到开头。
【解决方案4】:
function changeImage() 
{
    for (var i = 0; i < 2; i++) 
    {
        img.src = images[i];
     }
}


window.onload=function()
{
    setInterval(changeImage,5000);
}

你在 for 循环中的最后一行完全没用,只会让事情复杂化, 另外,您设置窗口加载事件的方式不标准!

编辑:src 属性为 null,因为很明显,您的数组大小只有 2!!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-06
    • 2023-04-09
    • 2020-12-29
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 2016-12-02
    • 1970-01-01
    相关资源
    最近更新 更多