IT

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

lottoking 2020. 5. 20. 08:04
반응형

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


줄임표가 포함 된 페이지에 동적 데이터가 포함되어 있습니다. 의미:

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

동일한 내용 (title = '$ {myData}')으로이 요소 툴팁에 추가하고 싶지만 내용이 길고 줄임표가 화면에 나타날 때만 표시되기를 원합니다.
그것을 할 방법이 있습니까?

한 방향-브라우저 (내 경우에는 IE)가 줄임표를 그릴 때 이벤트가 발생합니까?


내장 생략 부호 설정을 사용하고 titleMartin Smith의 주석에 온 디맨드 속성 (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;
}

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

내 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/

줄임표 감지 기능을 향상시키는 방법을 찾았습니다.

  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/


브라우저의 내장 툴팁 대신 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");
      }
    }
  });
};

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


이것이 내가 한 일입니다. 대부분의 툴팁 스크립트에서는 툴팁을 저장하는 기능을 실행해야합니다. 이것은 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();
});

I have the "when" around it, so that the "setupTooltip" function doesn't execute until all titles have been updated. Replace the "setupTooltip", with your tooltip function and the * with the elements you want to check. * will go through them all if you leave it.

If you simply want to just update the title attributes with the browsers tooltip, you can simplify like:

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

Or without check for ellipsis:

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

If you want to do this solely using javascript, I would do the following. Give the span an id attribute (so that it can easily be retrieved from the DOM) and place all the content in an attribute named 'content':

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

Then, in your javascript, you can do the following after the element has been inserted into the 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); 
}

Of course, if you're using javascript to insert the span into the DOM, you could just keep the content in a variable before inserting it. This way you don't need a content attribute on the span.

There are more elegant solutions than this if you want to use jQuery.


I have CSS class, which determines where to put ellipsis. Based on that, I do the following (element set could be different, i write those, where ellipsis is used, of course it could be a separate class selector):

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

Here's a Vanilla JavaScript solution:

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


None of the solutions above worked for me, but I figured out a great solution. The biggest mistake people are making is having all the 3 CSS properties declared on the element upon pageload. You have to add those styles+tooltip dynamically IF and ONLY IF the span you want an ellipses on is wider than its parent.

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

You could possibly surround the span with another span, then simply test if the width of the original/inner span is greater than that of the new/outer span. Note that I say possibly -- it is roughly based on my situation where I had a span inside of a td so I don't actually know that if it will work with a span inside of a span.

Here though is my code for others who may find themselves in a position similar to mine; I'm copying/pasting it without modification even though it is in an Angular context, I don't think that detracts from the readability and the essential concept. I coded it as a service method because I needed to apply it in more than one place. The selector I've been passing in has been a class selector that will match multiple instances.

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

This was my solution, works as a charm!

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

참고URL : https://stackoverflow.com/questions/5474871/html-how-can-i-show-tooltip-only-when-ellipsis-is-activated

반응형