我有这段代码:
<span><img id="user" src="http://placehold.it/100x100" alt="img"></span>
<span><h2 id="textToChange">text here</h2></span>
&#13;
当我更改#textToChange时,#user会自动移动,因为文本会发生变化,因为它会移动它。我想动画#user,这样它将以线性动画移动,而不是仅仅到达x值。 有可能实现或我疯了吗?感谢。
答案 0 :(得分:1)
这是一个有趣的小问题。让我把它分解成几个步骤:
现在,困难的部分是第2步和第3步。
对于第2步,您必须计算新文本的长度。这很棘手,因为没有内置函数可以告诉您文本与给定样式集的宽度。你几乎必须创建一个重复的元素并测量它。
对于步骤3,您必须在文本更改之前或之后移动元素而不会导致跳转。我这样做的方法是使用position: absolute
并将left
设置为当前位置(从而消除那里的任何混乱)。然后,我使用transform
(为了当前位置做一些数学计算)转换到正确的位置,以获得性能。在转换结束时,请删除style
属性并更改文本。
需要注意的另一件事是当图像变为position: absolute
时文本会四处跳跃。为简单起见,我将整行放在display: flex
容器中。如果您不想使用flex,可以在文本上使用inline-block
或block
并调整填充/高度,以便保留适当的空间。
这是我想出的(也在JSFiddle上):
var $img = document.getElementById('user');
var $text = document.getElementById('textToChange');
var $estimator = document.getElementById('estimator');
var extraWidth = $img.offsetLeft - $text.offsetWidth;
function estimate(text) {
$estimator.textContent = text;
var width = $estimator.offsetWidth;
$estimator.textContent = '';
return width;
}
document.getElementById('change-text')
.addEventListener('click', function() {
var newText = randomText();
var left = $img.offsetLeft;
$img.style.position = 'absolute';
$img.style.left = left + 'px';
$img.style.transition = 'transform linear 1s';
$img.style.transform = 'translateX(0)';
window.requestAnimationFrame(function() {
$img.style.transform = 'translateX(' + (extraWidth + estimate(newText) - left) + 'px)';
window.setTimeout(function() {
$text.textContent = newText;
$img.removeAttribute('style');
}, 1000);
});
});
// For testing
function randomText() {
var length = Math.floor(Math.random() * 43) + 3;
return 'Lorem ipsum dolor sit amet portris noc tefweep'.slice(0, length);
}
h2 {
position: relative;
height: 100px;
display: flex;
align-items: flex-end;
}
/* For measuring text width. I don't want it to be seen. */
.not-shown {
visibility: hidden;
color: transparent;
position: absolute;
z-index: -1;
}
<h2>
<span id="textToChange">text here</span>
<img id="user" src="http://placehold.it/100x100" alt="img">
</h2>
<h2 class="not-shown"><span id="estimator"></span></h2>
<button id="change-text">Change text</button>
请注意,如果文本转到多行,这不会很好。我选择不担心这种情况。