Стилизация JoyReactor по своему вкусу (больше текс и темная тема)
Мне часто с телефона неудобно читать лонгриды. А режим читалки в моем браузере обычно считает комментарии постом 0_о. В общем мучался некоторое время, а потом вспомнил про букмарклеты – отличная альтернатива для телефонов расширениям на десктопе. А теперь вот решил, мало ли, вдруг кому-то тоже что-то сильно хочется поменять на джое (или любом другом сайте), а возможности никак не видится.
Вообще букмарклет – это такой небольшой обман, это добавленная в закладки ссылка, которая на самом деле является командой браузеру выполнить код на открытой странице. Сами ссылки-команды используют сайты довольно часто (например, в стиме кнопка "купить" – как раз такая псевдо-ссылка), хотя сейчас все реже. А букмарклеты когда-то давно были альтернативой расширениям. Вы и сейчас можете найти огромные библиотеки полезных и не очень букмарклетов (что-то вроде музеев интернета 00-х =)).
И так, первый мой букмарклет был таким:
javascript:void(document.head.insertAdjacentHTML('beforeend', '<style>.post_content p { font-size: 35px; line-height: normal;} .post_content h3 { font-size: 45px; line-height: normal;}</style>'))
Нажмите по этой ссылке и увидите, что он делает. А может и не увидите, если здесь ссылки работают через редирект, как пост появится – узнаем. В таком случае нужно скопировать его текст и создать закладку с этой ссылкой. А затем, находясь на странице джоя, в адресной строке начать набирать название созданной закладки и нажать по ней в предложке. Размер текста должен измениться. Но только на этой странице и до ее перезагрузки.
Он очень простой, просто изменяет немного стили увеличивая абзацы и заголовки постов.
Но, как я уже писал выше, его недостаток в том, что он "нестабилен". Хотелось бы, чтобы изменения сохранялись даже после перехода на следующую страницу. Это уже посложнее, но если особо не заботиться о работе ВСЕХ функций. Тоже довольно небольшой код.
А еще, думаю многим может хотеться добавить темную тему, это не сложно с букмарклетами. Весь фокус в создании достаточно умного фильтра "переворачивающего" цвета. Вообще, этот фильтр достаточно интересен и часто удобен, хотя о нем почему-то многие веберы не знают (работает изначально переводя rgb в hsb). Единственная проблема, фильтры – довольно ресурсоемкие и не все телефоны нормально переваривают обилие фильтров. Так что осторожнее, скролл страницы может стать менее плавным или еще чего-то.
javascript:void((() => {
let svg = `<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="position: absolute;top: 0;z-index: -100;"><defs><filter id="invertColors" x="0%" y="0%" width="100%" height="100%" style="color-interpolation-filters: sRGB"><feColorMatrix result="red" in="SourceGraphic" type="matrix" values=" 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1"/> <feColorMatrix result="green" in="SourceGraphic" type="matrix" values=" 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1"/> <feColorMatrix result="blue" in="SourceGraphic" type="matrix" values=" 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1"/> <feBlend result="minredgreen" in="red" in2="green" mode="darken"/> <feBlend result="min" in="minredgreen" in2="blue" mode="darken"/> <feBlend result="maxredgreen" in="red" in2="green" mode="lighten"/> <feBlend result="max" in="maxredgreen" in2="blue" mode="lighten"/> <feComponentTransfer result="oneminusmin" in="min"> <feFuncR type="linear" intercept="1" slope="-1"/> <feFuncG type="linear" intercept="1" slope="-1"/> <feFuncB type="linear" intercept="1" slope="-1"/> </feComponentTransfer> <feComposite result="aminusmin" operator="arithmetic" in="SourceGraphic" in2="oneminusmin" k1="0" k2="1" k3="1" k4="-1"/> <feComposite result="colorresult" operator="arithmetic" in="aminusmin" in2="max" k1="0" k2="1" k3="-1" k4="1"/> <feComposite operator="in" in="colorresult" in2="SourceAlpha"/> </filter> </defs> </svg>`; let style = "<style>.post_content p { font-size: 35px; line-height: normal;} .post_content h3 { font-size: 45px; line-height: normal;} body, img, video, iframe {filter: url(#invertColors);} </style>";
document.head.insertAdjacentHTML('beforeend', style); document.body.insertAdjacentHTML('beforeend', svg);
async function loadPage(href, isNotToScroll){ if (!href) href = location.href; let url = new URL(href);
try { const response = await fetch(url, { credentials: 'same-origin' }); if (!response.ok) throw new Error('Ответ сети был не ok.');
const text = await response.text(); let body = text.match(/<body>(.*)<\/body>/is)[1]; if (!body) { location.href = href; throw new Error('No HTML to display!'); }
document.body.innerHTML = body + svg; if (!isNotToScroll) window.scroll(0, 0); }
catch (error) { console.error('Ошибка:', error); } }
document.addEventListener('click', (e)=>{ for (let el of e.path) { if (el instanceof HTMLAnchorElement && el.href.startsWith(location.origin)) { if (el.getAttribute("href").startsWith('#')) break; e.preventDefault(); console.log(history); history.pushState({}, el.href, el.href); loadPage(el.href); return; } } });
window.onpopstate = () => {loadPage(null, true)}; })())
Да, вот это все выше это может быть ссылкой, но создать ее в статье я не могу (похоже в редакторе есть ограничение длины ссылки) `; let style = ""; document.head.insertAdjacentHTML('beforeend', style); document.body.insertAdjacentHTML('beforeend', svg); async function loadPage(href, isNotToScroll){ if (!href) href = location.href; let url = new URL(href); try { const response = await fetch(url, { credentials: 'same-origin' }); if (!response.ok) throw new Error('Ответ сети был не ok.'); const text = await response.text(); let body = text.match(/(.*)<\/body>/is)[1]; if (!body) { location.href = href; throw new Error('No HTML to display!'); } document.body.innerHTML = body + svg; if (!isNotToScroll) window.scroll(0, 0); } catch (error) { console.error('Ошибка:', error); } } document.addEventListener('click', (e)=>{ for (let el of e.path) { if (el instanceof HTMLAnchorElement && el.href.startsWith(location.origin)) { if (el.getAttribute("href").startsWith('#')) break; e.preventDefault(); console.log(history); history.pushState({}, el.href, el.href); loadPage(el.href); return; } } }); window.onpopstate = () => {loadPage(null, true)}; })())">ссылкой Но `; let style = ""; document.head.insertAdjacentHTML('beforeend', style); document.body.insertAdjacentHTML('beforeend', svg); async function loadPage(href, isNotToScroll){ if (!href) href = location.href; let url = new URL(href); try { const response = await fetch(url, { credentials: 'same-origin' }); if (!response.ok) throw new Error('Ответ сети был не ok.'); const text = await response.text(); let body = text.match(/(.*)<\/body>/is)[1]; if (!body) { location.href = href; throw new Error('No HTML to display!'); } document.body.innerHTML = body + svg; if (!isNotToScroll) window.scroll(0, 0); } catch (error) { console.error('Ошибка:', error); } } document.addEventListener('click', (e)=>{ for (let el of e.path) { if (el instanceof HTMLAnchorElement && el.href.startsWith(location.origin)) { if (el.getAttribute("href").startsWith('#')) break; e.preventDefault(); console.log(history); history.pushState({}, el.href, el.href); loadPage(el.href); return; } } }); window.onpopstate = () => {loadPage(null, true)}; })())">ссылка. Но в браузере это работает (создать такую закладку).
В общем, надеюсь кому-то это будет полезным =)
`; let style = ""; document.head.insertAdjacentHTML('beforeend', style); document.body.insertAdjacentHTML('beforeend', svg); async function loadPage(href, isNotToScroll){ if (!href) href = location.href; let url = new URL(href); try { const response = await fetch(url, { credentials: 'same-origin' }); if (!response.ok) throw new Error('Ответ сети был не ok.'); const text = await response.text(); let body = text.match(/(.*)<\/body>/is)[1]; if (!body) { location.href = href; throw new Error('No HTML to display!'); } document.body.innerHTML = body + svg; if (!isNotToScroll) window.scroll(0, 0); } catch (error) { console.error('Ошибка:', error); } } document.addEventListener('click', (e)=>{ for (let el of e.path) { if (el instanceof HTMLAnchorElement && el.href.startsWith(location.origin)) { if (el.getAttribute("href").startsWith('#')) break; e.preventDefault(); console.log(history); history.pushState({}, el.href, el.href); loadPage(el.href); return; } } }); window.onpopstate = () => {loadPage(null, true)}; })())">ссылкаывавыавыавыаваы. И она делает темную тему и увеличивает шрифты, даже после перехода на другую страницу внутри ДжойРеактора и даже при возвращении обратно в истории. Здесь с читаемостью правда немного проблемы, но не знаю как лучше оформить лучше(
`; let style = ""; document.head.insertAdjacentHTML('beforeend', style); document.body.insertAdjacentHTML('beforeend', svg); async function loadPage(href, isNotToScroll){ if (!href) href = location.href; let url = new URL(href); try { const response = await fetch(url, { credentials: 'same-origin' }); if (!response.ok) throw new Error('Ответ сети был не ok.'); const text = await response.text(); let body = text.match(/(.*)<\/body>/is)[1]; if (!body) { location.href = href; throw new Error('No HTML to display!'); } document.body.innerHTML = body + svg; if (!isNotToScroll) window.scroll(0, 0); } catch (error) { console.error('Ошибка:', error); } } document.addEventListener('click', (e)=>{ for (let el of e.path) { if (el instanceof HTMLAnchorElement && el.href.startsWith(location.origin)) { if (el.getAttribute("href").startsWith('#')) break; e.preventDefault(); console.log(history); history.pushState({}, el.href, el.href); loadPage(el.href); return; } } }); window.onpopstate = () => {loadPage(null, true)}; })())">ссылкаывавыавыавыаваы. И она делает темную тему и увеличивает шрифты, даже после перехода на другую страницу внутри ДжойРеактора и даже при возвращении обратно в истории. Здесь с читаемостью правда немного проблемы, но не знаю как лучше оформить лучше(