HTML-줄임표가 활성화 된 경우에만 툴팁을 표시하는 방법


205

내 페이지에 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


1
text-overflow:ellipsis;Firefox에서는 전혀 작동하지 않는다는 점을 명심 하십시오. 자세한 내용은이 질문을 참조하십시오. stackoverflow.com/questions/4927257/…
Spudley

2
방금 비슷한 일을해야했습니다. 여부 확인 element.offsetWidth < element.scrollWidth에 따라 이 대답 지금까지 작동하는 것 같다.
Martin Smith


7
후손에 대한 참고 사항 : text-overflow:ellipsis;이제 Firefox에서 작동합니다. Firefox 7 (2011 년 9 월 릴리스)에 추가되었습니다.
sleske

답변:


161

내장 생략 부호 설정을 사용하고 titleMartin Smith의 주석에 온 디맨드 속성 (jQuery 포함)을 추가하는 방법은 다음과 같습니다 .

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

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

4
고마워, 매력처럼 작동합니다! 그러나보다 효율적으로 만들고 싶다면 bind ()를 on ()으로 바꾸는 것을 고려할 수 있습니다. $ (document) .on ( 'mouseenter', '.mightOverflow', function () {...});
Ziad

17
텍스트가 더 이상 오버플로되지 않는 경우 툴팁이 자동으로 제거되도록하려면 $ (document) .on ( 'mouseenter', '.mightOverflow', 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')}});
Chris Janssen 2013

1
mouseenter는 우리가 묶거나 듣는 이벤트입니다. 실제로 누군가가 해당 요소 위로 마우스를 가져갈 때까지 요소에 툴팁을 추가 할 필요는 없습니다. 따라서 우리는 클래스가 "mightoverflow"인 DOM 요소 중 하나에서 mouseenter 지점까지 추가를 연기합니다. JIT (Just-In-Time) 툴팁
Jason Kleban

2
"As of jQuery 1.7, the .on() method is the preferred method for attaching event handlers to a document"자세한 내용은 api.jquery.com/bindapi.jquery.com/on을
Adrien Be

2
IE10에서는 작동하지 않습니다. offsetWidth는 scrollWidth와 동일하므로 둘 다 잘린 너비를 제공합니다.
SsjCosty

59

다음은 순수한 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;
}

18
레이아웃이 깨질 수 있기 때문에 툴팁만큼 좋지 않습니다.
Alexander

2
툴팁의 문제점은 적어도 현재로서는 모바일에서 작동하지 않는다는 것입니다. 이 답변은 (읽을 수있을 것입니다) 레이아웃을 깨뜨릴 수 있지만 예를 들어 호버링 된 요소의 배경색이 달라 지도록 조정할 수 있습니다. 이것은 여전히 ​​모바일에서는 작동하지 않지만 데스크탑의 또 다른 옵션입니다.
trysis

1
내 요구를 완벽하게 충족시키는 훌륭한 답변에 감사드립니다. 일부 JavaScript를 사용하면 레이아웃을 손상시키지 않도록 블록을 절대 위치로 만드는 것을 상상할 수 있습니다.
Niavlys

2
CSS 문제에서 자바 스크립트를 부 풀리는 것보다 좋은 대답입니다. 분명히 줄임표는 자동 제목 옵션을 가져야하며, 현재 구현 방식이 의미가 없습니다. 너무 나쁜 CSS는 마지막 문자가 '...'인 경우 호버링 만 허용하지 않습니다.
John

32

uosɐſ의 답변은 근본적으로 정확하지만 마우스 입력 이벤트에서는 원하지 않을 것입니다. 그러면 요소 위로 마우스를 올릴 때마다 필요한지를 결정하기 위해 계산을 수행하게됩니다. 요소의 크기가 변하지 않는 한 그렇게 할 이유가 없습니다.

요소가 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());
});

+1, 페이지로드시이를 수행하는 것이 더 단순 해 보이지만 더 많은 가능성을 제공합니다. 즉. 툴팁을 "신호"하기 위해 밑줄이 점선 인 툴팁이있는이 요소의 스타일을 지정할 수 있습니다. 같은$(".mightOverflow").each(function() { if( $(this).offsetWidth < $(this).scrollWidth && !$(this).attr('title')){ $(this).attr('title', $(this).text()); $(this).css('border-bottom', '1px dotted #A8A8A8'); } });
아드 리앙은 수

잘못 '마우스가 이상 할 때마다 당신에게'- 그것은 이전에 계산 된 경우 검사를 수행합니다 (지금은 적어도 답이 업데이트 된 경우 나도 몰라) '&& $ this.attr! ('제목 ')'
룬 Jeppesen이

아니요, 제목 속성을 다시 추가하지 않아도됩니다. 필요한지 판단 하는 계산 은 여전히 ​​수행됩니다. 요소를 마우스로 가리킬 때마다 this.offsetWidth < this.scrollWidth확인조차 가능 !$this.attr('title')합니다.
Elezar

9
이 방법의 문제점은 모든 요소가 한 번에 확인되고 (잠재적 성능 영향) 한 번만 계산되므로 사용자가 브라우저를 축소하면 항목이 잘 리거나 확장되어 더 이상 잘리지 않게됩니다. 툴팁의 존재를 업데이트합니다. 코드를 창 크기 조정에 다시 연결하면 모든 항목의 크기를 확인할 때 성능 문제가 발생합니다. "$ (문서) CSTE 연구진 ( 'mouseenter를', '.mightOverflow'..."이벤트 위임을 사용하고 요소 마우스를 움직일 때까지 검사를 지연하면 실시간으로 업데이트 할 수 있으며, 한 번 @ 한 요소를 확인
Chris Janssen

IE10에서는 작동하지 않습니다. offsetWidth는 scrollWidth와 동일하므로 둘 다 잘린 너비를 제공합니다.
SsjCosty

18

다른 두 가지 순수한 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>

  1. 임의의 "툴팁"을 표시하십시오 .

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


이것이 바로 내가 찾던 것입니다!
Praneet Nadkar

훌륭한 솔루션, 정확히 내가 필요한 것. 감사합니다 !
Agu V

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);

용법:

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

편집하다:

이 플러그인에 대한 요점을 만들었습니다. https://gist.github.com/UziTech/d45102cdffb1039d4415


1
IE10에서는 작동하지 않습니다. offsetWidth는 scrollWidth와 동일하므로 둘 다 잘린 너비를 제공합니다.
SsjCosty

@SsjCosty 왜 IE 10에서 테스트하고 있습니까? IE 10을 설치할 수있는 사람이라면 누구나 IE 11을 설치할 수 있기 때문에 IE 10을 사용하는 사람은 없어야합니다.
Tony Brix

아, 우리는 지원되는 최소 IE 버전이 10이라는 회사 정책을 가지고 있습니다. 또한 많은 고객 (일부 은행 및 여러 기관)이 여전히 IE10을 사용하기 때문입니다. 오 잘
SsjCosty

12

줄임표가 실제로 적용되는지 여부를 감지 한 다음 전체 텍스트를 표시하는 툴팁을 표시해야합니다. 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. 브라우저가 릴레이 아웃하도록하십시오. 줄 바꿈이 발생하면 요소의 높이가 확장되어 줄임표가 필요합니다.
  4. CSS 스타일을 복원하십시오.

내 개선 사항은 다음과 같습니다. http://jsfiddle.net/28r5D/6/


10

브라우저의 내장 툴팁 대신 Bootstrap의 툴팁을 사용하는 jQuery 플러그인을 만들었습니다. 이전 브라우저에서는 테스트되지 않았습니다.

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");
      }
    }
  });
};

간단하고 훌륭합니다. 감사합니다!
GumZ

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();
});

나는 "때"를 가지고 있기 때문에 모든 타이틀이 업데이트 될 때까지 "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());
});

왜 공감해야합니까? 사람들이 문제가 무엇인지 알 수 있도록 의견을 말하십시오. 감사.
fanfavorite

2

자바 스크립트 만 사용 하여이 작업을 수행하려면 다음을 수행하십시오. span에 id 속성을 제공하고 (DOM에서 쉽게 검색 할 수 있도록) 모든 컨텐츠를 'content'라는 속성에 배치하십시오.

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

그런 다음 자바 스크립트에서 요소가 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); 
}

물론 자바 스크립트를 사용하여 스팬을 DOM에 삽입하는 경우 내용을 삽입하기 전에 변수에 유지할 수 있습니다. 이 방법으로 범위에 컨텐츠 속성이 필요하지 않습니다.

jQuery를 사용하려는 경우 이것보다 더 우아한 솔루션이 있습니다.


좋은. 이 페이지의 다른 부분에서 JQuery를 사용하고 있기 때문에 JQuery의 우아한 솔루션은 무엇입니까?
스파이더 맨

$("#myDataId").attr("title", function() { var innerText = $(this).text(); var content = $(this).attr("content"); if (innerText.length <= content.length) { return content; } return null; });
Mark Costello

1
순수한 자바 스크립트로 첫 번째 제안을 시도했지만 작동하지 않습니다. 'innerText'속성은 텍스트가 화면에 완전히 표시되지 않더라도 항상 텍스트의 전체 길이를 저장합니다. elemInnerText.length == elemContent.length !!
스파이더 맨

스팬의 스타일은 너비가 71입니다. 문자열의 너비가 그보다 길지 않은 이유는 무엇입니까? 정말 펑키 한 것을 원한다면 text-overflow : ellipsis를 설정하지 않고 숨겨진 요소를 추가하고 두 너비를 비교할 수 있습니다. 숨겨진 것이 숨겨지지 않은 것보다 넓은 경우 제목 속성을 보이는 것에 추가하십시오.
Mark Costello

2

줄임표를 넣을 위치를 결정하는 CSS 클래스가 있습니다. 이를 기반으로 다음을 수행합니다 (요소 집합이 다를 수 있음, 줄임표가 사용되는 곳은 물론 별도의 클래스 선택기가 될 수 있음).

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

1
나는 내 경우는 this이었다 anchor그래서 내가 사용하는 this.text()대신val()
바시르 AL-MOMANI

2

다음은 바닐라 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>


1

이것은 내 해결책 이었으므로 매력으로 작동합니다!

    $(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');
      }
  });

안녕하세요 @ FarukT 귀하의 솔루션이 저에게 잘 작동하고 있습니다. 감사합니다. 입력 및 범위를 가정하는 두 개의 html 태그가 있는지 묻고 싶습니다 .offsetWidth를 사용하여 산술 계산을 수행하기 위해 두 태그의 offsetWidth를 동일하게 계산하고 싶습니다. 어떻게해야합니까?
Kunal Tyagi

안녕하세요 @ KunalTyagi, 당신은 2 개의 분리 된 기능으로 그것을 할 수 있습니다. 입력과 스팬으로 하나만 작성되었지만이 기능을 2 번 복제 할 수 있습니다 (예 : 입력 만 사용하고 첫 번째 기능 만 사용). 다음과 같이 : $ (document) .on ( 'mouseover', 'input', function () {...}); 그리고 두번째 하나 $ (document) .on ( 'mouseover', 'span', function () {...});
FarukT

0

위의 해결책 중 어느 것도 나를 위해 효과가 없었지만 훌륭한 해결책을 찾았습니다. 사람들이 가장 큰 실수는 페이지로드시 요소에 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'
            });
        }
    });

0

스팬을 다른 스팬으로 둘러 쌀 수 있으며 원래 / 내부 스팬의 너비가 새 / 외부 스팬의 너비보다 큰지 테스트하면됩니다. 내가 말할 수 있음에 유의하십시오-대략 span내부에있는 상황 에 따라 td다르므로 실제로 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());
            }
        }
    });
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.