如何预测HTML元素的宽度,以便在不透明度和宽度上进行CSS转换?

问题描述 投票:1回答:2
  • 我正在处理带有spaninnerText节点。
  • 在运行时,我将更改innerText,以便节点的offsetWidth将根据future-innerText长度发生变化。
  • 我需要预见未来-offsetWidth,以便通过CSS处理宽度本身的transition
  • 在这种情况下,特别是,我需要在transitionopacity元素的width上制作span,所以我不能立即改变inneText

我怎样才能预测width的确切价值?

更一般地说,有一种方法可以“模拟”DOM更改,以便了解未来的CSS属性?

可能的起始代码段

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>
javascript html css dom css-transitions
2个回答
2
投票

正如我在评论中提到的,您可以克隆元素,将其内容设置为您想要的内容,并测量其宽度。然后,您可以将原始宽度更改为从克隆元素获得的宽度。

像这样:

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>

0
投票

受@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>
© www.soinside.com 2019 - 2024. All rights reserved.