Добавление оптимизации двоичного поиска в функцию многострочного ограничения текста - PullRequest
0 голосов
/ 06 марта 2019

Мне нужно решение для динамической обрезки многострочного текста в контейнере, чтобы вместо него он заканчивался эллипсами.

CSS не решение

В идеале CSS (линейный зажим) справится с этим, но поддержка браузера просто отсутствует (85,65%). - Кроме того, в настоящее время это «чрезвычайно хрупкая [...] недоделанная нестандартная собственность [y]» ( source ).

JS: выскочить, пока не подойдет (текущее решение)

В настоящее время у меня есть работающее решение JavaScript (measure & pop, пока оно не подходит), но оно плохо масштабируется. Это зависит от разницы между длиной текста и фиксированной длины, а также от количества текстовых элементов с фиксацией.

var trimTextAddEllipses = function (targetElementClassName) {
	var elArray = document.getElementsByClassName(targetElementClassName);
	Array.from(elArray).forEach(function (el) {

		// create a cache of full text in data-attribute to be non-destructive
		if (!el.hasAttribute('data-text-cache')) {
			el.setAttribute('data-text-cache',el.textContent);
		}
		// reset
		var words = el.textContent = el.getAttribute('data-text-cache');
		// turn into array to pop off items until it fits.
		var wordArray = words.split(' ');
		while (el.scrollHeight > el.offsetHeight) {
			wordArray.pop();
			el.innerHTML = wordArray.join(' ') + ' …';
		}
	});
};

Для изменения размеров я называю это обратным вызовом для requestAnimationFrame вызова, чтобы ограничить число выполнений зажима.

JS: бинарный поиск (цель)

Слова расположены по порядку (то есть отсортированы), поэтому подход с использованием бинарного поиска поможет повысить эффективность кода.

Я нашел эту эту функцию binarySearch, но не могу придумать функцию сравнения для правильной работы.

Мне бы хотелось помочь с функцией сравнения, которая будет использоваться со связанной функцией двоичного поиска, или с другим решением для двоичного поиска, которое подходит для этой проблемы.

Примечание

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

1 Ответ

2 голосов
/ 06 марта 2019

Вы можете легко позволить циклу использовать бинарный поиск:

let end = wordArray.length, distance = end;

while(distance > 0) {
   distance = Math.floor(distance / 2);
   el.innerHTML = wordArray.slice(0, end).join(' ') + '...';
   end += el.scrollHeight > el.offsetHeight ? -distance : distance;
}
...