我有一個動態數據在我的頁面,省略號風格的跨度。
.my-class
{
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
width: 71px;
}
<span id="myId" class="my-class"></span>
document.getElementById('myId').innerText = "...";
我想給這個元素添加相同內容的工具提示,但我希望它只在內容很長并且省略號出現在屏幕上時才出現。 有什么辦法嗎? 當省略號被激活時瀏覽器會拋出一個事件嗎?
*瀏覽器:Internet Explorer
下面是一種方法,它使用內置省略號設置,并根據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 {
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;
}
<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>
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());
});
這是我的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 & lt“this.scrollWidth”當元素幾乎包含其內容,但在寬度上只缺少一兩個像素時,尤其是對于全角中文/日文/韓文字符的文本。
這里有一個例子:http://jsfiddle.net/28r5D/5/
我發現了一種改進省略號檢測的方法:
比較“this.offsetWidth & lt首先,如果失敗,繼續步驟#2。 將css樣式暫時切換到{'overflow': 'visible ',' white-space': 'normal ',' word-break': 'break-all'} 讓瀏覽器重新布局。如果發生自動換行,元素將擴展其高度,這也意味著省略號是必需的。 恢復css樣式。 這是我的進步:http://jsfiddle.net/28r5D/6/
我創建了一個jQuery插件,它使用Bootstrap的工具提示,而不是瀏覽器的內置工具提示。請注意,這還沒有在舊瀏覽器上測試過。
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");
}
}
});
};
這里有一個普通的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 {
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>
這是我的解決方案,非常有效!
$(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,可以在插入之前將內容保存在變量中。這樣,span上就不需要內容屬性了。
如果您想使用jQuery,還有比這更好的解決方案。
這就是我最后在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 );
這就是我所做的。大多數工具提示腳本要求您執行一個存儲工具提示的函數。這是一個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());
});
我有CSS類,決定省略號放在哪里。在此基礎上,我做了以下工作(元素集可能不同,我編寫了這些,其中使用了省略號,當然它可能是一個單獨的類選擇器):
$(document).on('mouseover', 'input, td, th', function() {
if ($(this).css('text-overflow') && typeof $(this).attr('title') === 'undefined') {
$(this).attr('title', $(this).val());
}
});
為2022年添加簡單的一次性解決方案,屆時您不應使用jQuery,也不應試圖支持停產產品(如IE):
document.querySelectorAll('.overflow').forEach(span => {
if (span.scrollWidth > span.clientWidth) {
span.title = span.innerText
}
})
試試看:https://jsfiddle.net/metalim/cxw26smg/
上面的解決方案都不適合我,但是我想出了一個很棒的解決方案。人們犯的最大錯誤是在頁面加載時在元素上聲明所有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'
});
}
});
在我的例子中,我不僅使用了文本溢出:省略號;而且具有換行屬性,所以省略號只在第二行文本后應用。以下是我的div的風格:
.text {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
}
我在這里使用React,但是我認為這種方法也可以應用于普通的js。這是:
const MyComponent = ({text}: {text: string}) => {
const [titleActive, setTitleActive] = useState(false)
const ref = useCallback<(node: HTMLDivElement) => void>(
(node) => {
if (node) {
const blockWidth = node.offsetWidth
/* setting width to `max-content` makes div's width equal to text
rendered in one line */
node.style.width = 'max-content';
const textWidth = node.offsetWidth;
node.style.width = 'auto';
/* the multiplier of `blockWidth` is the number of lines shown
before ellipsis applied. In my case this is 2 (same
as in `-webkit-line-clamp` css property).
For one condition will be just `(textWidth > blockWidth)`
*/
if (textWidth > blockWidth * 2) {
setTitleActive(true)
}
}
},
[]
);
return (
<div
className="text"
title={titleActive ? text : undefined}
ref={ref}
>
{text}
</div>
)
}
您可以用另一個跨度來包圍該跨度,然后簡單地測試原始/內部跨度的寬度是否大于新/外部跨度的寬度。請注意,我說的可能,大致是基于我的情況,我有一個td內的跨度,所以我實際上不知道它是否適用于跨度內的跨度。
不過,這是我給那些可能發現自己處于與我相似處境的人的代碼;我不加修改地復制/粘貼它,即使它是在一個有角度的上下文中,我不認為這有損于可讀性和基本概念。我將它編碼為服務方法,因為我需要在多個地方應用它。我傳入的選擇器是一個匹配多個實例的類選擇器。
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());
}
}
});
}