Учим JavaScript на примере: Делаем собственный виджет, скин, стиль, плагин для голоса. Очень подробно разжевываю код :)
Его можно установить с помощью tampermonkey и других плагинов для браузера. Обновлять можно одним кликом. НО! Такие скрипты могут быть опасны, потому даже перед обновлением моего скрипта - проверяйте код или пишите мне с вопросом - действительно-ли я обновлял код. Или кто-то взломал мою страничку на greasyfork.org ))
Собственный скрипт вы сможете опубликовать в репозиториях и поделится им со всеми или пользоваться им единолично, сделав конкретно под себя.
После прочтения этой простыни - сделать собственный скин, плагин, виджет для голоса или любого другого сайта для вас будет очень легко :)При желании и в теории, вы можете даже на этом заработать :) Например делая такие скины для популярных соцсетей.
Например сделать суровый скин для пользователей одноклассников , которые сейчас в тюрьме :)
Или стилизовать порнхаб под ютуб для тех, кто любит ручной труд в обеденный перерыв или вообще делать на заказ сайты похожими на exel или 1c бухгалтерию, что бы офисные работники могли сидеть в соцсетях без оглядки на начальство :)
Очень подробно разбираем код
Как выглядит плод работы скина можно увидеть в ролике youtu.be/X8VB9a6suDg
Так как голос пока не поддерживает синтаксис кода (правда я не пробовал встраивать сюда iframe от codepen или js fiddle ), то придется все отображать скринами с notepad++
Если мы будем делать userscript для greasyfork (он мне показался безопасней других), то в вам понадобиться указать вначале некоторые параметры:
- name будет определять название скрипта в каталоге
- version необходимо менять каждый раз при обновлении
- include важный параметр, который определяет для какой страницы скрипт. В данном случае указан домен golos.io/* где оператор * означает, что скрипт будет на всех связанных страничках с golos.io
require позволит вам указать необходимые библиотеки из доверенных источников. Поддерживается cdnjs и jsdelivr, а это значит, что у вас выбор из сотни тысяч отличных плагинов. В нашем случае мы подключили jquery. Все его знают и скрипт будет написан на нем.
Блок /* текст */ не обязателен, я просто оставил в нем произвольную заметку.
JavascriptДобавляем свой css стиль, виджеты, кнопки и меняем разрешение на фотографиях в ленте постов
Разберем это скрин
В 19 строке у нас переменная (var от англ. variable) inlinecss в которую мы вставим наши стили. На скрине для компактности стили пустые, на деле же выглядит примерно так:
Стили должны быть одной строкой и неплохо бы их прогонять через минификатор.
На 20 строчке проделываем почти тоже самое, но в переменную вставляем уже не стили, а html. Например в моем скине там боковая панель с ответами, копка прокрутки страницы вверх и другие мелкие элементы.
На 22 и 23 строке мы вставляем содержание переменных в страницу. Стили в блок head, а html в конец страницы, так как далее мы его будем позиционировать css свойством position:fixed
С 27 по 41 строку мы делаем фотографии большими. Дело в том, что в голосе, все фото хостятся на внешних сайтах, что бы избежать многих проблем кроссдоменности, конфликтов https, а так же получить контроль над этими фотками голос использует проксирование.
Например если вы добавите в текст ссылку вида https://vk.com/album/photo.jpg то на деле она будет отображена так:
- Для превью https://imgp.golos.io/256x128/ https://vk.com/album/photo.jpg
- Одноколоночный макет для узких экранов https://imgp.golos.io/640x480/ https://vk.com/album/photo.jpg
- Аватар https://imgp.golos.io/36x36/ https://vk.com/album/photo.jpg
В каждом из случаев одно и тоже фото проходит оптимизацию по разному.
В своем скине я сделал одноколоночный макет на подобие tumblr или fb , который подразумевает большое фото или фотосет. Но проблема оказалась в том, что источник фото на главной это imgp.golos.io/256x128/ - такое разрешение для больших плиток постов слишком низкое и нам нужно как-то получить доступ к нормальному размеру картинок. Вот тут мы и обращаемся к imgp.golos.io/640x480/ ведь мы знаем, что там такие же фотки, только с нормальным размером. Таким образом все, что нам нужно, это заменить на главной в ссылках 256 x 128 на 640 x 480 . Причем сделать это не только для существующих постов, но и тех, которые подгрузятся далее. Делаем следующее
На 27 и 29 строчке мы делаем переменные со значениями, которое будем менять местами.
С 30 по 35 строчку у нас функция, которая перебирает регулярным выражением все значения путей к картинкам <img src= во всех фото с классом .PostSummary_image
На 36 строчке мы запускаем функцию. Это происходит только один раз. И проблема будет в том, что когда подгрузим новые посты, функция их не обработает, так как раньше их не было на странице.
Решаем проблему тем, что с 39 по 41 строчку мы заставляем срабатывать функцию каждый раз, когда происходит динамическое добавление любого контента в страницу, это событие выглядит как DOMNodeInserted . Теперь у нас обновляются фото не только в существующих постах, но и в тех, которые будут добавлены бесконечным скроллингом.
Создаем нашу самую большую функцию waitfor, которая будет выполняться рекурсивно
Получаем небходимые параметры для виджета "ответы" и возможности управлять стилями в аккаунте голоса. А так же добавить неограниченное число настроек в будущем!Пожалуй самый интересный костыль кусок кода
Как все работает на практике.
В видеоролике были примеры того, как работают настройки в аккаунте, ниже я опишу как пользователь сможет пользоваться параметрами на голосе.
Идея в том, что бы юзер мог прописать свои настройки где-то у себя в аккаунте , но настроек в аккаунте всего несколько.
Язык и валюта не подойдет, а вот строка со ссылкой на аватарку. Хм, да в ней можно устроить Лас Вегас :)
Дело в том, что если мы добавим в конце любого url (ссылки) знак вопроса, то это не повлияет на адрес сайта или фотографии, однако ссылка будет содержать параметры. Это часто используют партнерки для определения id партнера.
Но мы используем это для хранения произвольных параметров!
Магия происходит на строках 56-66, где мы считываем параметры, которые указаны после значка ? в нашей ссылке на юзерпик - аватар.
Например мы добавляем в конце
Далее на все тех же 56-66 строчках мы получим и отфильтруем все, что после ?
Отфильтруем таким образом, что из полученной строки мы сделаем набор опций похожих на это:
- параметр1=значение
- параметр2=значение
- параметр3=значение
- параметр4=значение
Далее в скрипте мы сможем применять их как угодно, например как переключатель, как в случае с топиками topics=OFF - таким же методом можно будет отключить любой элемент на сайте. Значение может быть не только OFF и служить не только как переключатель. В случае с ?css=[#content] мы сделаем следующее:
Получим все что после css= и перед ближайшим & . Затем в скрипте мы укажем, что весь этот стиль должен быть применен, тогда пользователь редактируя свою ссылку аватара сможет сделать голос другого цвета, размера, вида. Например, если вам на работе не разрешают зависать в соцсетях - вы сможете стилизовать голос под вид своей рабочей программы и не палиться перед начальством, продолжая постить мемасики и котиков)
Итак, мы получили и отфильтровали параметры после ссылки, но задействуем и обработаем мы их позднее, так как у нас есть проблема:
Пришлось немного помучатся, так как проблема взаимодействия скина с голосом была в том, что голос на react и большинство контента появляется не сразу, а динамически. Мне нужно было как-то получить ссылку на страницу ответов текущего пользователя и ссылку на аватарку текущего пользователя.
С 45 поооооо 150 строку у нас будет функция waitfor , которая будет содержать в себе много других функций описанных ниже. Вызвана она будет только потом на 151 строке, а затем будет рекурсивно вызываться внутри самой себя до тех пор, пока ваш аватар не появится. Учтите, что весь код ниже выполняется внутри нее:
47 и 48 строчка это переменные с двумя значениями - первая переменная хранит в себе html класс аватарки, которая еще не появилась. Вторая переменная хранит в себе ссылку на аватар.
Переменная на строке 51 хранит в себе ссылку на профиль пользователя, которую мы возьмем с ссылки в которую обвернут аватар. Это ссылка есть родительский элемент аватара и потому используем .parent().attr('href'); что бы получить атрибут href у ссылки.
Но на старте загрузки эти переменные ничего не хранят, так как эти элементы еще не подгрузились. Решаем мы эту проблему позже, а пока создадим еще одну интересную функцию на строках 56-66, которая поможет нам сделать возможность пользователю самому настраивать свой голос.
С помощью регулярного выражения и перебора строки мы фильтруем все лишнее в ссылке на аватар и получаем только значения после знака ? Но мы не вызываем пока эту функцию, пока еще рано, так как необходимые параметры еще не загрузились в наши переменные. Мы еще вернемся к этой функции, а пока создадим еще одну:
С 68 по 70 строку у нас функция ajax загрузки ваших ответов
Подробно о виджете ответов
Ответы загружает строка:
$('.answertarget').load('/usernameUrl + '/recent-replies/ #posts_list');
Работает это так: в html элемент div который мы создали в самом начале с классом answertarget мы загружаем (.load) содержимое страницы, ссылка на которую выглядит как:
Добавляем к ссылке имя из переменной usernameUrl и прибавляем значком + путь к ответам
@ ваше_имя/recent-replies/ так как мы будем вставлять в виджет не всю страницу, а только поле ответов, которое обернуто в id #posts_list , то в конце ссылке укажем этот id.
Вот так вот одной строчкой мы добиваемся появления ответов там, где нам хочется
NB: Вы можете указать любую ссылку в рамках домена golos.io вместо
/usernameUrl + '/recent-replies/ #posts_list
И тогда в виджет будет загружать контент с той страницы, которую вы укажете. Например для ваших комментариев укажите
/usernameUrl + '/posts/ #posts_list
Или замените переменную /usernameUrl + на ник любого пользователя и читайте его ответы, а не свои. Например, что бы читать мои:
Разбираем скрин дальше.
Определяем, когда страница готова к нашим действиям
На 72 строке начинается наше главное условие if (Upic.length)