Наша совместная команда Banwar.org

Связаться с нами

  • (097) ?601-88-87
    (067) ?493-44-27
    (096) ?830-00-01

Статьи

Список, що розкривається спойлер - як обрізати текст на jQuery?

Днями виникла задача реалізувати своєрідний спойлер на jquery. Суть зводиться до того, щоб якщо в блок виводиться занадто довгий текст, наприклад, перевищує 2000 символів, тоді текст повинен обрізатися, а в кінець вставлятися крапки. До того ж після блоку необхідно виводити посилання «Читати далі», яка буде розкривати текст повністю. Слід було також не забувати і про функціонал зворотного згортання блоку в формат анонса.

Завдання досить стандартна, проте пошук відповідного jquery-плагіна не увінчався успіхом, оскільки у всіх плагінах, які вдалося знайти, обмеження задаються не кількістю символів, а висотою блоку. Тобто вказується висота контейнера, і плагін обрізає текст, що виходить за його межі. В інтернеті можна знайти дуже зручні варіанти таких плагінів, наприклад, Readmore.js і dotdotdot . Причому останній навіть може відслідковувати зміну розміру вікна і автоматично оновлювати результат.

Однак проблема була в тому, що сайт адаптивний і блок приймає різну ширину в залежності від ширини вікна браузера. У підсумку могла вийти ситуація, коли в блоці виявиться зовсім мало символів. Звичайно ж, можна по якомусь алгоритму міняти висоту блоку при ресайз вікна, проте було прийнято рішення не робити якусь надбудову над якимось готовим рішенням, а написати свій невеликий плагін, який буде виконувати обрізку тексту на jquery виходячи з заданої кількості символів.

Звичайно ж, можна по якомусь алгоритму міняти висоту блоку при ресайз вікна, проте було прийнято рішення не робити якусь надбудову над якимось готовим рішенням, а написати свій невеликий плагін, який буде виконувати обрізку тексту на jquery виходячи з заданої кількості символів

Можна виділити кілька переваг даного підходу.

  1. Можна бути впевненим, що в блоці буде відображатися обсяг тексту, який несе смислове навантаження навіть в згорнутому стані.
  2. Не потрібні зайві обробники на зміну розміру вікна, які б постійно виконували перевірку того, скільки тексту влазить в блок.

При реалізації також необхідно було врахувати дві речі, які впливають на красу результату. По-перше, потрібно щоб текст обрізався по цілому слову. По-друге, уникнути ситуації «розкривати занадто мало» - може статися в разі, коли загальна кількість символів в блоці трохи більше заданого значення, за яким слід проводити обрізання, наприклад, на 50-100 символів. Якщо відповідних установок буде вказані, то модуль буде використовувати дефолтні значення.

Отже, алгоритм завдання досить простий:

  1. Вирізаємо необхідну кількість символів - формуємо анонс.
  2. Доповнюємо текст анонса трьома крапками і додаємо html-обв'язку у вигляді посилання «Читати далі».
  3. Навішуємо обробник на посилання, яка буде змінювати текст в блоці на анонс і повний залежно від стану.

Сама трудомістка частина реалізації скрипта html-спойлера - отримання анонса з повного тексту блоку, оскільки в блоці може бути не просто текст, а відформатована за допомогою html-тегів розмітка.

Нижче приведена функція, що відповідає за вирізання з html-коду шматка, у якого кількість символів, які не є html-розміткою, так само заданому в параметрах значенням або більше на величину закінчення останнього слова анонса.

// формування анонса person.cutBrief = function () {var tmp, i = 0, // лічильник циклів j = 0, // лічильник циклів html = data.html, // html блоку htmlLength = html.length, // кількість символів html блоку count = 0, // лічильник текстових символів countFlag = true, // поточний символ не є html-розміткою endCharsLen = ENDCHARS.length, // розмір масиву символів, що вказують на закінчення слова end = htmlLength, // позиція кінця анонса при пошуку resultLimit = data.limit.total - data.limit.delta, // необхідну кількість символів tagName, // назва тега tagStack = []; // стек тегів, які необхідно закрити в кінці анонсу if (data.count> data.limit.total) {// формуємо анонс for (; i <htmlLength; i ++) {// якщо відкривається тег if (html [i] = == '<') {countFlag = false; // символ не останній if (i <htmlLength - 1) {// тег є закриває if (html [i + 1] === '/') {tmp = html.indexOf ( '>', i + 1); if (tmp> 0) {// вірний формат закриття тега tagName = html.substr (i + 2, tmp-i-2); // виявлений тег повинен мати закриває частину? if ($ .inArray (tagName, TAGDIC)> = 0) {tagStack.pop (); }}} Else {// тег є відкриває // наступний символ - будь-яка латинська буква? if (/\w/gi.test(html[i+1])) {// отримання імені тега і опреденіе його на необхідність закриття tmp = html.indexOf ( '>', i + 1); if (tmp> 0) {tagName = html.substr (i + 1, tmp-i-1); // тег повинен мати закриває частину if ($ .inArray (tagName, TAGDIC)> = 0) {tagStack.push (tagName); }} Else {// не є тегом countFlag = true; }} Else {// не є тегом countFlag = true; }}}} // інкремент лічильник текстових символів if (countFlag) {count ++; } // якщо закривається тег if (html [i] === '>') {countFlag = true; } // дійшли до кінця необхідного розміру анонса if (count> = resultLimit) {// поточний символ не є кінцем слова if ($ .inArray (html [i], ENDCHARS) <0) {// символ не останній if (i <htmlLength - 1) {// наступний символ теж не кінець слова if ($ .inArray (html [i + 1], ENDCHARS) <0) {// шукаємо перше входження кожного символу з набору і вибираємо найближчий for (; j < endCharsLen; j ++) {tmp = html.indexOf (ENDCHARS [j], i + 1); if ((tmp> 0) && (tmp <end)) {end = tmp; }}; i = end; }}} Else {// слово закінчилося цілком count--; } Break; }}; // вирізаємо шматок html data.brief = html.substr (0, i); // додаємо точки data.brief + = opt.ellipsis; // закриваємо відкриті теги for (i = tagStack.length - 1; i> = 0; i--) {data.brief + = '</' + tagStack [i] + '>'; }; } Else {// не обрізати data.brief = html; }};

Застосовується плагін стандартно:

$ ( '. B-block - first'). Readmore ();

В плагіні передбачені наступні параметри:

  • ellipsis {string} - символи, які будуть виводитися в кінці анонсу;
  • textOpen {string} - текст посилання в згорнутому стані;
  • textClose {string} - текст посилання в розгорнутому стані;
  • callback {function} - функція, що виконується після розкриття / закриття блоку;
  • brief {integer} - максимальна кількість символів анонса, зменшене на величину addition;
  • addition {integer} - мінімальна кількість символів розкривається частини тексту;
  • smoothly {integer} - час плавного розкриття / закриття блоку в мілісекундах.

Слід зауважити, що callback-функція спрацьовує тільки після закінчення анімації тексту, яка виконується на jquery за допомогою методу animate, і приймає два вхідних параметра: посилання блок і поточний стан.

Нижче наведено приклад того, як можна в залежності від стану блоку, виконувати будь-які свої дії:

$ ( '. B-block - second'). Readmore ({ellipsis: '[...]', textOpen: 'Відкрити', textClose: 'Закрити', callback: function (self, state) {state? Self .css ( 'background', '# e74c3c'): self.css ( 'background', '# 3498db');}, brief: 500, addition: 100});

CSS в прикладі по мінімуму, можна і зовсім без нього обійтися (код наведено на SCSS):

.b-readmore {padding: 15px 0 0 0; & __ link {color: # 000; text-decoration: underline; &: Hover, &: focus, &: active {color: # 000; text-decoration: none; }} & __ open {display: inline-block; } & __ close {display: none; } & - opened & {& __ open {display: none; } & __ close {display: inline-block; }}}

Оцінюємо і коментуємо, як краще зробити спойлер для сайту за що задається кількістю символів.

Substr (i + 2, tmp-i-2); // виявлений тег повинен мати закриває частину?
Pop (); }}} Else {// тег є відкриває // наступний символ - будь-яка латинська буква?
Readmore ({ellipsis: '[...]', textOpen: 'Відкрити', textClose: 'Закрити', callback: function (self, state) {state?

Новости

Banwar.org
Наша совместная команда Banwar.org. Сайт казино "Пари Матч" теперь доступен для всех желающих, жаждущих волнения и азартных приключений.