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

时间:2011-03-29 15:19:00

标签: javascript html css tooltip ellipsis

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

<span style='text-overflow: ellipsis; overflow : hidden; white-space: nowrap;  
 width: 71;'>${myData}</span>

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

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

15 个答案:

答案 0 :(得分:155)

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

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

    if(this.offsetWidth < this.scrollWidth && !$this.attr('title')){
        $this.attr('title', $this.text());
    }
});

答案 1 :(得分:44)

这是一个纯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;
}

答案 2 :(得分:32)

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

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

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

或者,如果你不知道它的确切添加时间,那么在页面加载完成后调用该代码。

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

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

答案 3 :(得分:16)

这是我的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);

用法:

$("td, th").tooltipOnOverflow();

编辑:

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

答案 4 :(得分:11)

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

以下是一个示例:http://jsfiddle.net/28r5D/5/

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

  1. 首先比较“this.offsetWidth < this.scrollWidth”,如果失败则继续步骤#2。
  2. 暂时将css样式切换为{'溢出':'可见','空白':'正常','分词':'打破所有'}。
  3. 让浏览器做重新布局。如果发生自动换行,元素将扩展其高度,这也意味着需要省略号。
  4. 恢复css样式。
  5. 以下是我的改进:http://jsfiddle.net/28r5D/6/

答案 5 :(得分:10)

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

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

var bp=viz.bP()
            .data(data)
            .min(12)
            .pad(1)
            .height(h)
            .width(w)
            .barSize(35)
            .fill(function(d){
                return color[d.primary]
            });

答案 6 :(得分:4)

这是另外两个纯CSS解决方案:

  1. 将截断的文本显示在适当的位置:

import os
import csv

def Emailer(message, subject, recipient, anrede, name):
    import win32com.client as win32   

    outlook = win32.Dispatch('outlook.application')
    mail = outlook.CreateItem(0)
    mail.To = recipient
    mail.Subject = subject
    mail.GetInspector 

    header = 'MyHeader'
    message = 'MyHTMLMessage'

    index = mail.HTMLbody.find('>', mail.HTMLbody.find('<body')) 
    mail.HTMLbody = "<font size=-1 face='Arial'>" + mail.HTMLbody[:index + 1] + header + message + mail.HTMLbody[index + 1:] 

    mail.send


with open('Komplette Liste.csv', 'rb') as csvfile:
reader = csv.reader(csvfile, delimiter=';')
csv_list = list(reader)

row_count = sum(1 for row in csv_list)

for i in range(1,row_count):    
            unternehmen = str(csv_list[i][0])
            mail_address = str(csv_list[i][7])
            name = str(csv_list[i][8])

            infomail_count = infomail_count + 1 
            print(mail_address)

            Emailer("", "My Subject", "MailTo")
.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;
}

  1. Show an arbitrary "tooltip"

<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>
.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;
}

答案 7 :(得分:3)

这就是我所做的。大多数工具提示脚本都要求您执行存储工具提示的函数。这是一个jQuery示例:

$.when($('*').filter(function() {
   return $(this).css('text-overflow') == 'ellipsis';
}).each(function() {
   if (this.offsetWidth < this.scrollWidth && !$(this).attr('title')) {
      $(this).attr('title', $(this).text());
   }
})).done(function(){ 
   setupTooltip();
});

如果您不想检查省略号css,可以简化如下:

$.when($('*').filter(function() {
   return (this.offsetWidth < this.scrollWidth && !$(this).attr('title'));
}).each(function() {
   $(this).attr('title', $(this).text());
})).done(function(){ 
   setupTooltip();
});

我周围有“when”,因此在更新所有标题之前,“setupTooltip”功能不会执行。将“setupTooltip”替换为工具提示功能,将*替换为要检查的元素。 *如果你离开,将会全部通过。

如果您只想使用浏览器工具提示更新标题属性,则可以简化为:

$('*').filter(function() {
   return $(this).css('text-overflow') == 'ellipsis';
}).each(function() {
   if (this.offsetWidth < this.scrollWidth && !$(this).attr('title')) {
      $(this).attr('title', $(this).text());
   }
});

或者不检查省略号:

$.when($('*').filter(function() {
   return (this.offsetWidth < this.scrollWidth && !$(this).attr('title'));
}).each(function() {
   $(this).attr('title', $(this).text());
});

答案 8 :(得分:2)

如果您只想使用javascript执行此操作,我会执行以下操作。为span提供id属性(以便可以从DOM中轻松检索)并将所有内容放在名为“content”的属性中:

<span id='myDataId' style='text-overflow: ellipsis; overflow : hidden;
 white-space: nowrap; width: 71;' content='{$myData}'>${myData}</span>

然后,在您的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); 
}

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

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

答案 9 :(得分:1)

我有CSS类,它决定了省略号的放置位置。基于此,我做了以下(元素集可能不同,我写的那些,使用省略号,当然它可以是一个单独的类选择器):

$(document).on('mouseover', 'input, td, th', function() {
    if ($(this).css('text-overflow') && typeof $(this).attr('title') === 'undefined') {
        $(this).attr('title', $(this).val());
    }
});

答案 10 :(得分:0)

上述解决方案都不适合我,但我找到了一个很好的解决方案。人们犯的最大错误是在页面加载时在元素上声明了所有3个CSS属性。您必须动态添加这些样式+工具提示IF,并且只有在您想要省略号的范围比其父级更宽时才会添加。

    $('table').each(function(){
        var content = $(this).find('span').text();
        var span = $(this).find('span');
        var td = $(this).find('td');
        var styles = {
            'text-overflow':'ellipsis',
            'white-space':'nowrap',
            'overflow':'hidden',
            'display':'block',
            'width': 'auto'
        };
        if (span.width() > td.width()){
            span.css(styles)
                .tooltip({
                trigger: 'hover',
                html: true,
                title: content,
                placement: 'bottom'
            });
        }
    });

答案 11 :(得分:0)

您可以用另一个跨度围绕跨度,然后只测试原始/内跨的宽度是否大于新/外跨度的宽度。请注意,我可能会说 - 这大致取决于我在span内部td的情况,所以我实际上并不知道它是否适用于spanspan内。

这里虽然是我的代码,但其他人可能会发现自己处于类似于我的位置;我正在复制/粘贴它而不进行修改,即使它处于Angular环境中,我认为这不会损害可读性和基本概念。我将其编码为服务方法,因为我需要在多个地方应用它。我传入的选择器是一个匹配多个实例的类选择器。

CaseService.applyTooltip = function(selector) {
    angular.element(selector).on('mouseenter', function(){
        var td = $(this)
        var span = td.find('span');

        if (!span.attr('tooltip-computed')) {
            //compute just once
            span.attr('tooltip-computed','1');

            if (span.width() > td.width()){
                span.attr('data-toggle','tooltip');
                span.attr('data-placement','right');
                span.attr('title', span.html());
            }
        }
    });
}

答案 12 :(得分:0)

这是Vanilla JavaScript解决方案:

(function init() {

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

  for(let index = 0; index < cells.length; ++index) {
    let cell = cells.item(index);
    cell.addEventListener('mouseenter', setTitleIfNecessary, false);
  }

  function setTitleIfNecessary() {
    if(this.offsetWidth < this.scrollWidth) {
      this.setAttribute('title', this.innerHTML);
    }
  }

})();
.cell {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  border: 1px;
  border-style: solid;
  width: 120px; 
}
<div class="cell">hello world!</div>
<div class="cell">hello mars! kind regards, world</div>

答案 13 :(得分:0)

这是我的解决方案,很吸引人!

    $(document).on('mouseover', 'input, span', function() {
      var needEllipsis = $(this).css('text-overflow') && (this.offsetWidth < this.scrollWidth);
      var hasNotTitleAttr = typeof $(this).attr('title') === 'undefined';
      if (needEllipsis === true) {
          if(hasNotTitleAttr === true){
            $(this).attr('title', $(this).val());
          }
      }
      if(needEllipsis === false && hasNotTitleAttr == false){
        $(this).removeAttr('title');
      }
  });

答案 14 :(得分:0)

这就是我最终基于 profiling 所做的,并在元素不再溢出时添加移除 title 属性。这是纯 JS (ES6),使用事件委托来提高性能(当使用具有相同类的多个元素时)并使用保护子句来提高可读性:

// You may want to change document by an element closer to your target
// so that the handler is not executed as much
document.addEventListener( 'mouseenter', event => {
    let eventTarget = event.target;
    // This could be easily applied to text-truncate instead of my-class if you use bootstrap
    if ( !eventTarget.classList?.contains( 'my-class' ) ) {
        return;
    }
    if ( eventTarget.offsetWidth < eventTarget.scrollWidth ) {
        eventTarget.setAttribute( 'title', eventTarget.innerText );
        return;
    }
    eventTarget.removeAttribute( 'title' );
}, true );