使用 setInterval() 连续改变一个元素的宽度

3
所以我想要更改一个元素的宽度,并将其放置在 h1 元素内。每4秒使用 setInterval()更改 h1 的textContent。 我想这样做是为了给宽度属性添加转换,以填充 h1 和下一个单词之间的空白,使过渡变得平滑。
我尝试使用 getBoundingClientRect()获取元素的宽度,但它没有起作用。而当我设置宽度时,它仍然是第一个元素的宽度,并且没有随着所需动态更改。
这是代码:

const changingSpan = document.querySelector('.changing-span');
let array = ['best', 'tastiest', 'freshest'];
let count = 0;

setInterval(function() { 
    count++;
    let elementWidth = changingSpan.getBoundingClientRect().width.toString();
    if(count === array.length) count = 0;
    changingSpan.classList.add('animation-span');
    changingSpan.textContent = array[count];
    changingSpan.style.width = `${elementWidth}px`;
    changingSpan.addEventListener('animationend', function() {
    changingSpan.classList.remove('animation-span');
    })
  }, 4000);
.changing-span {
    display: inline-block;
    color: #c82929;
    transition: width .2s ease;
}

.animation-span {
    animation: moveDown .8s ease;
}

@keyframes moveDown {
    0% {opacity: 0;
        transform: translateY(-50%);
    }

    100% {
        transform: translateY(0);
    }
}
<h1 class="first-heading">The <span class="changing-span">best</span> burgers in town.</h1>


1
使用两个嵌套的span元素。内部的span应该是你测量单词宽度的元素。外部的span应该是你设置宽度的元素。这样,就不会有来自你试图测量的span上最后一个单词的硬编码宽度留下来。 - Sean
我尝试过了,但它仍然不起作用。 - xander17
其实,我当时并没有理解答案。现在终于明白了,那就是我需要将 span 包裹在另一个 span 中。谢谢! - xander17
3个回答

0
考虑使用 max-width 实现动画效果:

const changingSpan = document.querySelector('.changing-span');
let array = ['best', 'tastiest', 'freshest'];
let count = 0;

setInterval(function() {
  count++;
  if (count === array.length) count = 0;
  changingSpan.classList.add('animation-span');
  changingSpan.textContent = array[count];
  changingSpan.addEventListener('animationend', function() {
    changingSpan.classList.remove('animation-span');
  })
}, 4000);
.changing-span {
  display: inline-block;
  color: #c82929;
}

.animation-span {
  animation: moveDown .8s ease;
}

@keyframes moveDown {
  0% {
    opacity: 0;
    transform: translateY(-50%);
    max-width:0;
  }
  100% {
    transform: translateY(0);
    max-width:200px; /* a big value here */
  }
}
<h1 class="first-heading">The <span class="changing-span">best</span> burgers in town.</h1>


谢谢,但我不喜欢这个效果。如果有帮助的话,我想要像stackoverflow首页上的第一个标题那样的东西。 - xander17

0
你的代码非常好。但是你需要删除如下2行代码,然后你的代码就可以按照你想要的方式正常工作。 let elementWidth = changingSpan.getBoundingClientRect().width.toString(); changingSpan.style.width = ${elementWidth}px;

是的,它可以工作,但当添加一个新单词并且句子被调整大小时,它会立即发生,而我希望它可以平滑地关闭单词之间的间隙。 - xander17

0

所以答案是由Sean(谢谢)在上面发布的。我将在此放置代码片段,以防有人搜索类似的内容并想做相同的事情:

const changingSpan = document.querySelector('.changing-span');
const changingSpanWrapper = document.querySelector('.changing-span-wrapper');
let array = ['best', 'tastiest', 'freshest'];
let count = 0;

changingSpanWrapper.style.width = `${changingSpan.getBoundingClientRect().width.toString()}px`;
setInterval(function() { 
    count++;
    if(count === array.length) count = 0;
    changingSpan.classList.add('animation-span');
    changingSpan.textContent = array[count];
    changingSpan.addEventListener('animationstart', function() {
      let elementWidth = changingSpan.getBoundingClientRect().width.toString();
      let elementHeight = changingSpan.getBoundingClientRect().height.toString();
      changingSpanWrapper.style.width = `${elementWidth}px`;
      changingSpanWrapper.style.height = `${elementHeight}px`;
    })
    changingSpan.addEventListener('animationend', function() {
    changingSpan.classList.remove('animation-span');
    })
  }, 4000);
.changing-span-wrapper {
    display: inline-block;
    transition: width .2s ease, height .2s ease;
}

.changing-span {
    display: inline-block;
    color: #c82929;
}

.animation-span {
    animation: moveDown 1s ease;
}

@keyframes moveDown {
    0% {opacity: 0;
        transform: translateY(-50%);
    }

    100% {
        transform: translateY(0);
    }
}
<h1 class="first-heading">The <span class="changing-span-wrapper"><span class="changing-span">best</span></span> burgers in town.</h1>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接