开发者问题收集

使用 SetInterval 更改英雄部分中数组中的图像

2021-11-09
510

我正在制作一个作品集网站,想每隔几秒使用 SetInterval 制作一个带有过渡图像的英雄部分。我尝试了以下方法:

请注意,我将背景图像放在了 CSS 中,而不是 HTML 中的图像。

var images = [
'https://via.placeholder.com/728x90.png?text=slide1',
'https://via.placeholder.com/728x90.png?text=slide2',
'https://via.placeholder.com/728x90.png?text=slide3',
'https://via.placeholder.com/728x90.png?text=slide4',
];
var container = document.getElementById('hero');
var i = 0;
setInterval(function() {
  var newImg = "url('" + images[i] + "')"
//  console.log(newImg);
  container.style.background = newImg;
  i = i + 1;
  if (i == images.length) {
    i = 0;
  }
}, 1000);
#hero {
  height: 100vh;
  width: 100%;
  background: linear-gradient(rgba(0, 0, 0, 0.342), rgba(0, 0, 0, 0.342)), url('https://via.placeholder.com/728x90.png?text=slide1') fixed no-repeat center / cover;
  color: #fff9ff;
  transition: opacity 1s;
  opacity: 1;
}
<section id="hero">
  <div class="heroContainer">
    <div id="info">
      <h1>Lorem Ipsum</h1>
      <h2>Lorem ipsum.</h2>
      <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Reiciendis nesciunt excepturi quos obcaecati incidunt voluptatem ipsam sunt ipsum, autem deleniti cupiditate molestias quis unde quae totam porro dicta</p>
      <a id="heroButton" href="#">Contact Me</a>
    </div>
  </div>

图像没有过渡,并且出现了以下错误:

url('undefined')

main.js:70 Uncaught TypeError: 无法设置未定义的属性(设置“background”)

有人知道为什么吗?顺便说一句,我想继续使用 SetInterval!

2个回答

正如其他人提到的,您需要确保 JavaScript 在 DOM 加载 之后 执行。

我正在更新 CSS 变量,而不是设置 style 。我只是认为这样更方便。

我还摆脱了 i 变量,而是使用 Array.prototype.shift() (从最后一个位置移除 - 返回已移除的项目)和 Array.prototype.push() 来更改数组内图像的位置。

正如您所知,图像加载需要一段时间。您可以通过预加载图像来解决这个问题,但我不会在这里介绍。

如果您有更平滑的过渡(两个图像改变不透明度),那就更好了。

我也希望您不打算有一秒钟的间隔。或许可以每 30 秒更改一次:

var images = [
  'https://via.placeholder.com/701x90',
  'https://via.placeholder.com/702x90',
  'https://via.placeholder.com/703x90',
  'https://via.placeholder.com/704x90'
];

window.addEventListener("load", startBackgroundTransition);

function startBackgroundTransition() {
  var container = document.getElementById('hero');

  setInterval(function() {
    container.style.setProperty("--background-image", `url(${images[1]})`);
    images.push(images.shift());
  }, 1000);
}
#hero {
  --background-image: url(https://via.placeholder.com/701x90);
  height: 100vh;
  width: 100%;
  background: 
    linear-gradient(rgba(0, 0, 0, 0.342),
    rgba(0, 0, 0, 0.342)), 
    var(--background-image) fixed no-repeat center / cover;
  color: #fff9ff;
  /*transition: opacity 1s;
  opacity: 1;*/
}
<section id="hero">
  <div class="heroContainer">
    <div id="info">
      <h1>Lorem Ipsum</h1>
      <h2>Lorem ipsum.</h2>
      <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Reiciendis nesciunt excepturi quos obcaecati incidunt voluptatem ipsam sunt ipsum, autem deleniti cupiditate molestias quis unde quae totam porro dicta</p>
      <a id="heroButton" href="#">Contact Me</a>
    </div>
  </div>
Rickard Elimää
2021-11-09

为什么要使用 setInterval

For 循环可以处理这个问题:

var images = [
'https://via.placeholder.com/728x90.png?text=slide1',
'https://via.placeholder.com/728x90.png?text=slide2',
'https://via.placeholder.com/728x90.png?text=slide3',
'https://via.placeholder.com/728x90.png?text=slide4' // < un-needed comma
];
var container = document.getElementById('hero'); // Make sure you call the script after the element

for (var i = 0; i < images.length; i++) {

  // No need for quote marks in css "url()"

  var newImg = "url(" + images[i] + ")";
  container.style.background = newImg;

  if (i >= images.length) {
    i = 0;
  }
}

或者 while 循环:

var images = [
'https://via.placeholder.com/728x90.png?text=slide1',
'https://via.placeholder.com/728x90.png?text=slide2',
'https://via.placeholder.com/728x90.png?text=slide3',
'https://via.placeholder.com/728x90.png?text=slide4' // < un-needed comma
];
var container = document.getElementById('hero'); // Make sure you call the script after the element
let i = 0;
do {
  // No need for quote marks in css "url()"
  var newImg = "url(" + images[i] + ")";
  container.style.background = newImg;
  if (i >= images.length) {
    i = 0;
  }
} while (i < images.length);

jQuery:

var images = [
'https://via.placeholder.com/728x90.png?text=slide1',
'https://via.placeholder.com/728x90.png?text=slide2',
'https://via.placeholder.com/728x90.png?text=slide3',
'https://via.placeholder.com/728x90.png?text=slide4' // < un-needed comma
];
var container = $("#hero");

for (var i = 0; i < images.length; i++) {
  var newImg = "url(" + images[i] + ")";
  container.css("background", newImg);

  if (i >= images.length) {
    i = 0;
  }
}

jQuery while 循环:

var images = [
'https://via.placeholder.com/728x90.png?text=slide1',
'https://via.placeholder.com/728x90.png?text=slide2',
'https://via.placeholder.com/728x90.png?text=slide3',
'https://via.placeholder.com/728x90.png?text=slide4' // < un-needed comma
];
var container = $("#hero"); // Make sure you call the script after the element
let i = 0;
do {
  var newImg = "url(" + images[i] + ")";
  container.css("background", newImg);
  if (i >= images.length) {
    i = 0;
  }
} while (i < images.length);

您还在 css“url()”值周围加了引号。

您也不应该在过程完成后将 i 改回 0,因为这将导致无限循环。

编辑: 您说您正在使用 setInterval 进行 1 秒的延迟。

您可以在 for 中放置一个 setTimeout 循环:

JavaScript
var images = [
'https://via.placeholder.com/728x90.png?text=slide1',
'https://via.placeholder.com/728x90.png?text=slide2',
'https://via.placeholder.com/728x90.png?text=slide3',
'https://via.placeholder.com/728x90.png?text=slide4'
];
var container = document.getElementById('hero');
for (var i = 0; i < images.length; i++) {
  setTimeout(function() {
    var newImg = "url(" + images[i] + ")";
    container.style.background = newImg;

    if (i >= images.length) {
      i = 0;
    }
  }, 1000); // 1000ms -> 1s
}
Parking Master
2021-11-09