UZER2006
@UZER2006

Как правильно сделать автозамену текстовых смайликов?

Здравствуйте.

Решил добавить в свой чат текстовые смайлики, которые рендерятся на клиенте. Возникли две проблемы.

1. Как сделать нормальную (в т.ч. по производительности) замену текстового представления ":-)" на <img src='id.gif' title=':-)' />?

Пока это работает в таком виде:
for (var i = 1; i < messages.smiliesList.length; i++){
	for (var j = 0; j < messages.smiliesList[i].length; j++){
		if (message.indexOf(messages.smiliesList[i][j],k)>-1){
			message = message.split(messages.smiliesList[i][j]).join('<img src="img/smilies/'+messages.leadingZero(i)+'.gif" title="'+messages.smiliesList[i][j]+'" alt="'+messages.smiliesList[i][j]+'" />');
		}
	}
}


Но возникают конфликты, например, на паре смайликов «О:-)» и ":-)", первый после полной обработки превращается в
&lt;img src='01.gif' title='O&lt;img src='02.gif' title=':-)' /&gt;' /&gt;
.

Пока видится, что нужно как-то делать фильтр на то, чтобы после каждого прохода текст парсился только за пределами тегов или как-то через несколько буфферных переменных. Анализировать строку посимвольно не представляю как, смайликов много с самыми разными представлениями. Никаких терминальных символов или ещё чего добавлять тоже не хочу, нарушится текстовое представление сообщения.

2. Также проблема во всплывающих уведомлениях, где я вырезаю все теги, и картинки заменяю на их title. Распознаю по регулярке, ломается на смайликах со знаком ">" в текстовом представлении.
  • Вопрос задан
  • 4310 просмотров
Решения вопроса 1
  1. Матричная структура немного закручена, вот с обычным массивом, надеюсь идея будет понятна:
    function regexpify(str) {
    
        return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
    
    }
    
    function getIndex(smiles, name) {
        for (var i = 0, length = smiles.length; i < length; i++) {
            if (smiles[i].name === name) {
                return i;
            }
        }
        console.error('not found', name);
        return -1;
    }
    
    function process(message) {
        var smiles = messages.smiliesList,
            names = smiles.sort(function(a, b) {
                // сортируем имена, так что бы более специфичные были вначале
                return a.name.length > b.name.length ? 1 : -1;
            }).map(function(smile) {
                return regexpify(smile.name);
            }),
            regexp = new RegExp(names.join('|'), 'g');
    
        return message.replace(regexp, function(name) {
            return "<img src='/smiles/" + getIndex(smiles, name) + ".gif' alt='" + name + "'/>";
        })
    }
    

  2. Испольуя jQuery:
    function replaceImages(message) {
        return $('<div>').html(message).find('img').each(function(index, img) {
            $(img).replaceWith($(img).attr('alt'));
        }).end().html();
    }
    
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы