HTML - как я могу показать всплывающую подсказку ТОЛЬКО при активации многоточия - PullRequest
173 голосов
/ 29 марта 2011

На моей странице есть диапазон с динамическими данными, которые содержат многоточие. Значение:

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

и я хотел бы добавить к этому элементу всплывающую подсказку с тем же содержимым (title = '$ {myData}'), но я хочу, чтобы она отображалась только тогда, когда содержимое длинное и многоточие отображается на экране.
Есть ли способ сделать это?

в одном направлении - когда браузер (в моем случае IE) рисует многоточие - вызывает ли это событие?

Ответы [ 14 ]

156 голосов
/ 07 ноября 2012

Вот способ, который делает это, используя встроенный параметр многоточия, и добавляет атрибут title по требованию (с jQuery), основываясь на комментарии Мартина Смита:

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

    if(this.offsetWidth < this.scrollWidth && !$this.attr('title')){
        $this.attr('title', $this.text());
    }
});
44 голосов
/ 29 октября 2015

Вот чистое решение 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;
}
32 голосов
/ 11 декабря 2012

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());
});
16 голосов
/ 14 июля 2014

Вот мой плагин 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

12 голосов
/ 27 мая 2014

Нам нужно определить, действительно ли применен многоточие, а затем показать всплывающую подсказку для раскрытия полного текста.Недостаточно только сравнивать «this.offsetWidth < this.scrollWidth», когда элемент почти удерживает свое содержимое, но не хватает только одного или двух пикселей в ширину, особенно для текста полноразмерных китайских / японских / корейских символов.

Вот пример: http://jsfiddle.net/28r5D/5/

Я нашел способ улучшить обнаружение эллипса:

  1. Сначала сравните «this.offsetWidth < this.scrollWidth», продолжите шаг # 2, если не удалось.
  2. Временное переключение стиля css на {'overflow': 'visible', 'white-space': 'normal', 'word-break': 'break-all'}.
  3. Разрешить браузеруrelayout.Если происходит перенос слов, высота элемента увеличивается, что также означает необходимость многоточия.
  4. Восстановление стиля CSS.

Вот мое улучшение: http://jsfiddle.net/28r5D/6/

10 голосов
/ 13 июля 2017

Я создал плагин 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");
      }
    }
  });
};
5 голосов
/ 22 октября 2018

Вот два других чистых решения CSS:

  1. Показать усеченный текст на месте:

.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>
Показать произвольную «подсказку» :

.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;
}
<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>
3 голосов
/ 30 мая 2013

Это то, что я сделал. Большинство сценариев подсказок требуют от вас выполнения функции, которая хранит подсказки. Это пример 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());
});
2 голосов
/ 29 марта 2011

Если вы хотите сделать это исключительно с использованием JavaScript, я бы сделал следующее. Присвойте span идентификатор атрибута (чтобы его можно было легко извлечь из 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 для вставки диапазона в DOM, вы можете просто сохранить содержимое в переменной, прежде чем вставлять его. Таким образом, вам не нужен атрибут содержимого в промежутке.

Есть более элегантные решения, чем это, если вы хотите использовать jQuery.

1 голос
/ 20 ноября 2015

У меня есть класс CSS, который определяет, куда поместить многоточие.Исходя из этого, я делаю следующее (набор элементов может быть другим, я пишу те, где используется многоточие, конечно, это может быть отдельный селектор классов):

$(document).on('mouseover', 'input, td, th', function() {
    if ($(this).css('text-overflow') && typeof $(this).attr('title') === 'undefined') {
        $(this).attr('title', $(this).val());
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...