首页 > 解决方案 > 检测旁边有右对齐元素的溢出

问题描述

我有带有右对齐向下箭头的表格标题,以指示表格何时按该列排序。这些列可以调整大小,如果标题溢出并因此被截断,我需要在鼠标悬停时显示工具提示...。但是,我无法弄清楚在这种情况下如何正确检测溢出。我尝试了两种方法:向右浮动箭头和使用 flexbox 定位。

这是两种方法的小提琴。

该小提琴中的第 2 列有一个右浮动箭头,第 3 列使用 flex。问题:

如何使用该示例中给出的布局正确检测溢出?我不想要任何涉及克隆元素的方法。我的样式表太复杂了,这种方法无法正常工作,而且它的性能也很糟糕。

小提琴的代码在下面,所以它也包含在这个问题中。

document.querySelectorAll('span.ellipsis-overflow').forEach((el) => {
  if (el.offsetWidth < el.scrollWidth) {
    el.style.color = 'red';
  }
});
#col-2 {
  width: 80px; /* set to 60px to trigger overflow detection */
}

#col-3 {
  width: 80px;
}

.float i {
  float: right;
}

span.flex-container {
  display: flex;
  flex-direction: row;
}

span.flex-container i {
  margin-left: auto;
}

.ellipsis-overflow {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ellipsis-overflow * {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* below this is just style stuff to make the problem easier to see */

table {
  border-collapse: collapse;
  text-align: left;
  table-layout: fixed;
  width: 400px;
}

th {
  border: 1px solid black;
}

i.material-icons {
  font-size: 16px !important;
  display: inline-flex;
}
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

<p>Column text will be red if <code>offsetWidth</code> is less than
<code>scrollWidth</code>, indicating overflow. Trigger this in column 2 by setting
its width to 60px.</p>

<table>
  <thead>
    <tr>
      <th>Column 1</th>
      <th id="col-2" class="float">
        <span class="ellipsis-overflow">
          <i class="material-icons">arrow_downward</i>
          Column 2
        </span>
      </th>
      <th id="col-3">
        <span class="ellipsis-overflow">
          <span class="flex-container">
            <span>Column 3</span>
            <i class="material-icons">arrow_downward</i>
          </span>
        </span>
      </th>
    </tr>
  </thead>
</table>

标签: htmlcss

解决方案


原始答案

您可以设置overflow: auto条件之前并将其设置回hidden条件之后。:)

请参阅下面的片段(我已将col-2宽度设置为60px):

document.querySelectorAll('span.ellipsis-overflow').forEach((el) => {
  el.style.overflow = "auto";
  if (el.offsetWidth < el.scrollWidth) {
    el.style.color = 'red';
  }
  el.style.overflow = "hidden";
});
#col-2 {
  width: 60px; /* set to 60px to trigger overflow detection */
}

#col-3 {
  width: 80px;
}

.float i {
  float: right;
}

span.flex-container {
  display: flex;
  flex-direction: row;
}

span.flex-container i {
  margin-left: auto;
}

.ellipsis-overflow {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ellipsis-overflow * {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* below this is just style stuff to make the problem easier to see */

table {
  border-collapse: collapse;
  text-align: left;
  table-layout: fixed;
  width: 400px;
}

th {
  border: 1px solid black;
}

i.material-icons {
  font-size: 16px !important;
  display: inline-flex;
}
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

<p>Column text will be red if <code>offsetWidth</code> is less than
<code>scrollWidth</code>, indicating overflow. Trigger this in column 2 by setting
its width to 60px.</p>

<table>
  <thead>
    <tr>
      <th>Column 1</th>
      <th id="col-2" class="float">
        <span class="ellipsis-overflow">
          <i class="material-icons">arrow_downward</i>
          Column 2
        </span>
      </th>
      <th id="col-3">
        <span class="ellipsis-overflow">
          <span class="flex-container">
            <span>Column 3</span>
            <i class="material-icons">arrow_downward</i>
          </span>
        </span>
      </th>
    </tr>
  </thead>
</table>

更新的答案

我认为您可以对父高度进行相同的检查。

请参阅下面的片段:

document.querySelectorAll('span.ellipsis-overflow').forEach((el) => {
	var initialHeight = el.parentElement.clientHeight;
	el.classList.add("letMeCheckWidth");
	if (initialHeight  < el.parentElement.clientHeight) {
  	el.style.color = 'red';
  }
	el.classList.remove("letMeCheckWidth");
});
#col-2 {
  width: 80px; /* set to 60px to trigger overflow detection */
}

#col-3 {
  width: 80px;
}

.float i {
  float: right;
}

span.flex-container {
  display: flex;
  flex-direction: row;
}

span.flex-container i {
  margin-left: auto;
}

.ellipsis-overflow {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ellipsis-overflow * {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}


.ellipsis-overflow.letMeCheckWidth {
  display: block;
  overflow: auto;
  text-overflow: inherit;
  white-space: normal;
}

.ellipsis-overflow.letMeCheckWidth * {
  overflow: auto;
  text-overflow: inherit;
  white-space: normal;
}

/* below this is just style stuff to make the problem easier to see */

table {
  border-collapse: collapse;
  text-align: left;
  table-layout: fixed;
  width: 400px;
}

th {
  border: 1px solid black;
}

i.material-icons {
  font-size: 16px !important;
  display: inline-flex;
}
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

<p>Column text will be red if <code>offsetWidth</code> is less than <code>scrollWidth</code>, indicating overflow. Trigger this in column 2 by setting its width to 60px.</p>

<table>
  <thead>
    <tr>
      <th>Column 1</th>
      <th id="col-2" class="float">
        <span class="ellipsis-overflow">
          <i class="material-icons">arrow_downward</i>
          Column 2
        </span>
      </th>
      <th id="col-3">
        <span class="ellipsis-overflow">
          <span class="flex-container">
            <span>Column 3</span>
            <i class="material-icons">arrow_downward</i>
          </span>
        </span>
      </th>
    </tr>
  </thead>
</table>

您也可以在jsfiddle上对其进行测试..


推荐阅读