Несколько дней назад статья Nuggets о вызове переднего плана была очень популярна, но десятки лайков и сотни комментариев показали, что эта статья не о качестве, а о полемике. Объективно говоря, вопрос в нем хороший, и он может помочь нам понять некоторые механизмы js. В комментариях автора неоднократно упоминалось о качестве статей в разделе front-end.Я хочу сказать, что мало того, что раздел front-end такой же, как и другие разделы, ни одно сообщество не может гарантировать, что все статьи являются высококачественными продуктами, но количество статей во фронтенд-разделе Nuggets относительно велико. , Эта проблема относительно очевидна, но у каждого читателя разный уровень. Вы думаете, что эта статья бесполезна, но она может быть очень полезным для других.
Так вроде многие в комментариях говорят, что надеются, что в Наггетс будет функция блокировки и блокировки, которая может заблокировать автора и заблокировать статью. Эта функция действительно может удовлетворить потребности многих людей в просмотре статей, но это не день и не два, чтобы призвать эту функцию, и у чиновника может быть свой план, который не был включен в график разработки. У меня на самом деле не было этого требования раньше, в лучшем случае я не хотел читать статьи с интервью, но после того, как эта статья вышла, я обнаружил, что у меня все еще есть необходимость блокировать, по крайней мере, эта статья не должна появляться в моем список рекомендуемых статей. Хотя я знаю, что официалы обязательно выпустят эту функцию в будущем, но жажду пока не решить, поэтому лучше разработать плагин самостоятельно для реализации этой функции.
Заявление о потребностях
- Добавляйте нелюбимых авторов в черный список и больше не отображайте статьи авторов из черного списка на главной странице и при поиске статей.
- Добавьте нелюбимые ключевые слова в черный список заголовков и больше не отображайте статьи с ключевыми словами в заголовке на главной странице и при поиске статей.
- Вы можете заблокировать авторов в любое время на странице сведений о статье.
- Черным списком можно управлять (добавлять и удалять).
Дисплей готовой продукции
Настоящим заявляется, что авторское затемнение предназначено только для демонстрации функции, а для эффекта он намеренно выбрал авторов высокого уровня с большим количеством колонок и не намерен оскорблять двух фотогеничных авторов.
Блокировка автора
Блокировка ключевого слова заголовка
Идеи схемы
Идея реализации на самом деле очень проста. Первое, что нужно уяснить, это то, что список статей Nuggets — это данные, запрашиваемые бэкендом. В будущем, когда эта функция будет официально реализована, бэкэнд может напрямую возвращать отфильтрованные результаты или его можно отфильтровать, когда интерфейс получит данные, обработать и отобразить снова. Для наших внешних плагинов такой возможности нет, и мы можем достичь своей цели, только скрыв сгенерированные элементы страницы.
Версия кода ввода консоли
Давайте начнем с самой простой реализации, фильтруя весь контент, содержащий ключевое слово «css», Сначала мы открываем панель отладки Chrome и смотрим на html-структуру списка статей на главной странице:
Все статьи, как показано на рис.liв виде этикетки, помещенной вclassдляentry-listизul, то что нам нужно сделать сейчас, это выбратьentry-listвсе подliпометить и найти содержимое внутри, если ключевое слово существуетcssпросто спрячь этоliЭтикетка.
//$$是大部分浏览器调试控制台都支持的API,等价于document.querySelectorAll,平时开发不能用。
$$('.entry-list>li').forEach(item => {
//innerText是一个节点及其后代的“渲染”文本内容,判断里面是否包含css,不区分大小写。
if (/css/i.test(item.innerText)) {
//符合要求的元素隐藏
item.hidden = true;
}
});
Введите этот код в консоль, и вы обнаружите, что записи, содержащие ключевые слова css в списке статей (это не только заголовок) скрыты.
Однако статья, загруженная после того, как полоса прокрутки сдвинется вниз, все равно будет отображаться, и если вы хотите скрыть ее, вы можете только снова запустить код в консоли.
Версия сценария масляной обезьяны
То, что мы хотим сделать, это полный плагин вместо ручного ввода кода в консоли, как указано выше, хотя вы можете написать полный код плагина для запуска консоли, функциональный эффект на самом деле такой же, но он не долгосрочное решение в конце концов.
Сначала мы можем превратить эту функцию в плагин для браузера, например, на основе спецификаций Chrome и API, установить разработку проекта и, наконец, упаковать в файл формата CRX, браузер Chrome может установить этот плагин локально или потратить деньги, чтобы стать разработчиками Google Опубликовано в Google Магазин приложений.
Преимущество подключаемого модуля браузера заключается в том, что можно вызывать больше API-интерфейсов на уровне браузера, используя браузер в качестве соответствующих функций, предоставляемых собственным подключаемым модулем, но для нас, чтобы предоставить небольшую функцию, предоставляемую веб-сайтом, некоторые куры-убийцы имеют нож для крупного рогатого скота, и этот плагин предназначен только для Chrome, если другие браузеры хотят развиваться, например, Firefox использует расширение формата XPI.
Лучший способ - использоватьTampermonkey.
Tampermonkey (внутреннее название oil monkey) — это плагин для браузера, самый популярный менеджер пользовательских скриптов, и есть соответствующие версии в Chrome, Microsoft Edge, Safari, Opera Next и Firefox, то есть мы пишем Скрипт можно запускать в различных браузерах через него. Сегодня мы реализуем наши функции в виде скриптов масляных обезьян.
Друзья, которых больше интересует разработка плагинов для браузера, рекомендуют эту статью:[Галантные товары] Стратегия развития плагина (расширения) Chrome
Реализация схемы
Установить Тампермонки
Установка Tampermonkey проста и проста.Это не просто и не просто.Просто то,что Tampermonkey входит в официальный маркет плагинов различных браузеров.Его легко найти и скачать,и он не ограничивается теми браузеры, упомянутые выше.Некоторые мобильные браузеры также поддерживаются, и хотя официальный сайт Tampermonkey не написан, есть также некоторые внутренние рынки подключаемых модулей браузера, такие как браузер со скоростью 360 и браузер Sogou. Причина не проста, то есть рынок плагинов некоторых браузеров нам не так просто получить.
Если на самом деле нет рынка плагинов для браузера, пока это ядро Chromium, оно обычно поддерживает локальную установку crx.
После завершения установки мы можем щелкнуть значок плагина oil monkey в браузере, и мы сможем просматривать, открывать, удалять и управлять нашими скриптами в панели управления.
Создать файл сценария
Если мы хотим разработать свои собственные сценарии, мы можем открыть страницу сценариев, выбрав добавить новый сценарий, но рекомендуется писать их в нашем собственном редакторе.Удобнее иметь подсказки и форматирование.
Созданный скрипт по умолчанию имеет некоторые коды, как показано ниже, то есть шапка похожа на комментарий.Приведем краткое описание того, что здесь используется.Для получения дополнительной информации см.официальная документация.
// ==UserScript==
// @name 掘金文章黑名单 <-插件名,会显示在管理面板里
// @namespace https://github.com/hoc2019/blackList <-脚本命名空间
// @version 0.1 <-版本号
// @description 掘金文章黑名单过滤脚本 <-描述
// @author wangzy <-作者
// @match https://juejin.im/* <-只有匹配到的网站才会使用该脚本
// @require https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js <-引入脚本,这里用了jQuery
// @grant GM_addStyle <-给网站注入css样式的方法
// ==/UserScript==
(function() {
'use strict';
// Your code here...
})();
Фильтрация списка статей — MutationObserver отслеживает изменения узла dom
Фильтрация и скрытие списка статей аналогичны приведенной выше версии кода ввода консоли, основное внимание уделяется времени запуска операции скрытия. Из-за асинхронного запроса данных, если будет слишком рано, dom-узел списка статей не будет создан, и операция фильтрации завершится неудачно, а если слишком поздно, то список будет виден невооруженным глазом.
Простой и грубый способ — написать опрос, чтобы непрерывно определять, существует ли узел dom списка статей, если он существует, значит, статья загружена и можно выполнять операцию фильтрации. Таким же образом прокрутите вниз, чтобы загрузить статью, и вы также можете запустить операцию фильтрации, опросив, чтобы определить, изменяется ли количество узлов DOM в списке статей (конечно, вы также можете обнаружить событие колеса прокрутки). . Однако опрос сам по себе является методом поиска баланса между производительностью и опытом. Если интервал опроса короткий, оценка будет точной, а опыт будет хорошим, но он будет потреблять много производительности. В противном случае производительность будет низкой. хорошо, а опыт будет плохим.
Итак, здесь мы используем MutationObserver.MutationObserver можно использовать для отслеживания изменений узлов DOM.Это замена старой функции Mutation Events.Подробности см. в MDN.Документация.
Примерное использование выглядит следующим образом:
const container = $('#juejin');
const config = {
attributes: false, // 检测节点属性变化,这里用不到,为减少不必要的触发这里不用开启
childList: true, // 检测子节点添加和删除
subtree: true // 检测包含后代节点
};
const mutationCallback = mutationsList => {
for (let mutation of mutationsList) {
const type = mutation.type;
const addedNodes = mutation.addedNodes; //增加节点数组
// 会根据上面的的设置触发相应事件,这里可以判断触发的事件类型
switch (type) {
case 'childList':
//因为我们是要判断列表加载,只用处理节点增加时的事件即可
if (addedNodes.length > 0) {
list = $('.entry-list');
if (list.children().length) {
//停止观察
loadObserver.disconnect();
//过滤操作
filter(list.children());
//创建滚动后加载观察
createNodeListener(list[0], config, updateLoad);
}
}
break;
}
}
};
//创建首次加载观察
const loadObserver = createNodeListener(container[0], config, handleLoad);
//定义一个创建观察者的工厂函数,方便创建观察者。
function createNodeListener(node, config, mutationCallback) {
const observer = new MutationObserver(mutationCallback);
observer.observe(node, config);
return observer;
}
Потому что он обрабатывается каждый раз при изменении узла списка статей, отклик очень своевременный, и маловероятно, что запись сначала отобразится, а потом исчезнет, и он пассивно срабатывает, и это не похоже на опрос, фон постоянно получение информации об узле запроса DOM.
Здесь может возникнуть вопрос, почему новое наблюдение нужно пересоздавать в середине, ведь исходное наблюдение основано на контейнере очень верхнего уровня (узел div с id juejin, только он есть в начале), какой-то другой DOM изменения узла за пределами списка статей также вызовут события, поэтому, когда мы получаем контейнер списка статей (ul, чей класс — entry-list), мы перестаем наблюдать за контейнером верхнего уровня и наблюдаем только за контейнером списка статей, так что мы может точно реагировать только на Изменения в узле списка статей.
通过MutationObserver构造函数创建完观察者后不会立即启动观察,需要通过观察者者调用observe方法,需要注意的是observe方法的第一个参数必须是DOM Node (可能是一个Element) ,通过jQuery获取的节点要转化为原生dom节点,例如$('#juejin')[0]这样。
Хранение данных в черном списке — доступ к данным localStorage
Данные черного списка хранятся в localStorage, что позволяет сохранять данные в течение длительного времени, даже если страница закрыта.Подробности см. в MDN.Документация.
Метод использования очень прост, но следует отметить, что localStorage может хранить только строки, если вы хотите сохранить массивы и объекты, вам нужно сделать сериализацию и преобразовать их в строки json.
//存储
const authorBlackList = ['小四', '小五'];
localStorage.setItem('authorBlackList', JSON.stringify(authorBlackList));
//读取
const authorBlackList = JSON.parse(localStorage.getItem('authorBlackList'));
Сохраненные данные можно просмотреть, открыв панель приложений отладки браузера.Поскольку браузер сохраняется локально, а localStorage очищается, данные будут очищены, и данные не могут быть разделены между браузерами.Хранение на стороне сервера требует затрат, что еще осталось официалам.Давайте сделаем это.
Боковая панель управления черным списком
Это также относительно легко реализовать, просто напишите html, создайте узел с помощью jQuery и вставьте его на страницу, а если стиль CSS должен быть вставлен с помощью метода GM_addStyle, предоставляемого скриптом oil monkey, как упоминалось ранее.
Вероятно, что-то вроде этого:
//css样式
const myScriptStyle ='.black-sidebar{background:#000}'
GM_addStyle(myScriptStyle);
//html结构
const sidebarHtml = '<div class="black-sidebar"><ul><ul></div>';
$('body').append($(sidebarHtml));
Моменты, которые могут быть уникальными, заключаются в том, что черный список на боковой панели должен быть динамически добавлен позже, поэтому щелчок по событию не может быть привязан напрямую через метод jQuery Click.liНа этикетке, но привязать к родителю через метод наulВыше это то же самое, что делегирование события. Тем не менее, это точки использования jQuery, я не знаю, будут ли его использовать новые друзья.
Синхронизация данных боковой панели на разных страницах — прослушиватель событий visibilitychange
Боковая панель управления черным списком создается с самого начала.Хотя работа текущей страницы будет обновлена на боковой панели, мы обычно открываем несколько страниц в процессе просмотра, так как же поддерживать боковую панель на нескольких страницах?синхронизация данных? Очевидно, что управлять домом через вкладки браузера нереально, но мы можем отслеживать переключение вкладки и при отображении вкладки повторно получать данные и обновлять список.
Мы отслеживаем его с помощью события visibilitychange. Подробную информацию об этом событии см. в MDN.Документация.
document.addEventListener('visibilitychange', function() {
if (document.visibilityState === 'visible') {
// 更新侧边栏数据
updateSidebarList();
if (pathname === 'post') {
//如果是详情页,更新拉黑按钮状态
updateBtnState();
}
}
});
Эффект следующий:
上面document.visibilityState是只读属性表示标签页状态,visible表示显示,还有hidden表示隐藏。所以通过该方法还可以检测到标签页的隐藏,移动端浏览器切换到后台s,媒体声音还在继续播放的问题,可以通过这个事件手动暂停解决。
Кнопка затемнения страницы сведений о статье
Это тоже очень просто, но я наткнулся на интересное место, когда делал это: я изначально хотел создать элемент, такой же, как кнопка поделиться выше, и добавить то же имя класса, но селектор класса в стиле Самородки также. С данными data-v-xxx (функция с ограниченной областью, используемая vue для предотвращения загрязнения стиля CSS), я просто клонировал узел кнопки «Поделиться», а затем изменил содержимое.
наконец
Основные функции этого плагина выполнены, но так как цель разработки для личного пользования, совместимость не рассматривается, и нет теста в различных ситуациях, просто запускаем и пользуемся.
На самом деле, есть еще много моментов, которые можно оптимизировать, например, после добавления и удаления черного списка необходимо обновить страницу, чтобы она вступила в силу, некоторые DOM-операции можно сократить, а код дополнительно абстрагировать и инкапсулировать. объектно-ориентированный и так далее. Так что цель данной статьи не в продвижении этого плагина, а просто в том, чтобы поделиться процессом разработки скрипта и идеями решения некоторых задач в нем.Достаточно вызвать у некоторых людей интерес к разработке скрипта.Это тоже эта серия.Цель статьи.
Я выложу код этого скрипта на гитхаб, вы можете использовать его, если вам это нужно, и скрипт также был помещен вGreasyForkРынок скриптов, самородки могут искать статьи в черном списке, но есть небольшие последующие обновления программы, ремонт ошибок, обслуживание общих интересов, может участвовать, прежде чем официальное из этой функции, мы собственными руками и одеждой.