Так как я постоянно читаю Хабр, то какие-то, на мой скромный взгляд, шероховатости в юзабилити тут же находили место в списке непреодолимых желаний по улучшению.
А почетное место заняла идея отображения обновлений трекера без необходимости дополнительных переходов и, желательно, в одном блоке.
Конечно же вся соль была в том как получать данные, но нужно же где-то их показывать. Поэтому путь от простого к сложному начался с контейнера для получаемых обновлений:
var trackerLink = document.querySelector('.userpanel > .top > a.count'); trackerLink.href = '#tracker_updates'; var updates = document.createElement('ul'); updates.className = 'updates'; updates.style.display = 'none'; userpanel.appendChild(updates); trackerLink.onclick = function (event) { event.preventDefault(); updates.style.display = (updates.style.display != 'none' ? 'none' : 'block'); };
И логически перешел к написанию функции парсинга страниц трекера:
function getUpdates(url, getUrl) { var xmlhttp = new XMLHttpRequest(); xmlhttp.responseType = 'document'; xmlhttp.onreadystatechange = function () { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { var tracks = xmlhttp.responseXML.querySelectorAll(url); for (i = 0; i < tracks.length; i++) { var post = tracks[i]; post.removeChild(post.firstElementChild); updates.appendChild(post); post.outerHTML = post.outerHTML.replace(/td/g, "li"); } } } xmlhttp.open("GET", getUrl, true); xmlhttp.send(); } getUpdates('tr.new > td.event_type', '/tracker/subscribers/'); getUpdates('tr.new > td.mention_type', '/tracker/mentions/');
В итоге получался список обновлениями подписчиков и новыми упоминаниями о пользователе. Все верно, главное же — обновления постов. И вот с ними все сложилось несколько иначе, так как требовалось еще отображать счетчик новых комментариев для каждого поста:
(function () { var xmlhttp = new XMLHttpRequest(); xmlhttp.responseType = 'document'; xmlhttp.onreadystatechange = function () { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { var tracks = xmlhttp.responseXML.querySelectorAll('tr.new > td.post_title'); var commentCounts = xmlhttp.responseXML.querySelectorAll('tr.new > td.comment_count'); for (i = 0; i < tracks.length; i++) { var track = tracks[i]; var commentCount = commentCounts[i].firstChild.nextSibling; commentCount.className = 'count'; track.appendChild(commentCount); updates.appendChild(track); track.outerHTML = track.outerHTML.replace(/td/g, "li"); } }; xmlhttp.open("GET", '/tracker/', true); xmlhttp.send(); })();
А обернул запрос в анонимную самовызывающуюся функцию потому, что все описанные ранее части выполнялись в виде одной именованной функции.
Все бы хорошо, да наверняка не всем хочется каждый раз кликать кнопку отображения все скрытых картинок или разворачивать дерево ответов к комментариям. Вдруг нужна только пользовательская панель. И тут решено было наконец добавить управление настройками, чтобы комфорт был по-настоящему таковым. Почти сразу пришел к варианту с хранением настроек в local storage и тут процесс встал, так как правильнее было бы использовать родные для каждого из браузеров методы работы с локальным хранилищем. Начал с изучения Chrome Storage API и……им же и закончил, потому что слишком накладно получается строить луна-парк для каждого вместе счастливого будущего для всех и сразу. Появились некотрые идеи, но ввиду недостаточного опыта и просто ради совета бывалого обратился за помощью к spmbt. Он мне как раз подсказал элегантный вариант в виде трех простых функций:
var setLocStor = function(name, hh){ if(!localStorage) return; localStorage['custom_'+ name] = JSON.stringify({h: hh}); }, getLocStor = function(name){ return (JSON.parse(localStorage && localStorage['custom_'+ name] ||'{}')).h; } ,removeLocStor = function(name){localStorage.removeItem('custom_'+ name);}
Насколько я понимаю, в случае использования Storage API Хрома запросы будут выполняться асинхронно (прошу меня поправить, так как могу ошибаться).
Не буду мучать вас портянками с кодом и вкратце упомяну о том, что создавал именованные чекбоксы со значением по-умолчанию disabled, а для отключения фичи значение менялось на enabled. При клике по каждому чекбоксу выполняется запись пары ключ-значение в local storage. При вызове блока настроек читаются записи local storage и чекбоксам присваиваются соответствующие состояния (при значении ключа disabled чекбокс в состоянии false и если enabled — true). Функции, отвечающие за фичу «слушают» значение своего ключа в local storage и выполняются только если значение в состоянии disabled, то есть галочку «отключить» в настройках не установили.
И в завершении длинного рассказа небольшой бонус в виде отображение текущих кармы и рейтинга пользователя по клику на область с информацией о данном пользователе в его комментарии.
Ну вот и все, я убедился в том, что совмещать приятное с полезным в обучении не только можно, но и нужно. Учиться интереснее если есть стимул, который каждый день приходит в виде пары-тройки идей. Даже если результат трудов пригодился только тебе и нескольким приятелям, то нет абсолютно никакого повода думать о сомнительности мероприятия — ты получил не очередной изученный минимум, а новое увлечение.
Теперь развитие скрипта будет зависеть от свободного времени и новых предложений/хотелок, а полученные знания продолжу закреплять на практике и придумывать себе более сложные задачи для дальнейшего изучения JavaScript.
Спасибо всем, кто дочитал и, надеюсь, кого-то убедил повторить «путь самурая».
Буду признателен за конструктивную критику и рекомендации.
ссылка на оригинал статьи http://habrahabr.ru/post/192444/
Добавить комментарий