Вы ненавидите репутацию? Нажмите здесь, чтобы избавиться от него

Су ... Недавно я прочитал мета-сообщение о неотъемлемых проблемах репутации. В нем перечислены такие вещи, как:

  • Подтверждение смещения.
  • Demotivating для пользователей с низким уровнем репутаций.
  • Hubris и элитарность высокопоставленных пользователей по сравнению с пользователями с низким уровнем репутаций.
  • Неправильное представление компетенции.
  • ...

Поэтому я подумал про себя: «Как могла бы быть сеть, без репутации?»

Я схватил инспектора, проверил вопросы, мою страницу профиля и активную страницу, и как отображается репутация.

Затем я быстро взломал следующий небольшой пользовательский скрипт (ECMA6) для Greasemonkey, который скрывал бы всю репутацию от вида:

// ==UserScript==
// @name         Reputation Hider
// @namespace    http://gihub.com/Vogel612/ReputationHider
// @version      0.1
// @description  Hides all reputation displays from StackExchange sites
// @author       Vogel612
// @grant        none
// @include      /https?:\/\/(meta\.)?.*\.stackexchange\.com\/.*/
// @include      /https?:\/\/(stackoverflow|serverfault|superuser|askubuntu)\.com\/.*/
// ==/UserScript==
/* jshint -W097 */
'use strict';

let slice = function(collection) {
  return [].slice.call(collection);   
}

let repClasses = [ "rep", "reputation", "reputation-score" ];

let hideRepz = function() {
  repClasses.forEach(clazz => 
    slice(document.getElementsByClassName(clazz))
      .forEach(el => { 
        // this results in minor inconsistencies in CSS, but alas
        el.style.visibility = 'hidden';
      })
    );
}

hideRepz();
// add event listener for live-updates
document.addEventListener("DOMNodeInserted", hideRepz);

Это уже давно работает для меня, и мне нравится говорить, что это освежающее изменение. Это в стороне:

Он скрывает все номера репутации на странице. Если вам интересно, вы все равно можете их найти. Также он выглядит забавным в /questions, когда активные таймеры outdented по-разному, но это только мой OCD сходит с ума. Он также проверяет новые вопросы, которые вы загружаете по уведомлению.

Что я могу сделать лучше в этом usercript?

67 голосов | спросил Vogel612 15 FebruaryEurope/MoscowbMon, 15 Feb 2016 16:33:30 +0300000000pmMon, 15 Feb 2016 16:33:30 +030016 2016, 16:33:30

6 ответов


42

Было бы лучше сделать это с помощью стиля пользователя , например используя расширение Стильное , например:

 .rep, .reputation, .reputation-score {
    visibility: hidden;
}

Одно из преимуществ пользовательских стилей над сценариями заключается в том, что они применяются, как только страница начинает загружаться, поэтому вы не увидите кратковременное замедление количества повторений во время загрузки страницы. Кроме того, стили пользователей будут автоматически применяться также к новому динамическому содержимому, загруженному, например. через Ajax (например, новые ответы, отправленные во время просмотра страницы).

Если вы настаиваете на использовании пользовательского сценария , возможно, он будет эмулировать стили пользователей, используя @run-at document-start и вводить элемент

 style

Я использую этот метод в своем Неофициальном патче стека (SOUP) пользовательский скрипт (который сочетает в себе кучу более или менее небольших исправлений и улучшений интерфейса), чтобы я мог эффективно применять CSS-only и JS-tweaks из одного пользовательского скрипта.

Следует отметить одну деталь: стили, введенные таким образом, обычно включаются до в любые фактические таблицы стилей сайта на странице, что означает, что они будут переопределены селекторами CSS сайта с одинаковой специфичностью , В некоторых случаях вам может понадобиться использовать // ==UserScript== // @name Hide Stack Exchange reputation (demo) // @namespace http://vyznev.net/ // @description A demonstration of using style injection to emulate user styles // @author Ilmari Karonen // @version 1.0 // @license Public domain // @match *://*.stackexchange.com/* // @match *://*.stackoverflow.com/* // @match *://*.superuser.com/* // @match *://*.serverfault.com/* // @match *://*.stackapps.com/* // @match *://*.mathoverflow.net/* // @match *://*.askubuntu.com/* // @homepageURL http://codereview.stackexchange.com/a/120100 // @grant none // @run-at document-start // ==/UserScript== var css = ".rep, .reputation, .reputation-score {\n" + " visibility: hidden;\n" + "}\n"; var style = document.createElement('style'); style.textContent = css; (document.head || document.documentElement).appendChild(style); и /или различные специфические хаки , чтобы убедиться, что ваши пользовательские стили будут иметь приоритет.

ответил Ilmari Karonen 16 FebruaryEurope/MoscowbTue, 16 Feb 2016 03:48:07 +0300000000amTue, 16 Feb 2016 03:48:07 +030016 2016, 03:48:07
27

Вы можете использовать querySelectorAll вместо getElementsByClassName. Таким образом, вы обладаете большей гибкостью в элементах таргетинга. Он также позволяет несколько селекторов. Таким образом, вам не нужно дважды зацикливаться.

Вместо [].slice, который использует ненужный массив как хост, попробуйте вместо этого использовать Array.prototype.slice.call. Дольше, но без этого дополнительного массива.

Кроме того, попробуйте использовать display:none, поскольку видимость просто скрывает элемент, но поддерживает макет. Таким образом, нет неловкого пробела, где была репутация, делая макет естественным.

Увидев, что вы положили ES6, мы также можем использовать удобные функции стрелок dandy.

'use strict';

const REPUTATION_ELEMENTS = '.rep, .reputation, .reputation-score';

function getElementArray(selector){
  return Array.prototype.slice.call(document.querySelectorAll(selector));
}

document.addEventListener("DOMNodeInserted", event => {
  getElementArray(REPUTATION_ELEMENTS).forEach( element => {
    element.style.display = 'none';
  });
});
ответил Joseph 15 FebruaryEurope/MoscowbMon, 15 Feb 2016 17:15:30 +0300000000pmMon, 15 Feb 2016 17:15:30 +030016 2016, 17:15:30
15

Обновить URL

UserScripts обладают магической способностью обновлять себя, если вы предоставляете ссылку на исходную версию своего скрипта в качестве заголовка UserScript:

Примечание. Фактически вам нужно увеличить версию, или она не будет обновляться.

// ==UserScript==
// @name         Reputation Hider
// @namespace    http://gihub.com/Vogel612/ReputationHider
// @version      0.1
// @downloadURL
// @updateURL

Метод

Я не являюсь поклонником вашего метода.

Проверка обновлений DOM перед повторным просмотром всего.

Было бы разумнее просто вставить таблицу стилей, чтобы переопределить таблицы стилей SE.

Гораздо больше труда.


Функции ES6

Мне нравится использование ES6 в вашем коде, но вы не использовали его в полном объеме:

let slice = function(collection) {
  return [].slice.call(collection);   
}

Вместо использования старой function(collection){}, вы можете использовать (collection) => ():

let slice = (collection) => [].slice.call(collection)

То же самое относится к функции в вашем основном цикле.


Нарезка и нарезка

В настоящее время вы используете только slice с вашим выбором элемента.
Вы должны объединить два!

slice(document.getElementsByClassName(clazz))
let fetchElements(clazz) => [].slice.call(document.getElementsByClassName(clazz))

Или, эй, давайте сделаем еще один шаг и сделаем магию конкатенации:

let fetchElements = (clazzArrey) =>
    clazzArrey.map((clazz) => [].slice.call(document.getElementsByClassName(clazz)))

В качестве альтернативы вы можете использовать конкатенацию строк, чтобы создать одну огромную селекторную строку и использовать querySelectorAll, как описано Джозефом.

Я нахожу, что querySelector* может иметь худшую производительность, но всегда были краевыми случаями, которые запускают это для меня.


Поддержка

В настоящее время очень мало браузеров полностью поддерживают ES6. Я не обязательно буду использовать его, если это необходимо. Вы не особенно хотите убить поддержку значительной части пользователей, используя ее.


Будущее глядя

Это, как правило, не является точкой обзора, но я думаю, что вы могли бы добавить поддержку для других полей и создать удобное диалоговое окно dandy, которое вы хотите скрыть. Это будет достойное создание StackApps в моих глазах.

ответил Quill 16 FebruaryEurope/MoscowbTue, 16 Feb 2016 01:39:58 +0300000000amTue, 16 Feb 2016 01:39:58 +030016 2016, 01:39:58
5

Вместо document.getElementsByClassName вы можете использовать document.querySelectorAll(CSS selector).

Изменить (Ответить на @ 200_success): Вы можете использовать любого из них. Просто я предпочитаю document.querySelectorAll, так как я думаю, что это лучше немного .

  1. document.getElementsByClassName имеет 31 букву, а document.querySelectorAll имеет 25 букв.
  2. document.querySelectorAll использует CSS для получения элементов DOM, но document.getElementsByClassName не работает.
  3. IE 8 + поддерживает document.querySelectorAll (IE 8 поддерживает только селектора CSS2), но document.getElementsByClassName предназначен для IE 9 + .

И вам не нужно создавать Array из DOMNodeList с помощью slice, так как DOMNodeList - это DOMNodeList -like. т. е. вы можете использовать его как Array, используя Array.

Array.prototype.forEach.call(DOMNodeList, callbackFunction)
ответил K._ 15 FebruaryEurope/MoscowbMon, 15 Feb 2016 23:03:39 +0300000000pmMon, 15 Feb 2016 23:03:39 +030016 2016, 23:03:39
4

Поскольку вы используете ES6, вы можете заменить функцию slice на Array.from , как это (изменение Джозефа тоже);

let hideRepz = function() {
  repClasses.forEach(clazz => 
    Array.from(document.querySelectorAll(`.${clazz}`))
      .forEach(el => { 
        el.style.display = 'none';
      })
    );
}
ответил Jivings 15 FebruaryEurope/MoscowbMon, 15 Feb 2016 18:57:18 +0300000000pmMon, 15 Feb 2016 18:57:18 +030016 2016, 18:57:18
3

Избегайте использования устаревших событий

События мутации (DOMNodeInserted) устарел , и вы должны использовать наблюдателей Mutation .

Использование образца:

function processNewNodes(topNode) {
    var nodes = topNode.querySelectorAll(selector);
    // ...
}

var observer = new MutationObserver(function(mutations, observer) {
    mutations.forEach(function(mutation) {
        Array.prototype.forEach.call(mutation.addedNodes, processNewNodes);
    });
});

observer.observe(document, {
    subtree: true,
    childList: true
});
ответил Bob 17 FebruaryEurope/MoscowbWed, 17 Feb 2016 02:53:43 +0300000000amWed, 17 Feb 2016 02:53:43 +030016 2016, 02:53:43

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132