我的页面中有一个包含动态数据的跨度,具有 ellipsis
样式。
.my-class
{
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
width: 71px;
}
<span id="myId" class="my-class"></span>
document.getElementById('myId').innerText = "...";
我想在此元素工具提示中添加相同的内容,但我希望它仅在内容较长且省略号出现在屏幕上时出现。
有什么办法吗?
浏览器会在 ellipsis
被激活时抛出一个事件吗?
*浏览器:Internet Explorer
text-overflow:ellipsis;
在 Firefox 中根本不起作用 - 请参阅此问题了解更多信息:stackoverflow.com/questions/4927257/…
element.offsetWidth < element.scrollWidth
是否有效。
text-overflow:ellipsis;
现在可以在 Firefox 中使用;它是在 Firefox 7(2011 年 9 月发布)中添加的。
这是一种使用内置省略号设置的方法,并根据 Martin Smith 的评论按需添加 title
属性(使用 jQuery):
$('.mightOverflow').bind('mouseenter', function(){
var $this = $(this);
if(this.offsetWidth < this.scrollWidth && !$this.attr('title')){
$this.attr('title', $this.text());
}
});
这是一个纯 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;
}
以下是另外两个纯 CSS 解决方案:
在适当位置显示截断的文本:
.overflow { 溢出:隐藏; -ms - 文本 - 溢出:省略号;文本溢出:省略号;空白:nowwrap; } .overflow:hover { 溢出:可见; } .overflow:悬停跨度 { 位置:相对;背景颜色:白色;盒子阴影:0 0 4px 0 黑色;边框-半径:1px; }
显示任意“工具提示”:
.wrap { 位置:相对; } . 溢出 { 空白 : nowwrap ;溢出:隐藏;文本溢出:省略号;指针事件:无; } .overflow:after { 内容:"";显示:块;位置:绝对;顶部:0;对:0;宽度:20px;高度:15px; z-index:1;边框:1px 纯红色; /* 仅用于可视化 */ pointer-events:initial; } .overflow:hover:after{ 光标:指针; } .tooltip { /* 可见性:隐藏; */显示:无;位置:绝对;前10名;左:0;背景-颜色:#fff;填充:10px; -webkit-box-shadow: 0 0 50px 0 rgba(0,0,0,0.3);不透明度:0;过渡:不透明度 0.5s 缓动; } .overflow:head + .tooltip { /*可见性:可见; */ 显示:初始;过渡:不透明度 0.5s 缓动;不透明度:1; }
uosɐſ 的回答基本上是正确的,但您可能不想在 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());
});
$(".mightOverflow").each(function() { if( $(this).offsetWidth < $(this).scrollWidth && !$(this).attr('title')){ $(this).attr('title', $(this).text()); $(this).css('border-bottom', '1px dotted #A8A8A8'); } });
this.offsetWidth < this.scrollWidth
甚至可能会在您每次将鼠标悬停在元素上时执行对 !$this.attr('title')
的检查。
这是我的 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
我们需要检测是否真的应用了省略号,然后显示一个工具提示来显示全文。当元素几乎保持其内容但仅缺少一两个像素的宽度时,仅比较“this.offsetWidth < this.scrollWidth
”是不够的,特别是对于全角中日韩字符的文本。
这是一个示例:http://jsfiddle.net/28r5D/5/
我找到了一种改进省略号检测的方法:
首先比较“this.offsetWidth < this.scrollWidth”,如果失败则继续步骤#2。暂时将 css 样式切换为 {'overflow': 'visible', 'white-space': 'normal', 'word-break': 'break-all'}。让浏览器重新布局。如果发生自动换行,元素将扩展其高度,这也意味着需要省略号。恢复 CSS 样式。
这是我的改进:http://jsfiddle.net/28r5D/6/
我创建了一个 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");
}
}
});
};
这是一个 Vanilla 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); } } .cell { 空白:nowrap;溢出:隐藏;文本溢出:省略号;边框:1px;边框样式:实心;宽度:120px; }
这是我的解决方案,很有魅力!
$(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');
}
});
如果您只想使用 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,还有比这更优雅的解决方案。
$("#myDataId").attr("title", function() { var innerText = $(this).text(); var content = $(this).attr("content"); if (innerText.length <= content.length) { return content; } return null; });
这就是我所做的。大多数工具提示脚本要求您执行存储工具提示的函数。这是一个 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();
});
我在它周围有“何时”,因此“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());
});
这就是我最终基于 https://stackoverflow.com/a/13259660/1714951 所做的,并在元素不再溢出时添加了 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 );
我有 CSS 类,它决定在哪里放置省略号。基于此,我执行以下操作(元素集可能不同,我写了那些,其中使用了省略号,当然它可以是一个单独的类选择器):
$(document).on('mouseover', 'input, td, th', function() {
if ($(this).css('text-overflow') && typeof $(this).attr('title') === 'undefined') {
$(this).attr('title', $(this).val());
}
});
this
是 anchor
,所以我使用 this.text()
而不是 val()
上面的解决方案都不适合我,但我想出了一个很好的解决方案。人们犯的最大错误是在页面加载时在元素上声明了所有 3 个 CSS 属性。您必须动态添加这些样式+工具提示,并且仅当您想要椭圆的跨度大于其父级时。
$('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'
});
}
});
您可以用另一个跨度包围跨度,然后简单地测试原始/内部跨度的宽度是否大于新/外部跨度的宽度。请注意,我说可能 - 它大致基于我在 td
内有 span
的情况,所以我实际上不知道它是否适用于 span
内的 span
.
这是我的代码,供其他可能发现自己处于与我相似的位置的人使用;即使它在 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());
}
}
});
}
"As of jQuery 1.7, the .on() method is the preferred method for attaching event handlers to a document"
有关详细信息,请参阅 api.jquery.com/bind 和 api.jquery.com/on