Выделите Ajax Response с помощью Javascript - PullRequest
0 голосов
/ 17 мая 2018

Я пытаюсь выделить запрос внутри текста, полученного из ответа ajax, перед тем как создать HTML-код и вставить его в DOM.Прямо сейчас я использую этот фрагмент кода:

function highlightWords(line, word, htmltag) {
    var tag = htmltag || ["<b>", "</b>"];
    var regex = new RegExp('(' + preg_quote(word) + ')', 'gi');
    return line.replace(regex, tag[0] + "$1" + tag[1]);
}

function preg_quote(str) {
    return (str + '').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1");
}

Однако, это не в состоянии выделить другие слова, если запрос похож на sit behind.Это только выделит полную фразу, а не отдельные слова.Он также не заботится о тегах HTML, и это приводит к непредсказуемым результатам, если запрос span, например ...

Я обнаружил различные библиотеки, которые лучше справляются с подсветкой, например https://markjs.io/ или https://www.the -art-of-web.com / javascript / search-highlight /

Эти библиотеки, тем не менее, всегда хотят выделить контент, который уже присутствует в DOM.

Мой поиск получает ответ ajax, который я затем превращаю в HTML с JS и вставляю полную HTMLString в родительский контейнер, используя DOM7 (что аналогично jQuery).Поэтому я бы предпочел выделить текст перед созданием HTMLString и вставкой его в DOM.

Есть идеи?

Ответы [ 4 ]

0 голосов
/ 21 мая 2019

Я просто делаю выделение в ответе на запрос ajax.Это работает для меня:

$.ajax({
    url : url,
    type : 'POST',
    success: function(response) {
        // Highlight
        let term = 'word';
        $context = $("#selector");
        $context.show().unmark();
        if (term){
            $context.mark(term, {
                done: function() {
                    $context.not(":has(mark)").hide();
                }
            });
        }
    }
});
0 голосов
/ 31 мая 2018

Если ваш ответ ajax содержит html, я не думаю, что есть простой способ обойти сначала создание элементов DOM.Ниже приведена работа, даже в случае, если в запросе указано span, а результаты ajax содержат <span>

        function highlightWords(line, word, htmltag) {
            var words = word.split(/\s+/);
            var tag = htmltag || ["<b>", "</b>"];

            var root = document.createElement("div");
            root.innerHTML = line;
            root = _highlightWords(words, tag, root);
            return root.innerHTML;
        }

        // Recursively search the created DOM element
        function _highlightWords(words, htmlTag, el) {
            var children = [];

            el.childNodes.forEach(function(el) {
                if (el.nodeType != 3) { // anything other than Text Type
                    var highlighted = _highlightWords(words, htmlTag, el);
                    children.push(highlighted);
                } else {
                    var line = _highlight(el.textContent, words, htmlTag);
                    var span = document.createElement("span");
                    span.innerHTML = line;
                    children.push(span);
                }
            });

            // Clear the html of the element, so the new children can be added
            el.innerHTML = "";
            children.forEach(function (c) { el.appendChild(c)});
            return el;
        }

        // Find and highlight any of the words
        function _highlight(line, words, htmlTag) {
            words.forEach(function(singleWord) {
                if (!!singleWord) {
                    singleWord = htmlEscape(singleWord);
                    line = line.replace(singleWord, htmlTag[0] + singleWord + htmlTag[1]);
                }
            });
            return line;
        }
0 голосов
/ 31 мая 2018

Я думаю, вы были на правильном пути, используя для этого библиотеку. Я использовал для этого замечательную библиотеку с именем mark.js .

Работает без зависимостей или с jQuery. То, как вы можете заставить его работать.

  1. Сделайте вызов AJAX.
  2. Загрузить строку в DOM.
  3. Вызвать API Mark.js для загруженного вами контента.

Вот фрагмент кода:

document.addEventListener('DOMContentLoaded', getText);

function getText() {
  const headline = document.getElementsByTagName("h1")[0];
  const p = document.getElementsByTagName("p")[0];

  fetch('https://jsonplaceholder.typicode.com/posts/1').
  then(response => response.json()).
  then(json => {
    console.log(json);
    headline.innerHTML = json.title;
    p.innerHTML = json.body;
    addMark('aut facere');
  });
}

function addMark(keyword) {
  var markInstance = new Mark(document.querySelector('.context'));
  var options = {
    separateWordSearch: true
  };
  markInstance.unmark({
    done: function() {
      markInstance.mark(keyword, options);
    },
  });
}
<script src="https://cdn.jsdelivr.net/mark.js/8.6.0/mark.min.js"></script>
<div class="context">
  <h1></h1>
  <p></p>
</div>
0 голосов
/ 31 мая 2018

Стиль фрагмента: Предупреждение : используется DOM7 согласно Вопросу

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

var text // your ajax text response
var strQuery = 'sit behind' // your query string 

var queryWords = strQuery.split(' ')
var textWords = text.split(' ')
var bufferNormalWords  = []

textWords.forEach(function (word) {
    if (queryWords.indexOf(word) != -1) { // found
      var normalWords = bufferNormalWords.splice(0, buffer.length) // empty buffer
      // Your DOM7 commands
      $$('#container').add('span').text(normalWords.join(' ')) // normal text
      $$('#container').add('span').css('color', 'red').text(word + ' ') // why not red          
    }
    else bufferNormalWords.push(word)
})

Не путайте текст с HTMLStrings, просто установите текст и создайте необходимые элементы, чтобы придать им стиль, который вам нужен, с помощью DOM7 .

...