HTML - 如何在激活省略号时显示工具提示

Spi*_*man 182 html javascript css ellipsis tooltip

我的页面中包含省略号的动态数据.含义:

.my-class
{
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;  
  width: 71px;
}
Run Code Online (Sandbox Code Playgroud)

并且我想添加具有相同内容的此元素工具提示(title ='$ {myData}')但我希望它仅在内容很长并且省略号出现在屏幕上时才会出现.
有什么办法吗?

一个方向 - 当浏览器(在我的情况下是IE)绘制省略号时 - 它会抛出一个关于它的事件吗?

Jas*_*ban 159

这是使用内置省略号设置的方法,并title根据Martin Smith的评论添加按需(使用jQuery)属性:

$('.mightOverflow').bind('mouseenter', function(){
    var $this = $(this);

    if(this.offsetWidth < this.scrollWidth && !$this.attr('title')){
        $this.attr('title', $this.text());
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 如果您希望在文本不再溢出时自动删除工具提示,请修改为:$(document).on('mouseenter','.modeOverflow',function(){var $ t = $(this); var title = $ t.attr('title'); if(!title){if(this.offsetWidth <this.scrollWidth)$ t.attr('title',$ t.text())} else {if(this.offsetWidth> = this.scrollWidth && title == $ t.text())$ t.removeAttr('title')}}); (17认同)
  • 谢谢,像魅力一样!但是,如果你想提高效率,你可以考虑用on()替换bind(),如下所示:$(document).on('mouseenter','.modeOverflow',function(){...}); (4认同)
  • `“从jQuery 1.7开始,.on()方法是将事件处理程序附加到文档的首选方法”。有关更多信息,请参见http://api.jquery.com/bind/和http://api.jquery .com / on / (2认同)
  • 这个解决方案正确吗?offsetWidth 考虑了边框,因此如果边框与溢出大小相同,则此建议将不起作用。(这对我们来说是一个边缘情况)clientWidth 似乎是一个更好的选择。 (2认同)
  • 它在IE10上不起作用 - offsetWidth与scrollWidth相同,两者都给我截断的宽度. (2认同)

Snæ*_*ørn 49

这是一个纯CSS解决方案.不需要jQuery.它不会显示工具提示,而只是在鼠标悬停时将内容扩展到其全长.

如果您的内容被替换,则效果很好.然后你不必每次都运行jQuery函数.

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

.might-overflow:hover {
    text-overflow: clip;
    white-space: normal;
    word-break: break-all;
}
Run Code Online (Sandbox Code Playgroud)

  • 它不如工具提示好,因为它可能会破坏布局. (13认同)
  • 工具提示的问题在于,至少在目前,它们无法在移动设备上运行。这个答案可能(读:可能会)破坏布局,但可以进行调整,例如使所悬停的元素具有不同的背景颜色。这仍然无法在移动设备上使用,但这是台式机的另一种选择。 (2认同)
  • 这是一个很好的答案,比在 css 问题上膨胀 javascript 更好。显然省略号应该有一个自动标题选项,目前它的实现方式缺乏意义。太糟糕了 css 不允许只 :hover 如果最后一个字符是 '...' (2认同)

Ele*_*zar 32

uosɐs的答案基本上是正确的,但您可能不希望在mouseenter事件中这样做.每次将鼠标悬停在元素上时,这将导致它进行计算以确定是否需要它.除非元素的大小发生变化,否则没有理由这样做.

将元素添加到DOM后立即调用此代码会更好:

var $ele = $('#mightOverflow');
var ele = $ele.eq(0);
if (ele.offsetWidth < ele.scrollWidth)
    $ele.attr('title', $ele.text());
Run Code Online (Sandbox Code Playgroud)

或者,如果您不知道确切添加的时间,则在页面加载完成后调用该代码.

如果您需要使用多个元素,那么您可以为它们提供相同的类(例如"mightOverflow"),并使用此代码更新它们:

$('.mightOverflow').each(function() {
    var $ele = $(this);
    if (this.offsetWidth < this.scrollWidth)
        $ele.attr('title', $ele.text());
});
Run Code Online (Sandbox Code Playgroud)

  • 这种方法的问题是一次检查所有元素(潜在的性能影响)并且它只计算一次,这样如果用户缩小浏览器导致事物被截断或扩展,导致它们不再被截断你不能更新工具提示的存在.将代码附加到窗口再次调整大小会产生性能问题,因为每个项目都会检查其大小.通过使用事件委托"$(document).on('mouseenter','.mindOverflow',..."并延迟检查直到鼠标悬停元素,您可以动态更新并且只检查1个元素@一次 (9认同)

Ton*_*rix 17

这是我的jQuery插件:

(function($) {
    'use strict';
    $.fn.tooltipOnOverflow = function() {
        $(this).on("mouseenter", function() {
            if (this.offsetWidth < this.scrollWidth) {
                $(this).attr('title', $(this).text());
            } else {
                $(this).removeAttr("title");
            }
        });
    };
})(jQuery);
Run Code Online (Sandbox Code Playgroud)

用法:

$("td, th").tooltipOnOverflow();
Run Code Online (Sandbox Code Playgroud)

编辑:

我已经为这个插件做了一个要点. https://gist.github.com/UziTech/d45102cdffb1039d4415

  • 它在 IE10 上不起作用 - offsetWidth 与scrollWidth 相同,两者都给我截断的宽度。 (2认同)

小智 12

我们需要检测省略号是否真的应用,然后显示工具提示以显示全文.this.offsetWidth < this.scrollWidth当元素几乎保持其内容但仅缺少一个或两个宽度的像素时,仅仅比较" " 是不够的,特别是对于全角中文/日文/韩文字符的文本.

这是一个例子:http://jsfiddle.net/28r5D/5/

我找到了一种改进省略号检测的方法:

  1. 首先比较" this.offsetWidth < this.scrollWidth",如果失败则继续步骤#2.
  2. 暂时将css样式切换为{'溢出':'可见','白色空间':'正常','单词突破':'打破所有'}.
  3. 让浏览器做重新布局.如果发生自动换行,元素将扩展其高度,这也意味着需要省略号.
  4. 恢复css样式.

这是我的改进:http://jsfiddle.net/28r5D/6/


Ste*_*ven 10

我创建了一个jQuery插件,它使用Bootstrap的工具提示而不是浏览器的内置工具提示.请注意,尚未使用旧版浏览器进行测试.

JSFiddle:https://jsfiddle.net/0bhsoavy/4/

$.fn.tooltipOnOverflow = function(options) {
    $(this).on("mouseenter", function() {
    if (this.offsetWidth < this.scrollWidth) {
        options = options || { placement: "auto"}
        options.title = $(this).text();
      $(this).tooltip(options);
      $(this).tooltip("show");
    } else {
      if ($(this).data("bs.tooltip")) {
        $tooltip.tooltip("hide");
        $tooltip.removeData("bs.tooltip");
      }
    }
  });
};
Run Code Online (Sandbox Code Playgroud)


Han*_*nes 10

Here are two other pure CSS solutions:

  1. Show the truncated text in place:

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

.overflow:hover {
  overflow: visible;
}

.overflow:hover span {
  position: relative;
  background-color: white;

  box-shadow: 0 0 4px 0 black;
  border-radius: 1px;
}
Run Code Online (Sandbox Code Playgroud)
<div>
  <span class="overflow" style="float: left; width: 50px">
    <span>Long text that might overflow.</span>
  </span>
  Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad recusandae perspiciatis accusantium quas aut explicabo ab. Doloremque quam eos, alias dolore, iusto pariatur earum, ullam, quidem dolores deleniti perspiciatis omnis.
</div>
Run Code Online (Sandbox Code Playgroud)

  1. Show an arbitrary "tooltip":

.wrap {
  position: relative;
}

.overflow {
  white-space: nowrap; 
  overflow: hidden;
  text-overflow: ellipsis;
  
  pointer-events:none;
}

.overflow:after {
  content:"";
  display: block;
  position: absolute;
  top: 0;
  right: 0;
  width: 20px;
  height: 15px;
  z-index: 1;
  border: 1px solid red; /* for visualization only */
  pointer-events:initial;

}

.overflow:hover:after{
  cursor: pointer;
}

.tooltip {
  /* visibility: hidden; */
  display: none;
  position: absolute;
  top: 10;
  left: 0;
  background-color: #fff;
  padding: 10px;
  -webkit-box-shadow: 0 0 50px 0 rgba(0,0,0,0.3);
  opacity: 0;
  transition: opacity 0.5s ease;
}


.overflow:hover + .tooltip {
  /*visibility: visible; */
  display: initial;
  transition: opacity 0.5s ease;
  opacity: 1;
}
Run Code Online (Sandbox Code Playgroud)
<div>
  <span class="wrap">
    <span class="overflow" style="float: left; width: 50px">Long text that might overflow</span>
    <span class='tooltip'>Long text that might overflow.</span>
  </span>
  Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad recusandae perspiciatis accusantium quas aut explicabo ab. Doloremque quam eos, alias dolore, iusto pariatur earum, ullam, quidem dolores deleniti perspiciatis omnis.
</div>
Run Code Online (Sandbox Code Playgroud)

  • 即使文本没有被截断,该解决方案也会有工具提示,这不能满足原始问题 (5认同)

wua*_*min 5

这是一个香草 JavaScript 解决方案:

var cells = document.getElementsByClassName("cell");

for(const cell of cells) {
  cell.addEventListener('mouseenter', setTitleIfNecessary, false);
}

function setTitleIfNecessary() {
  if(this.offsetWidth < this.scrollWidth) {
    this.setAttribute('title', this.innerHTML);
  }
}
Run Code Online (Sandbox Code Playgroud)
.cell {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  border: 1px;
  border-style: solid;
  width: 120px; 
}
Run Code Online (Sandbox Code Playgroud)
<div class="cell">hello world!</div>
<div class="cell">hello mars! kind regards, world</div>
Run Code Online (Sandbox Code Playgroud)


Mar*_*llo 3

如果你想仅使用 javascript 来完成此操作,我会执行以下操作。为 span 指定一个 id 属性(以便可以轻松地从 DOM 中检索它)并将所有内容放入名为“content”的属性中:

<span id='myDataId' style='text-overflow: ellipsis; overflow : hidden;
 white-space: nowrap; width: 71;' content='{$myData}'>${myData}</span>
Run Code Online (Sandbox Code Playgroud)

然后,在您的 javascript 中,您可以在将元素插入 DOM 后执行以下操作。

var elemInnerText, elemContent;
elemInnerText = document.getElementById("myDataId").innerText;
elemContent = document.getElementById("myDataId").getAttribute('content')
if(elemInnerText.length <= elemContent.length)
{
   document.getElementById("myDataId").setAttribute('title', elemContent); 
}
Run Code Online (Sandbox Code Playgroud)

当然,如果您使用 javascript 将跨度插入到 DOM 中,则可以在插入之前将内容保留在变量中。这样,您就不需要跨度上的内容属性。

如果您想使用 jQuery,还有比这更优雅的解决方案。