【问题标题】:Changing Images from array in a hero section with SetInterval使用 SetInterval 从英雄部分中的数组更改图像
【发布时间】:2021-11-12 03:35:42
【问题描述】:

我正在制作一个作品集网站,并希望每隔几秒使用 SetInterval 制作一个带有过渡图像的英雄部分。我试过这个:

请注意,我将背景图片放在 CSS 中,而不是作为 HTML 中的 img。

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('未定义')

main.js:70 Uncaught TypeError: Cannot set properties of undefined (setting 'background')

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

【问题讨论】:

  • 我更新了你的 sn-p
  • container.style.background = newImg;更新背景并清除背景的所有其他属性
  • edit您的问题并添加您的错误文本,而不是错误文本的图像。
  • 您可能希望转换background 属性而不是opacity,因为您不会每秒更改opacity。您可能还想更改转换时间或超时,以便转换有时间在下一个开始之前完全运行。
  • 您不会在此处收到该错误。这意味着您在找到元素之前执行代码。包裹在window.addEventListener("load", function() {..... }); 中,也许改换类。然后图像可以在 CSS 中

标签: javascript html


【解决方案1】:

正如其他人所提到的,您需要确保 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>

【讨论】:

  • 您的startBackgroundTransition 不会启动转换,正如我在对该问题的评论中提到的那样......它还将调用startBackgroundTransition() 的结果分配给窗口的load 事件,而不是比函数本身。它在这里工作是因为 Stack Snippets 的 JavaScript 部分是在 DOM 加载后执行的。
  • 好点。我的错。改变那个。也感谢校对。 :)
  • 非常感谢!我稍后会试一试,如果一切顺利,我会告诉你。这个新手非常感谢帮助:)
  • @RickardElimää 嘿 :) 终于有时间尝试了!我插入了代码的 sn-ps,但不知何故我收到了这个错误,而不是“未捕获的类型错误:无法读取未定义的属性(读取 'setProperty')”嗯...
  • 并不奇怪,因为 container 变量未定义。发生这种情况是因为它是在创建 DOM 之前声明的。我更新了我的答案并将声明移到了startBackgroundTransition()
【解决方案2】:

你为什么使用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
}

【讨论】:

  • 延迟一秒的图像之间的持续过渡在哪里?
  • 您的“jQuery”示例不起作用。 jQuery 对象没有 style 属性。你必须使用.css('background', newImg)
  • 数组中没有添加空值;现代 ECMAScript 中允许使用尾随逗号的语法。传递给 CSS url 函数的参数周围的引号是完全有效的,并且在某些情况下确实需要。 OP想要一个无限循环。当您希望在每次出现之间暂停时,循环没有意义。
  • 感谢您的意见!!我正在使用 setinterval,因为这是我学校项目的一部分(所以使用 setinterval 将有助于获得更多分数哈哈)
  • 您可以在 for 循环中放置一个 setTimeout 以延迟 1000 毫秒(1 秒)
猜你喜欢
  • 2019-10-28
  • 1970-01-01
  • 2019-11-26
  • 1970-01-01
  • 2018-01-06
  • 2021-04-08
  • 2021-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多