Задать вопрос

Как правильно обернуть ссылки внутри текста при помощи JS?

Здравствуйте! Использую такую функцию для оборачивания ссылок вида site.com или https://site.com в соответствующий html-тэг <a href></a>
function wrapLinks() {
    let selector = document.querySelectorAll('.article-comment-text.fl'),
        patternProtocol = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g,
        patternUrl = /[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g;

    selector.forEach(element => {
        let text = element.innerHTML;

        if (text.match(patternProtocol)) {
            text = text.replaceAll(patternProtocol, '<a href="$&" target="_blank">$&</a>');
        } else {
            text = text.replaceAll(patternUrl, '<a href="https://$&" target="_blank">$&</a>');
        }   
        element.innerHTML = text;
    });
}

Но возникает проблема, если, например, в тексте есть картинка, обернутая в тэг img.
Атрибут src этого тэга тоже ссылка и парсится наравне с другими. Подскажите можно решить эту проблему? Заранее спасибо!
  • Вопрос задан
  • 692 просмотра
Подписаться 1 Простой Комментировать
Решения вопроса 1
@artalexs Автор вопроса
Немного покопался и доработал функцию, если кому нужно, вот она
function wrapLinks() {
    let selector = document.querySelectorAll('.article-comment-text.fl'),
        pattern = /(https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z()]{1,6}\b([-a-zA-Z0-9()@:;%_\+.~#?&//=]*)/g,
        imgPattern =  /<img[^>]+src="?([^"\s]+)"?\s*(\/)?/g;

    selector.forEach(element => {
        let text = element.innerHTML;
        let needless = [];
        let urls = text.match(pattern);
        let links = element.querySelectorAll('a[href]');

        if (urls) {
            while (src = imgPattern.exec(text)) {
                needless.push(src[1]);
            }

            if (links.length) {
                links.forEach(elem => {
                    needless.push(elem.href);
                    needless.push(elem.innerHTML);
                });
            }

            urls = urls.filter(el => {
                return needless.indexOf(el) < 0;
            });

            urls.forEach(elem => {
                if (elem.match(/^https?\:\/\//i)) {
                    text = text.replace(elem, '<a href="$&" target="_blank">$&</a>');
                } else {
                    text = text.replace(elem, '<a href="//$&" target="_blank">$&</a>');
                }
            });
        }

        element.innerHTML = text;
    });
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
zb_venom
@zb_venom
Жизнерадостный чебурек
Что бы исключить картинки:
if(element.tagName != "IMG")
Если же у вас текст находится в тэге<p></p>, чтобы допустить изменение только в нем:
if(element.tagName == "P")
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы