如何预测 HTML 元素的宽度,以便在不透明度和宽度上进行 CSS 过渡?
How to predict the width of an HTML Element in order to made a CSS transition on the opacity and the width?
- 我正在处理一个带有
innerText
的 span
节点。
- 在运行时,我会改变
innerText
所以节点的offsetWidth
会改变,这取决于未来-innerText
的长度。
- 我需要预见未来-
offsetWidth
以便通过 CSS. 处理宽度本身的 transition
- 在这种情况下,特别是,我需要在
opacity
和 width
上制作 transition
both =15=] 元素,所以我无法立即更改 inneText
。
如何预测 width
的准确值?
更一般地说,有一种方法可以 "simulate" DOM 更改以了解 future-CSS-properties?
可能的起始代码片段
let h1 = document.getElementsByTagName("h1")[0];
let span = document.getElementsByTagName("span")[0];
h1.addEventListener("click", function() {
if(span.innerText == "Better") {
span.innerText = "Awsome";
} else {
span.innerText = "Better";
}
})
h1 span {
border: 1px solid red;
display: inline-block;
padding: 4px;
transition-property: all;
}
<h1>Hello <span>Awsome</span> World!</h1>
正如我在评论中提到的,您可以克隆该元素,将其内容设置为您想要的内容,并测量其宽度。然后,您可以将原始宽度更改为从克隆元素获得的宽度。
像这样:
let h1 = document.getElementsByTagName("h1")[0];
let span = document.getElementsByTagName("span")[0];
span.style.width = `${span.clientWidth}px`;
h1.addEventListener("click", function() {
const nextWord = getNextWord();
const featureWidth = getFeatureWidth(nextWord);
span.style.color = 'rgba(0, 0, 0, 0)';
span.style.width = `${featureWidth}px`;
setTimeout(() => {
span.textContent = nextWord;
span.style.color = 'rgba(0, 0, 0, 1)';
}, 300);
});
function getNextWord() {
if(span.innerText == "Better") {
return "Awsome";
}
return "Better";
}
function getFeatureWidth(word) {
const clonedSpan = document.createElement('span');
clonedSpan.setAttribute('style', 'position: absolute;z-index: -1');
clonedSpan.textContent = word;
h1.appendChild(clonedSpan);
const width = clonedSpan.clientWidth;
h1.removeChild(clonedSpan);
return width;
}
h1 span {
border: 1px solid red;
display: inline-block;
padding: 4px;
transition: all .3s ease;
}
<h1>Hello <span>Awsome</span> World!</h1>
受@Mosh Feu 解决方案的启发,这里是案例的返工:
let h1;
let span;
let width;
let words;
let opacity;
let button;
button = document.getElementsByTagName("button")[0];
element = document.getElementById("word");
width = window.getComputedStyle(element).getPropertyValue("width");
words = [
'Better',
'Great',
'Best Ever',
'Incredible',
'Awsome'
];
element.setAttribute('style', `
color: rgba(0, 0, 0, ${opacity = 1});
width: ${width};
`);
let iterator = words.values();
function changeWord() {
let word;
let next;
let width;
next = iterator.next();
if (next.done) {
iterator = words.values();
next = iterator.next();
}
word = next.value;
width = getFeatureWidth(word);
element.setAttribute('style', `
color: rgba(0, 0, 0, ${opacity = 0});
width: ${width};
`);
setTimeout(() => {
element.textContent = word;
element.setAttribute('style', `
color: rgba(0, 0, 0, ${opacity = 1});
width: ${width};
`);
}, 300);
}
button.addEventListener("click", changeWord);
function getFeatureWidth(word) {
let clone;
let width;
let parent;
clone = element.cloneNode(true);
clone.setAttribute('style', `
position: absolute;
z-index: -1
`);
clone.textContent = word;
parent = element.parentElement;
parent.appendChild(clone);
width = window.getComputedStyle(clone).getPropertyValue("width");
parent.removeChild(clone);
return width;
}
#word {
border: 1px solid red;
background-color: rgba(0, 0, 0, .25);
display: inline-block;
transition-property: color, width;
transition-duration: .3s, .3s;
transition-delay: 0, 0;
transition-timing-function: ease, ease;
white-space: nowrap;
box-sizing: content-box;
}
<h1>
Hello <span id="word">Awsome</span> World!
</h1>
<button>Next</button>
- 我正在处理一个带有
innerText
的span
节点。 - 在运行时,我会改变
innerText
所以节点的offsetWidth
会改变,这取决于未来-innerText
的长度。 - 我需要预见未来-
offsetWidth
以便通过 CSS. 处理宽度本身的 - 在这种情况下,特别是,我需要在
opacity
和width
上制作transition
both =15=] 元素,所以我无法立即更改inneText
。
transition
如何预测 width
的准确值?
更一般地说,有一种方法可以 "simulate" DOM 更改以了解 future-CSS-properties?
可能的起始代码片段
let h1 = document.getElementsByTagName("h1")[0];
let span = document.getElementsByTagName("span")[0];
h1.addEventListener("click", function() {
if(span.innerText == "Better") {
span.innerText = "Awsome";
} else {
span.innerText = "Better";
}
})
h1 span {
border: 1px solid red;
display: inline-block;
padding: 4px;
transition-property: all;
}
<h1>Hello <span>Awsome</span> World!</h1>
正如我在评论中提到的,您可以克隆该元素,将其内容设置为您想要的内容,并测量其宽度。然后,您可以将原始宽度更改为从克隆元素获得的宽度。
像这样:
let h1 = document.getElementsByTagName("h1")[0];
let span = document.getElementsByTagName("span")[0];
span.style.width = `${span.clientWidth}px`;
h1.addEventListener("click", function() {
const nextWord = getNextWord();
const featureWidth = getFeatureWidth(nextWord);
span.style.color = 'rgba(0, 0, 0, 0)';
span.style.width = `${featureWidth}px`;
setTimeout(() => {
span.textContent = nextWord;
span.style.color = 'rgba(0, 0, 0, 1)';
}, 300);
});
function getNextWord() {
if(span.innerText == "Better") {
return "Awsome";
}
return "Better";
}
function getFeatureWidth(word) {
const clonedSpan = document.createElement('span');
clonedSpan.setAttribute('style', 'position: absolute;z-index: -1');
clonedSpan.textContent = word;
h1.appendChild(clonedSpan);
const width = clonedSpan.clientWidth;
h1.removeChild(clonedSpan);
return width;
}
h1 span {
border: 1px solid red;
display: inline-block;
padding: 4px;
transition: all .3s ease;
}
<h1>Hello <span>Awsome</span> World!</h1>
受@Mosh Feu 解决方案的启发,这里是案例的返工:
let h1;
let span;
let width;
let words;
let opacity;
let button;
button = document.getElementsByTagName("button")[0];
element = document.getElementById("word");
width = window.getComputedStyle(element).getPropertyValue("width");
words = [
'Better',
'Great',
'Best Ever',
'Incredible',
'Awsome'
];
element.setAttribute('style', `
color: rgba(0, 0, 0, ${opacity = 1});
width: ${width};
`);
let iterator = words.values();
function changeWord() {
let word;
let next;
let width;
next = iterator.next();
if (next.done) {
iterator = words.values();
next = iterator.next();
}
word = next.value;
width = getFeatureWidth(word);
element.setAttribute('style', `
color: rgba(0, 0, 0, ${opacity = 0});
width: ${width};
`);
setTimeout(() => {
element.textContent = word;
element.setAttribute('style', `
color: rgba(0, 0, 0, ${opacity = 1});
width: ${width};
`);
}, 300);
}
button.addEventListener("click", changeWord);
function getFeatureWidth(word) {
let clone;
let width;
let parent;
clone = element.cloneNode(true);
clone.setAttribute('style', `
position: absolute;
z-index: -1
`);
clone.textContent = word;
parent = element.parentElement;
parent.appendChild(clone);
width = window.getComputedStyle(clone).getPropertyValue("width");
parent.removeChild(clone);
return width;
}
#word {
border: 1px solid red;
background-color: rgba(0, 0, 0, .25);
display: inline-block;
transition-property: color, width;
transition-duration: .3s, .3s;
transition-delay: 0, 0;
transition-timing-function: ease, ease;
white-space: nowrap;
box-sizing: content-box;
}
<h1>
Hello <span id="word">Awsome</span> World!
</h1>
<button>Next</button>