В этой статье рассмотрим аспекты работы с таким довольно популярным расширением для Firefox, как Greasemonkey. А именно: зачем нужен Greasemonkey, как его установить, как написать скрипт, где найти готовые скрипты и т.п.

1. Зачем нужен Greasemonkey?

Greasemonkey - это расширение, изначально написанное для браузера Mozilla Firefox, которое позволяет выполнять пользовательский JavaScript-код на любых веб-страницах. То есть пользователь может добавить свой собственный JavaScript, который запуститься вместе с теми скриптами, которые уже есть на сайте. Greasemonkey может понадобиться для многих целей, одна из них - добавление нового функционала, который не предусмотрен самим сайтом. В этой статье будет продемонстрирован пример расширение функционала сайта комиксов http://fffuuu.ru.

2. Как установить Greasemonkey и создать скрипт?

Для этого необходимо зайти на страницу расширения и установить его через кнопку «Добавить в Firefox». После перезапуска браузера появиться иконка расширения в виде улыбающейся мартышки в правом верхнем углу.

Greasemonkey иконка

Для создания скрипта можно использовать выпадающее меню этой кнопки, затем пункт «Создать скрипт». Вводим имя скрипта, описание (если требуется). Также необходимо ввести пространство имён. Насколько я понял, это поле имеет значение, если Вы захотите поделиться Вашими скриптами с сообществом. Обычно туда пишут адрес сайта автора (для того, чтобы программа различала 2 скрипта, если имена их совпадут). Если Вы пишите скрипт для себя, введите туда любую строку.

Также необходимо задать поле «Включение». Оно содержит список страниц, на которых будет выполняться Ваш скрипт. Если оставить это поле пустым, то скрипт будет действовать везде. Давайте перейдём к реальному примеру и предположим, что я хочу добавить какой либо скрипт на сайт комиксов fffuuu.ru. Адрес каждого комикса на этом сайте имеет вид «http://fffuuu.ru/show/324679», где последние цифры - это номер комикса. И я хочу, чтобы мой скрипт запускался только на странице с комиксом (и не запускался, например, на главной). Поэтому я напишу в поле «Включение» следующую строку: «http://fffuuu.ru/show/*». Звёздочка будет задавать шаблон, вместо которого может быть любые символы в любом количестве.

При первом создании скрипта программа предложит выбрать внешний редактор, который будет использоваться для написания скриптов. Если Вы не используете такой, можно выбрать обычный Блокнот. Я использую NetBeans. В любом случае, перед нами отобразиться наш редактор из заготовкой нашего скрипта. У меня она будет иметь вид:

// ==UserScript==
// @name           fffuuu
// @namespace      http://softlakecity.ru
// @include        http://fffuuu.ru/show/*
// ==/UserScript==

3. Написание скриптов Greasemonkey и управление ими

Ну, собственно, можно и начать писать скрипт. Хотя Greasemonkey - это просто средство запуска скриптов, а не язык программирования, «hello world» на Greasemonkey будет иметь вид:

// ==UserScript==
// @name           fffuuu
// @namespace      http://softlakecity.ru
// @include        http://fffuuu.ru/show/*
// ==/UserScript==
alert('hello, world!');

Наш скрипт будет выводить сообщение 'hello, world!' на страницах, указанных в директиве @include.

Управление написанными скриптами происходит в окне «Дополнения» Mozilla Firefox, там появляется новая вкладка «Пользовательские скрипты», через которую можно включать, отключать, удалять и редактировать их.

4. Как можно получить доступ к функции или переменной, которая уже есть на странице?

Предположим, мы хотим получить получить доступ к функции someFunction(), которая есть в скрипте сайта. Напрямую получить такой доступ не получиться. Для этой цели нужно использовать объект unsafeWindow. Чтобы выполнить нашу функцию, напишем:

unsafeWindow.someFunction();

5. Пример пользовательского скрипта Greasemonkey

Давайте продемонстрируем пример какого-нибудь более-менее полезного скрипта Greasemonkey. Есть такой сайт http://fffuuu.ru, там пользователи публикуют дурацкие, но иногда забавные комиксы. Для того, чтобы переключаться между комиксами, надо нажимать кнопки «Предыдущий» и «Следующий» в виде картинок-стрелок по бокам. Иногда пользователи выкладывают слишком большие изображения, и для того, чтобы увидеть кнопку «Следующий», надо пользоваться скролом. Да и вообще, было бы удобно иметь возможность переключаться между комиксами с помощью клавиатуры, как это происходит, например, в Вконтакте. Ещё каждому комиксу можно поставить плюсик, либо оценку «Школоло».
Путём анализа кода страницы можно увидеть, что ссылка «Следующий» имеет класс «right_arr», а «Предыдущий» - «left_arr». При нажатии на кнопку «Плюс» запускается функция vote(comicsID, 'rating','news'), где comicsID - номер комикса. Если нажать на кнопку «Школоло», то запускается эта же функция, но второй параметр равен «ratingX».
Предположим, мы хотим, чтобы нажатие кнопок влево и вправо на клавиатуре было равнозначно клику по ссылкам «Предыдущий» и «Следующий» соответственно, а нажатие кнопок Delele и Insert соответствовало кнопкам «Школоло» и «Плюс».

// ==UserScript==
// @name           fffuuu
// @namespace      http://softlakecity.ru
// @include        http://fffuuu.ru/show/*
// ==/UserScript==
document.onkeyup = KeyCheck; // Назначим обработчик событий нажатий клавиш
function KeyCheck(event)
{    
    console.log(event.keyCode);
    switch(event.keyCode) // Проверяем, какую клавишу нажал пользователь
    { 
        case 37: // Если это стрелка влево    
            alink = document.getElementsByClassName('left_arr'); // Получаем элемент с классом left_arr (ссылка)
            if(alink.length == 1) {
                window.location.href = alink[0].href; // Переходим по ссылке
            }            
            break;
        case 39: // Если это стрелка вправо            
            alink = document.getElementsByClassName('right_arr');
            if(alink.length == 1) {
                window.location.href = alink[0].href;
            }
            break;
        case 46: // Если это клавиша Del
            comicsID = document.URL.substr(22); // Получаем номер комикса из адресной строки
            unsafeWindow.vote(comicsID, 'ratingX','news'); // Запускаем функцию голосования, которая уже есть на сайте
            break;
        case 45: // Если это клавиша Insert
            comicsID = document.URL.substr(22);
            unsafeWindow.vote(comicsID, 'rating','news');            
            break;
    }
}

6. Подключение jQuery в Greasemonkey

В Greasemonkey можно легко подключить jQuery или любой другой фреймворк, библиотеку или скрипт. Для этого надо использовать директиву @require, предварительно убедившись, что наш фреймворк не используется на сайте.
Вот-так можно подключить jQuery с Google API:

// ==UserScript==
// @name           youtube
// @namespace      http://softlakecity.ru
// @include        http://www.youtube.com/*
// @require        https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js
// ==/UserScript==
$(document).ready(function() {
    alert('hello!');
});

Однако, если этот способ по какой-то причине не работает, Вы можете использовать альтернативный.

// ==UserScript==
// @name           youtube
// @namespace      http://softlakecity.ru
// @include        http://www.youtube.com/watch?v=*
// ==/UserScript==
var script = document.createElement('script');
script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js';
document.getElementsByTagName('head')[0].appendChild(script);
script.addEventListener('load', function(){ 
    jQuery = unsafeWindow['jQuery'];
    jQuery.noConflict();
    jQuery(document).ready(function() {
        console.log('here'); // Вставьте Ваш jQuery-код сюда. Используйте полное имя объекта jQuery, а не знак доллара.
    });
}, false);

Кстати, проверить, имеется ли библиотека jQuery на сайте, можно так:

if (unsafeWindow.jQuery === undefined) {
    console.log('jQuery на сайте нет.');
} else {
   jQuery = unsafeWindow.jQuery;
   console.log('Версия jQuery на сайте ' + jQuery.fn.jquery);
}

7. Как можно симулировать клик мышкой?

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

var simulateClick = function( el ) {
   var customEvent = document.createEvent("MouseEvents");
   customEvent.initMouseEvent(   "click",
                        true,
                        true,
                        unsafeWindow,
                        1,
                        0,
                        0,
                        0,
                        0,
                        false,
                        false,
                        false,
                        false,
                        0,
                        undefined
                     );
   el.dispatchEvent( customEvent );
};

8. Где можно найти готовые скрипты Greasemonkey?

На сайте http://userscripts.org/

9. Что насчёт поддержки Greasemonkey Хромом?

Пока что не знаю. Вроде заявлена «нативная», то есть встроенная поддержка, но удобного интерфейса для запуска пользовательских скриптов я там не обнаружил. Зато есть Tampermonkey, который я попробовал - работает отлично. Единственное, что мне не понравилось, это то, что невозможно редактировать файлы во внешнем редакторе.

14 комментария

  • Евгений:

    Альтернативный способ подключения jQuery более действенный конечно.
    Но меня интересует такой вопрос.Когда используешь альтернативный способ и на сайте уже
    подключена библиотека jQuery то происходит конфликт.
    Как написать код,который бы проверял если библиотека подключена то свою не подключать.
    Если библиотеки jQuery на сайте нет то подключить.

    • Администратор:

      По-моему, не должно быть никаких конфликтов и 2 версии jQuery могут работать одновременно, тем более что скрипты GreaseMonkey, как я понял, работают в изолированном именном пространстве. Хотя, наверняка утверждать не стану.

      Вот так можно проверить, подключена ли jQuery ранее, если нет, то подключить:

      if (unsafeWindow.jQuery === undefined) {
      console.log(‘jQuery на сайте нет.’wink;
      var script = document.createElement(‘script’wink;
      script.src = ‘https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js’;
      document.getElementsByTagName(‘head’wink[0].appendChild(script);
      script.addEventListener(‘load’, function(){
      jQuery = unsafeWindow[‘jQuery’];
      jQuery.noConflict();
      jQuery(document).ready(function() {
      console.log(‘Вы подключили jQuery версии ‘ + jQuery.fn.jquery);
      });
      }, false);

      } else {
      jQuery = unsafeWindow.jQuery;
      console.log(‘Версия jQuery на сайте ‘ + jQuery.fn.jquery);
      }

  • Евгений:

    Так вот почему здесь нет комментариев.Их просто удаляют.Тогда зачем нужна такая возможность.
    Так можно отпугнуть посетителей.Пожалуй удалю из закладок ваш сайт.Только не медлите быстро удалите
    этот комментарий.

    • Администратор:

      Не удаляют, просто комментарий проходит проверку перед добавлением, ибо спамеров много. А комментариев нет, потому что сайт новый, и материалов мало.

  • Евгений:

    Доброго времени суток вам!!!

    Во первых хочу извиниться за то что я выше написал о удалении постов и всё такое.В тот день я пришёл с одного форума на котором не очень хорошо относились к пользователям.Поэтому мне казалось что везде так.

    Хочу написать о конфликтах jQuery в Greasemonkey и jQuery если есть на сайте.Уж не знаю конфликты это или нет но глюки однозначно при таком сочетании появляются.Например на Юкозе.В свой аккаунт не войдёшь если включен скрипт с jQuery.Поэтому я и задавал здесь вопрос о том как сделать проверку для подключения jQuery в Greasemonkey.

    Как то мне достаточно давно попался такой код для подключения jQuery:

    var GM_JQ = document.createElement(‘script’wink;
    GM_JQ.src = ‘http://jquery.com/src/jquery-latest.js’;
    GM_JQ.type = ‘text/javascript’;
    document.getElementsByTagName(‘head’wink[0].appendChild(GM_JQ);
    function GM_wait() {
    if(typeof unsafeWindow.jQuery == ‘undefined’wink { window.setTimeout(GM_wait,100); }
    else { $ = unsafeWindow.jQuery; letsJQuery(); }
    }
    GM_wait();
    function letsJQuery() {

    //Свой код здесь

    }//Конец функции

    Этой конструкцией я пользуюсь по сей день.При таком подходе jQuery библиотека подгружается не зависимо от того есть ли на сайте она или нет.И поэтому если на сайте уже есть эта библиотека то возникали частые конфликты.

    Решить такую проблему мне удавалось просто написав другой скрипт с этой же конструкцией но с
    удалением GM_JQ.src = ‘http://jquery.com/src/jquery-latest.js’;

    А вот сегодня сижу смотрю на эту конструкцию и думаю «А дайка я попробую сделать так:»
    просто взял и переменную GM_JQ с методом .src переместил в иначе
    else { $ = unsafeWindow.jQuery; letsJQuery();
    GM_JQ.src = ‘http://jquery.com/src/jquery-latest.js’;
    }
    И о чудо! Теперь всё работает великолепно.Если на сайте jQuery нет до идёт подгрузка.
    Если же есть то библиотека не загружается.

    • Администратор:

      Ну хорошо, раз работает. Я правда не понял, зачем здесь таймер на 100 милисикунд. В любом случае, спасибо за информацию, возможно это кому-нибудь пригодится.

  • Евгений:

    Прошу прощения в посте сделал ошибку.Переменную GM_JQ перенёс не в ИНАЧЕ а в ТО

    if(typeof unsafeWindow.jQuery == ‘undefined’wink { window.setTimeout(GM_wait,100);
    GM_JQ.src = ‘http://jquery.com/src/jquery-latest.js’;
    }

  • quest:

    7. Как можно симулировать клик мышкой?

    В принципе понятно.
    Но вы не могли бы подсказать как по очереди кликнуть на несколько ссылок.
    На данном этапе моих знаний хватает только на то чтобы только понять общий
    принцип.А технически не могу реализовать.
    По всей видимости нам нужно отобрать все ссылки и они будут представлять собой
    массив.После в цикле по очереди перебрать и кликнуть с заданным интервалом.
    Если сможете помочь буду безмерно благодарен.
    ***
    В Интернете очень мало,крайне мало информации по поводу написания кода для пользовательских
    скриптов применяемых в Greasmonkey или Scriptish.Если бы вы могли потихонечку на своём сайте
    развивать эту тему то очень многим пользователям было бы интересно.
    С Уважением!

    • Администратор:

      О Scriptish лично я не знал, надо будет как-нибудь посмотреть, что он из себя представляет.
      Greasmonkey создан для людей, которые имеют представление о JavaScript, в этом случае проблем с освоением возникнуть не должно. Есть ещё такой инструмент, как iMacros, там не требуется знания JavaScript, для некоторых задач он может быть предпочтительней. Но это отдельная тема.

      Что касается по-очереди кликнуть на несколько ссылок. Для начала надо знать, что из себя эти ссылки представляют. Надо исследовать структуру того HTML документа, с которым Вы работаете. В простейшем случае каждая ссылка будет иметь вид:
      <a href=»http://somesite.com» id=»link3″>Сайт</a>
      В этом случае получить ссылку не составит труда, так как id уникален для каждого элемента:
      simulateClick(document.getElementById(‘link3’wink);
      Если у ссылки нет своего id, тогда у неё может быть класс и т.д. Это уже основы JavaScript. Конечно, если ссылки идут в хаотичном порядке, тогда будет сложнее.

  • Михаил:

    Добрый день, подскажите пожалуйста как вызвать функцию которая находится в скрипте greasemonkey на странице.

    • Администратор:

      Точно так же, как и любу функцию JavaScript:
      someFunction();
      Если же функция эта находится не в Вашем скрипте, тогда:
      unsafeWindow.someFunction();

  • Евгений:

    Добрый день. перерыл весь интернет, справочник только на англиском, не могу написать скрипт, так как знаний мало. К примеру мне нужно написать скрипт-бот для сайта что бы он выполнял простейши

Добавить комментарий