仅在角度UI引导指令中截断文本时显示工具提示

时间:2022-11-04 17:37:07

I want to show angular UI bootsrap tooltip only when the text is truncated. I tried the below code with custom directive

我想只在文本被截断时显示角度UI bootsrap工具提示。我用自定义指令尝试了下面的代码

<div tooltip="{{value}}" tooltip-append-to-body="true" enable-truncate-tooltip>{{value}}</div>

.directive("enableTruncateTooltip", function () {
  return {
    restrict: 'A',
    link: function (scope, elem, attr) {
      elem.bind('mouseenter', function () {
        var $this = angular.element(this);

        if (this.offsetWidth >= this.scrollWidth) {
          angular.element('.tooltip').attr('hide-tooltip', true);
        }
      });
    }
  }
})

It works fine in angular-ui-bootstrap version 0.12.1. But later versions are not supporting this.

它在angular-ui-bootstrap版本0.12.1中工作正常。但是后来的版本不支持这个。

How can i achieve this same functionality in latest version of angular-ui-bootstrap?

如何在最新版本的angular-ui-bootstrap中实现相同的功能?

Thanks in advance for your help.

在此先感谢您的帮助。

2 个解决方案

#1


7  

TL;DR: Plunker Demo (using $watch) Old demo (using $timeout)

TL; DR:Plunker演示(使用$ watch)旧演示(使用$ timeout)

(The answer was updated to reflect a suggestion to use $watch instead of $timeout, thanks for the comment Michael Mish Kisilenko!)

(答案已更新,以反映使用$ watch而不是$ timeout的建议,感谢评论Michael Mish Kisilenko!)

First of all, change your angular-ui directives to the updated ones (prefix with 'uib-'):

首先,将angular-ui指令更改为更新的指令(前缀为'uib-'):

<div uib-tooltip="{{value}}" show-tooltip-on-text-over-flow tooltip-enable="false">{{value}}</div>

And then use the following directive, which dynamically changes the angular-ui provided feature tooltip-enable (note that you should initialize the element with directive tooltip-enable="false" so the tooltip will be disabled if the text is not truncated:

然后使用以下指令,该指令动态更改angular-ui提供的功能tooltip-enable(请注意,您应该使用指令tooltip-enable =“false”初始化元素,以便在文本未截断时禁用工具提示:

myApp.directive("showTooltipOnTextOverflow", ["$timeout", function($timeout) {
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
      var el = element[0];
      scope.$watch(function(){
        return el.scrollWidth;
      }, function() {
        var el = element[0];
        if (el.offsetWidth < el.scrollWidth) {
          //console.log('ellipsis is active for element', element);
          attrs.tooltipEnable = "true";
        } else {
          //console.log('ellipsis is NOT active for element', element);
        }
      });
      /*$timeout(function() {
        var el = element[0];
        if (el.offsetWidth < el.scrollWidth) {
          //console.log('ellipsis is active for element', element);
          attrs.tooltipEnable = "true";
        } else {
          //console.log('ellipsis is NOT active for element', element);
        }
      });*/
    }
  };
}]);

To truncate the text i'll use plain CSS:

截断文本我将使用纯CSS:

span.truncated {
    width: 400px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

#2


0  

Using watch as mentioned in answer posted by Lulu will bring performance down. It will add so many watchers as many cells grid has and these get evaluated in each digest cycle.

使用Lulu发布的回答中提到的手表将降低性能。它将添加许多单元网格所具有的观察者,并在每个摘要周期中对其进行评估。

I modified his code to use mouseover approach - so the need of tooltip is evaluated in mouseover event only on particular cell:

我修改了他的代码以使用鼠标悬停方法 - 因此只在特定单元格的鼠标悬停事件中评估工具提示的需要:

myApp.directive("showTooltipOnTextOverflow", ["$timeout", function($timeout) {
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
      var el = element[0];

      if (angular.isObject(el)) {
        var evaluateTooltip = (event: JQueryEventObject, isOurEvent: boolean) => {
        // evaluate whether to enable tooltip
        attrs.tooltipEnable = el.offsetWidth < el.scrollWidth ? "true" : "false";

        if (isOurEvent !== true && attrs.tooltipEnable === "true") {
          // tooltip should be enabled, trigger mouseover again to trigger tooltip (current mouseover is already handled by tooltip with false value)
          // and mark it as our event to avoid its handling here
          element.trigger("mouseover", [true]);

          // revert tooltip enabling back to false to cover case when mouseover happens and tooltip should not be enabled
          scope.$applyAsync(() => {
          attrs.tooltipEnable = "false";
        });
      }
    };

    element.on("mouseover", evaluateTooltip);

    element.on("$destroy", () => {
      element.off("mouseover", evaluateTooltip);
    });
  }
});

#1


7  

TL;DR: Plunker Demo (using $watch) Old demo (using $timeout)

TL; DR:Plunker演示(使用$ watch)旧演示(使用$ timeout)

(The answer was updated to reflect a suggestion to use $watch instead of $timeout, thanks for the comment Michael Mish Kisilenko!)

(答案已更新,以反映使用$ watch而不是$ timeout的建议,感谢评论Michael Mish Kisilenko!)

First of all, change your angular-ui directives to the updated ones (prefix with 'uib-'):

首先,将angular-ui指令更改为更新的指令(前缀为'uib-'):

<div uib-tooltip="{{value}}" show-tooltip-on-text-over-flow tooltip-enable="false">{{value}}</div>

And then use the following directive, which dynamically changes the angular-ui provided feature tooltip-enable (note that you should initialize the element with directive tooltip-enable="false" so the tooltip will be disabled if the text is not truncated:

然后使用以下指令,该指令动态更改angular-ui提供的功能tooltip-enable(请注意,您应该使用指令tooltip-enable =“false”初始化元素,以便在文本未截断时禁用工具提示:

myApp.directive("showTooltipOnTextOverflow", ["$timeout", function($timeout) {
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
      var el = element[0];
      scope.$watch(function(){
        return el.scrollWidth;
      }, function() {
        var el = element[0];
        if (el.offsetWidth < el.scrollWidth) {
          //console.log('ellipsis is active for element', element);
          attrs.tooltipEnable = "true";
        } else {
          //console.log('ellipsis is NOT active for element', element);
        }
      });
      /*$timeout(function() {
        var el = element[0];
        if (el.offsetWidth < el.scrollWidth) {
          //console.log('ellipsis is active for element', element);
          attrs.tooltipEnable = "true";
        } else {
          //console.log('ellipsis is NOT active for element', element);
        }
      });*/
    }
  };
}]);

To truncate the text i'll use plain CSS:

截断文本我将使用纯CSS:

span.truncated {
    width: 400px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

#2


0  

Using watch as mentioned in answer posted by Lulu will bring performance down. It will add so many watchers as many cells grid has and these get evaluated in each digest cycle.

使用Lulu发布的回答中提到的手表将降低性能。它将添加许多单元网格所具有的观察者,并在每个摘要周期中对其进行评估。

I modified his code to use mouseover approach - so the need of tooltip is evaluated in mouseover event only on particular cell:

我修改了他的代码以使用鼠标悬停方法 - 因此只在特定单元格的鼠标悬停事件中评估工具提示的需要:

myApp.directive("showTooltipOnTextOverflow", ["$timeout", function($timeout) {
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
      var el = element[0];

      if (angular.isObject(el)) {
        var evaluateTooltip = (event: JQueryEventObject, isOurEvent: boolean) => {
        // evaluate whether to enable tooltip
        attrs.tooltipEnable = el.offsetWidth < el.scrollWidth ? "true" : "false";

        if (isOurEvent !== true && attrs.tooltipEnable === "true") {
          // tooltip should be enabled, trigger mouseover again to trigger tooltip (current mouseover is already handled by tooltip with false value)
          // and mark it as our event to avoid its handling here
          element.trigger("mouseover", [true]);

          // revert tooltip enabling back to false to cover case when mouseover happens and tooltip should not be enabled
          scope.$applyAsync(() => {
          attrs.tooltipEnable = "false";
        });
      }
    };

    element.on("mouseover", evaluateTooltip);

    element.on("$destroy", () => {
      element.off("mouseover", evaluateTooltip);
    });
  }
});