Javascript 是否有CSS方式或无回流方式来最小化元素的宽度(不增加高度)?

Javascript 是否有CSS方式或无回流方式来最小化元素的宽度(不增加高度)?,javascript,css,Javascript,Css,下面是一张iMessage的照片,很抱歉它有点大。在图中,您将看到不同的多行消息具有不同的宽度。事实上,每一条似乎都优化为最小宽度,而不创建换行符 下面是一些实现这种效果非常缓慢的代码 //查找元素在不变高的情况下可以具有的最小宽度 函数最小化WidthDomNode{ 如果domNode.offsetWidth{ const startHeight=domNode.offtheight; const startWidth=domNode.offsetWidth; 如果startWidth==

下面是一张iMessage的照片,很抱歉它有点大。在图中,您将看到不同的多行消息具有不同的宽度。事实上,每一条似乎都优化为最小宽度,而不创建换行符

下面是一些实现这种效果非常缓慢的代码

//查找元素在不变高的情况下可以具有的最小宽度 函数最小化WidthDomNode{ 如果domNode.offsetWidth<160{return;} const squinchFurther==>{ const startHeight=domNode.offtheight; const startWidth=domNode.offsetWidth; 如果startWidth==0{ 回来 } domNode.style.width=startWidth-1+px; //检查新尺寸前,等待回流 requestAnimationFrame=>requestAnimationFrame=>{ //如果高度增加,请返回 如果domNode.offthelight!==starthelight{ domNode.style.width=startWidth+px; }否则{ 进一步挤压; } }; } requestAnimationFrame=>RequestAnimationFrameSquinchFuture; } const divs=document.querySelectorAlldiv; 对于let i=0;i症结案例a我发现了一个技巧,它只能导致一次回流,但这有点糟糕。其基本要点是:

// helper fns from npm el-tool
const div = (children: HTMLElement[]) => {
  const out = document.createElement("div");
  children.forEach((child) => out.appendChild(child));
  return out;
}
const span = (text: string) => {
  const out = document.createElement("span");
  out.innerText = text;
  return out;
}


export default function minimalWidthDiv(innerText: string) {
  // split string into words with following spaces included
  const wordEls = innerText.trim().match(/\S+\s+/g).map(span);
  const thinDiv = div(wordEls);
  // set to hidden while computing width to avoid thrashy renders
  thinDiv.style.visibility = "hidden";

  // wait for first render
  requestAnimationFrame(() => requestAnimationFrame(() =>
    const numberOfLines = magicFnThatFindsNumberOfLines();
    const currentWidth = thinDiv.offsetWidth;
    const minimalWidth = currentWidth/numberOfLines;
    let bestWidth = 0;
    // figure out the best width based of the widths of the words
    // if more than two lines, the loop below won't work is most cases
    for (let i = 0; i < wordEls.length && bestWidth < minimalWidth; i++) {
      bestWidth += wordEls[i].offsetWidth;
    }
    // update the width of the thinDiv and make it visible.
    thinEl.style.width = bestWidth + "px";
    thinEl.style.visibility = "";
  ));
  return thinDiv;
}

这里的诀窍是将所有单词放在不同的跨距中,以便计算它们的宽度。从这里,可以计算出最小宽度,而不需要新的线条。

据我所知,仅使用CSS是不可能的。下面的解决方案将每个文本块保存在一个简单的+结构中,然后使用它来测量的宽度,并将其更新为具有正确宽度的display:block

看起来有一个最大宽度可以解释换行,也就是说,如果McCormick或Interest在前一行,那么宽度会太长。我相信我从未见过超过屏幕宽度约75%的消息。我已经为这个演示设置了160px的最大宽度

请注意,有两个for循环,这样可以缓存宽度,这样我们就不会不断地读写DOM并导致多次回流

函数更新位{ const elems=document.queryselectoral'.inner'; 常量长度=元素长度; 常数宽度=[]; //从DOM中读取 对于设i=0;i这是一个非常好的方法来减少一些松弛,但它仍然没有达到预期的效果。我已经修改了我的帖子,加入了一个片段,其中有一个关键案例,可以更好地说明我的意思。很抱歉,我第一次不清楚。@sephered我明白你的意思,但你要知道,你特别引用了iMessage,它不会以那种方式包装邮件,它会以我演示的方式包装邮件。尝试发送这样的邮件来查看。你确定这就是你需要的行为吗?我没有iMessage,但我相信这是真的。我的错误。就我的情况而言,我的解决方案很好。但是,这是如何发生的一个背景故事:在sketch/illustrator等工具中调整文本框的大小非常简单,结果是外观更好,占用的空间更少。如果我希望或需要在将来实时执行此操作,最好有一个更好的方法。这就是我的动力。