После первого поста про свой вариант изучения JavaScript, совмещая приятное с полезным, решил внести важные дополнения и, заодно, сделать рывок в обучении.
Первый вариант скрипта не имел одной едва заметной, на первый взгляд, но важной функции — отправки личного сообщения автору комментария. Тут же решено было исправить это:
function clickPm(event) {
event.preventDefault();
var username = event.target.parentElement.parentElement.parentElement.querySelector('a.username').innerText;
window.location.pathname = '/conversations/' + username;
}
var infobars = document.querySelectorAll('.to_chidren'); //в стилях Хабра замечены и другие классы с опечатками, so strange
for (i = 0; i < infobars.length; i++) {
var pmLink = createBtn('pmlink', '', ' reply_link', 'container', clickPm);
infobars[i].appendChild(pmLink);
}
Создается ссылка с иконкой сообщения для каждого комментария, а обработчик по нажатию отправляет нас на страницу отправки личного сообщения пользователю, в чьем комментарии мы выполнили нажатие.
Так как последние дни явно прослеживается тренд на разного рода юзербары, то решено было сделать оный с обязательным отображением кармы и рейтинга, а тажке сохранением привычной структуры пользовательского блока. Также юзербар должен быть прозрачным, чтобы не слишком затруднять навигацию по страницам анонсов (лента, посты и так далее). Если второе решалось стилями, то первое было немного сложнее. Почитав про правила оформления запросов усвоил важную вещь — только асинхронные запросы. Сделаю небольшую ремарку — обычно я стараюсь каждый вновь изученный материал применять на «пациенте», то есть в контексте своих задач. Это же я советую выполнять таким же как я начинающим, так как примеры не запоминаются ввиду их однобокости.
Вначале нужно создать юзербар:
var userpanel = document.querySelectorAll('.userpanel')[0];
var userpanelTop = document.querySelectorAll('.userpanel > .top')[0];
var userpanelBottom = document.querySelectorAll('.userpanel > .bottom')[0];
var karmaDescription = document.querySelectorAll('.charge')[0];
if (userpanelBottom != null) {
userpanelTop.innerHTML += userpanelBottom.innerHTML;
userpanel.removeChild(userpanelBottom);
userpanel.removeChild(karmaDescription);
karmaCounter();
};
if (userpanelTop == null) {
var top = document.createElement('div');
top.className = 'top';
top.innerHTML = userpanel.innerHTML;
userpanel.innerHTML = null;
userpanel.appendChild(top);
};
Определяю переменные и условия для разных состояний пользователя (залогинен и разлогинен). Небольшой трюк с userpanel.innerHTML = null после передачи содержимого переменной userpanel другой создаваемой переменной userpanelTop (которая является контейнером юзербара) и до включения userpanelTop в userpanel позволяет избежать дополнительных хождений по DOM-у.
Так выглядит функция парсинга xml-страницы с данными пользователя:
function karmaCounter() {
var xmlhttp=new XMLHttpRequest();
xmlhttp.overrideMimeType('text/xml');
var userBlock = document.querySelectorAll('.top > .username')[0].innerText;
var userpanelTop = document.querySelectorAll('.userpanel > .top')[0];
var karmaCharge = document.createElement('a');
karmaCharge.className = 'count karma';
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
var counter = xmlhttp.responseXML.querySelectorAll('karma')[0].firstChild;
var rating = xmlhttp.responseXML.querySelectorAll('rating')[0].firstChild;
karmaCharge.innerText = 'карма ';
karmaCharge.appendChild(counter);
karmaCharge.innerText += ', рейтинг ';
karmaCharge.appendChild(rating);
userpanelTop.insertBefore(karmaCharge, userpanelTop.firstChild.nextSibling.nextSibling);
}
}
xmlhttp.open("GET", '/api/profile/' + userBlock ,true);
xmlhttp.send();
}
Важный момент — для корректного парсинга мне пришлось переопределять MIME-тип с помощью overrideMimeType('text/xml').
Забыл упомянуть о главном — в рамках скрипта пытаюсь соблюдать общий стиль и выполнять новый функционал так, чтобы он органично смотрелся в приятном минимализме Хабра. Нет цели напридумывать много всего и попытаться это реализовать в скрипте, лишь необходимое и не выбивающееся из рамок.
И на этот раз не обошлось без некоторой размытости в тексте, за что прошу меня простить. Ввиду скромного опыта где-то я могу ошибаться и, вероятно, вызывать справедливое возмущение. Для такого аргументированного возмущения в виде комментариев и был создан данный пост, ведь я смогу усвоить полезные уроки.
Спасибо всем, принявшим приглашение посетить мой луна-парк.
Автор: Glebcha