Показать количество слов, которые переполнены в AngularJS - PullRequest
0 голосов
/ 16 января 2020

У меня переполненный текст, и я хочу отобразить количество слов, которые скрыты переполнением.

Например: у меня есть строка: I want to see the overflowed words that are hidden in here. И мой div может содержать только 3 слова. Итак, я хочу увидеть: I want to +9.

Вот что у меня есть:

let items = [
  "item 1 - class 1;",
  "item 2 - class 1;",
  "item 3 - class 1;",
  "item 4 - class 1;",
  "item 5 - class 1;",
  "item 6 - class 1;",
  "item 7 - class 1;",
  "item 8 - class 1;",
];

let app = angular.module('app', []);
app.directive('my', function() {
  return {
    controller: function($scope) {
      $scope.items = items;
    }
  }
});
.a {
  white-space: nowrap;
  overflow: hidden;
  width: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>

<body ng-app="app">
  <div my class="a">
    <span ng-repeat="item in items">{{item}}</span>
  </div>
</body>

Я не могу найти способ сделать 2 вещи: 1. показать только полностью элементы, а не частично элементы в строке. 2. показать текст, например, (+8), который может расходовать и увидеть переполненные 8 элементов.

Ответы [ 3 ]

0 голосов
/ 20 января 2020

Я думаю, что вы можете сделать это, используя el.offsetLeft - el.scrollLeft, а затем getBoundingClientRect(), чтобы получить ширину и посмотреть, находится ли элемент внутри <div my class="a">:

https://codepen.io/Alexander9111/pen/OJPaNBP

До сих пор я только просматривал, какие элементы (промежутки) находятся внутри, наполовину внутри и снаружи div.a - я не уверен, как с этим справиться?

(Обратите внимание, что первая функция getOffset происходит от: { ссылка }, а затем приведенный ниже код принадлежит мне.

//getOffset take from:
//https://stackoverflow.com/a/442474/9792594
function getOffset( el ) {
    var _x = 0;
    var _y = 0;
    while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
        _x += el.offsetLeft - el.scrollLeft;
        _y += el.offsetTop - el.scrollTop;
        el = el.offsetParent;
    }
    return { top: _y, left: _x };
}

document.addEventListener('DOMContentLoaded',
 function(){
  const spans = document.querySelectorAll("span");
  const a = document.querySelector(".a");
  const a_rect = a.getBoundingClientRect();
  const box = getOffset(a);
  for (i = 0; i < spans.length; i++){
    const el = getOffset( spans[i]);
    rect = spans[i].getBoundingClientRect();
    console.log(i, el.left, el.left + rect.width);
    if ((el.left + rect.width) < (box.left + a_rect.width)){
      console.log(i, "inside")
    } else if (el.left < (box.left + a_rect.width)) {
      console.log(i, "half inside")         
    } else {
      console.log(i, "outside")
    }
  }

}, false);
0 голосов
/ 21 января 2020

ОБНОВЛЕНИЕ после комментария:

Хорошо, после разъяснения, я думаю, что у меня есть лучшее представление о том, чего вы пытаетесь достичь. Код ниже почти точно делает то, что вы хотите - но это, конечно, не элегантное решение. Фиксированная ширина, символьное ограничение, все еще сохраняющееся как константа, являются обеими обязанностями (например, когда речь идет о адаптивном дизайне, шрифтах меньшего / большего размера и т. Д. c.) Кроме того, код, который я сделал, далек от semanti c html или правильного JS / AngularJS, но я надеюсь, что он поможет вам в каком-то направлении.

Два важных бита кода :

1) содержимое :: after с атрибутом dynamici c, который также можно активировать. Поэкспериментируя с этой концепцией, я полагаю, что это поможет вам найти оптимальное решение

2) css с двумя видимыми состояниями (открыто / закрыто) и нацелено на него динамически c ID

Надеюсь, это поможет, дайте мне знать, если что-то неясно или все еще не то, чего вы хотите достичь.


Это немного обходной путь, и я даже не уверен, что именно этого вы пытались достичь в отношении эффекта переполнения. Обратите внимание, что в отношении производительности это замедляется при больших записях (хотя я полагаю, что вы не ожидаете, что вы увидите тысячи таких строк). Очевидно, что это не полное решение, но может привести вас к возможному пути. Дайте мне знать в комментариях, если это абсолютно не то, на что вы надеялись - тогда мы можем найти способ.

let items = [
  "This is a very long text to cut",
  "This is short",
  "Buuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuut whaaaaaaaaaaaaaaaaaaaat is this?",
  "This is super lengthy. This is super lengthy. This is super lengthy. This is super lengthy. This is super lengthy. This is super lengthy. This is super lengthy. This is super lengthy. "
];

let app = angular.module('app', []);
app.directive('my', function() {
  return {
    controller: function($scope, $timeout) {
      $scope.items = [];

      let limitChar = 20; // set it according to width, though the css of element p will do the rest of the magic
      $.each(items,function(index,item){
        let words = item.trim().split(" ");  // trim is required not to add empty strings to the array when visibleWords is created below

        let visible = item.substring(0, limitChar).trim();
        let visibleWords = visible.split(" ");
        let remainingWordCount = words.length - visibleWords.length;

        let entry = {
          "open" : false,
          "trimmed" : visibleWords.join(" "),
          "count" : remainingWordCount,
          "full" : item
        }

        $scope.items.push(entry)
      })

      $scope.opener = function(item, id){
        item.open = true;
        // the timeout is required so that the DOM refreshes first and the item_id_open dom element is actually existing.
        $timeout(function(){
          $('#' + 'item_' + id + "_open").css({
              'overflow' : 'initial',
              'text-overflow' : 'initial',
              'white-space' : 'normal'
          });
        },0)
      }

      $scope.closer = function(item,id){
        item.open = false;
        // the timeout is required so that the DOM refreshes first and the item_id_open dom element is actually existing.
        $timeout(function(){
          $('#' + 'item_' + id + "_closed").css({
              'overflow' : 'hidden',
              'text-overflow' : 'ellipsis',
              'white-space' : 'nowrap'
          });
        },0)
      }
    }
  }
});
.container2{
  position:relative;
  float:left;
  background-color:green;
  width:180px;
}

.element{
  width:180px;
  position:relative;
  float:left;
}

.element p{
  position:relative;
  float:left;
  display:inline-block;
  width:150px;
  margin:10px 0;
  overflow:hidden;
  text-overflow:ellipsis; /* this is optional, can also be substituted with modifying the width */
  padding-right:5px;
  word-break:break-word;
  white-space:nowrap;
}

.element span{
  position:absolute;
  right:0px;
  top:10px;
  display:inline-block;
}

.element span::after{
  content: "(+" attr(remainder) ")";
  float:left;
  position:relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>

<body ng-app="app">
  <div my>
    <div class="container2">
      <div flex="100" class="element" ng-repeat="item in items track by $index">
        <p ng-if="!item.open" id="{{'item_' + $index + '_closed'}}">
          {{item.trimmed}}
        </p>
        <span ng-if="!item.open && item.count > 0" ng-click="opener(item, $index)" style="cursor:pointer" remainder="{{item.count}}"></span>

        <p ng-if="item.open" id="{{'item_' + $index + '_open'}}">
          {{item.full}}
        </p>
        <span ng-if="item.open" ng-click="closer(item, $index)" style="cursor:pointer" remainder="{{item.count}}"></span>
      </div>
    </div>
  </div>
</body>
0 голосов
/ 16 января 2020

Вы можете создать переменную, которая будет содержать длину текста отверстия за вычетом длины текста, который можно просмотреть в вашем случае. «Я хочу» - это 9 символов, затем

$scope.hiddenChars=YourHoleText.length-9;

и отображение * 1004. * значение, если оно больше нуля

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...