Список содержимого

Страница 3 из 4 < | >


Контролируйте страницы с помощью UserJS

Примеры использования

Перезапись специфичных переменных или функций

UserJS позволяют перезаписывать переменные и функции, устанавливаемые любыми скриптами на странице. Это делается использованием методов ‘defineMagicVariable’ и ‘defineMagicFunction‘. Например, если сайт некорректно идентифицирует Opera, и затем пытается заставить Opera выполнить код, который был предназначен для другого браузера:

var ie = document.all;

UserJS может перезаписать неправильную идентификацию:

window.opera.defineMagicVariable( 'ie', function () { return 0; }, null );

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

Загрузка скриптов

Для обнаружения событий, когда скрипты собираются загружаться, интерпретироваться, или выполняться, может быть использован метод ‘window.opera.addEventListener‘.

UserJS может использовать событие ‘BeforeScript’ для обнаружения момента, когда скрипт на странице собирается интерпретироваться JavaScript-машиной. Если необходимо, содержимое скрипта может быть затем перезаписано или отменена его интерпретация.

Например, если скрипт сравнивает несуществующее значение атрибута с нулем:

if( node.getAttribute('myattribute') != null ) {

Они никогда не должны приравниваться друг к другу, поскольку ‘getAttribute’ должен возвратить пустую строку, но некоторые другие браузеры неправильно возвращают ‘null‘. Как результат, в скрипте в Opera произошел бы сбой, которая правильно возвращает пустую строку. Для предупреждения возникновения этой проблемы, UserJS может обнаружить момент, когда скрипт собирется интерпретироваться а перезаписать его для удаления сравнения, так как нет в нем необходимости с этим типом оператора:

if( location.hostname.indexOf('example.com') != -1 ) {
  window.opera.addEventListener(
    'BeforeScript',
    function (e) {
      e.element.text = e.element.text.replace(/!=s*null/,'');
    },
    false
  );
}

Если страница загружает специфический внешний скрипт, который вызывает проблемы, можно использовать ‘BeforeExternalScript’ для обнаружения момента, когда скрипт должен загрузиться, и предотвращения загрузки скрипта в Opera:

if( location.hostname.indexOf('example.com') != -1 ) {
  window.opera.addEventListener(
    'BeforeExternalScript',
    function (e) {
      if( e.element.getAttribute('src').match(/problem/script.js$/) ) {
        e.preventDefault();
      }
    },
    false
  );
}

Отмена событий и обработчиков событий

UserJS может использовать одно из событий ‘BeforeEvent.type’ для обнаружения момента, когда должно произойти событие скрипта, даже если на странице нет скрипта, ожидающего это событие. Это можно использовать для обнаружения специфических типов событий, таких как ‘BeforeEvent.click‘.

Вы также можете использовать ‘BeforeEvent’ самостоятельно для ожидания событий любого типа. В Opera 8, это не будет срабатывать, если вы будете ожидать более определенный ‘BeforeEvent.type‘. Например, если вы ожидаете события ‘BeforeEvent.click‘, то события ‘BeforeEvent’ не произойдут для события шелчек. Примите во внимание, что ‘BeforeEvent’ может обнаружить существенное количество событий, и использование его может привести к сбою в работе.

Для предотвращения обнаружения “onload” событий скриптами на странице, вы можете использовать для их завершения ‘BeforeEvent.load‘. Примите во внимание, что “onload” происходят для других элементов, таких, как изображения, и скрипт должен проверить, произошло ли событие для всего документа:

if( location.hostname.indexOf('example.com') != -1 ) {
  window.opera.addEventListener('BeforeEvent.load',function (e) {
    //проверка того, что загружена страница, а не только рисунок
    if( e.event.target instanceof Document ) {
      e.preventDefault();
    }
  },false);
}

В большинстве случаев, события ‘BeforeEventListener’ могут быть более полезными, если они будут происходить только в том случае, если скрипт на странице ожидает эти события. Они обеспечивают доступ и к объекту события, и к функции обработчика событий. События могут быть отменены, используя preventDefault.

Эти события могут также быть обнаружены, более специфично используя ‘BeforeEventListener.type‘, в некоторых случаях вы можете использовать ‘BeforeEvent.type’ вместо ‘BeforeEvent‘. Например, для предотвращения мониторинга скриптом движений мышью:

if( location.hostname.indexOf('example.com') != -1 ) {
  window.opera.addEventListener(
    'BeforeEventListener.mousemove',
    function (e) {
      e.preventDefault();
    },
    false
  );
}

Вы можете также более тщательно обнаруживать функциональность, которая должна быть предотвращена. В этих примерах UserJS проверяет если обработчик событий — функция ‘myMouseTrail’ – предоставляется страницей. Он тогда изменит объект события и представит так, что позиция мыши – наверху страницы:

if( location.hostname.indexOf('example.com') != -1 ) {
  window.opera.addEventListener(
  'BeforeEventListener.mousemove',
    function (e) {
      if( e.listener == moveMouseTrail ) {
        e.event.clientY = 0;
        e.event.pageY = 0;
      }
    },
    false
  );
}

Событие ‘AfterEvent’ позволяет пользовательскому JavaScript проверять, если скрипт на странице завершает дуйствие. Когда действие было предотвращено, UserJS может отменить прекращение, и позволить действию свершиться.

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

if( location.hostname.indexOf('example.com') != -1 ) {
  window.opera.addEventListener(
    'AfterEvent.submit',
    function (e) {
      if( e.eventCancelled ) {
        //скрипт пытался остановить подтверждения формы
        if( confirm( 'Подтверждение было предотвращено. Подтвердить в любом случае?' ) ) {
          //предотвращение блокировки скриптом подтверждения формы
          e.preventDefault();
        }
      }
    },
    false
  );
}

JavaScript URL

Страницы также могут использовать JavaScript в виде URL как способ инициализации скриптов, например наличие JavaScript в атрибуте HREF ссылки, или атрибуте TARGET формы. UserJS может обнаружить момент, когда они будут активироваться и предотвратить их запуск, или перезаписать скрипт, который должен запуститься. Примите во внимание, что это также затрагивает закладурки (bookmarklets), использующие протокол javascript:.

Например, если страница использует JavaScript в виде URL для открытия нового окна, UserJS может использовать событие ‘BeforeJavascriptURL’ для перезаписи его таким образом, что он будет отображать диалог подтверждения до открытия окна.

if( location.hostname.indexOf('example.com') != -1 ) {
  window.opera.addEventListener(
    'BeforeJavascriptURL',
    function (e) {
      if( e.source.indexOf('window.open') != -1 ) {
        //перезапись скрипта для подтверждения до открытия окна
        e.source = e.source.replace(
          /window.open/g,
          'if( confirm(\'Подтверждаете открытие окна?\') ) window.open'
        );
      }
    },
    false
  );
}

JavaScript в виде URL могут также возвращать значения. Страница может преднамеренно использовать это значение для перезаписи себя новым содержимым, но иногда может возвращать ошибочное значение и неправильно перезаписывать содержимое страницы. UserJS может перехватить это возвращенное значение используя событие ‘AfterJavascriptURL’ и отображая диалог подтверждения до записи нового содержимого. Он также при необходимости может перезаписать новое содержимое.

if( location.hostname.indexOf('example.com') != -1 ) {
  window.opera.addEventListener(
    'AfterJavascriptURL',
    function (e) {
      if( typeof( e.returnValue ) == 'string' ) {
        if( confirm('Перезаписать страницу?') ) {
          e.returnValue += 'Изменено User JavaScript';
        } else {
          e.preventDefault();
        }
      }
    },
    false
  );
}

Нормальные скрипты и события

UserJSs не должны полагаться на эти специальные события, и могут также принимать нормальное выполнение скриптов. Например, для отображения на каждой странице предупреждения о том, какой режим рендеринга использует Opera (QuirksMode или CSS1Compat), вы можете использовать следующее:

document.addEventListener(
  'load',
  function (e) {
    if( !document.body ) { return; }
    var mydiv = document.createElement('div');
    mydiv.style.position = 'fixed';
    mydiv.style.top = '0px';
    mydiv.style.right = '0px';
    mydiv.style.border = '1px solid #000';
    mydiv.style.backgroundColor = '#fff';
    mydiv.style.color = '#000';
    mydiv.appendChild(document.createTextNode(document.compatMode))
    document.body.appendChild(mydiv);
  },
  false
);

Скрипты Greasemonkey

Opera способна запускать большинство Greasemonkey-скриптов. Это JavaScripts, разработанные для работы с Greasemonkey, расширением для браузеров семейства Mozilla. Для того, чтобы сообщить Opera о том, какой из файлов скриптов использует разметку Greasemonkey, имя файла, содержащего скрипт, должно заканчиваться на “.user.js” (все остальные “.js”-файлы воспринимаются как нормальные UserJS). Скрипты, которые используют разметку Greasemonkey, обрабатываются немного по-другому (для того, чтобы быть совместимыми с существующими скриптами):

Из-за этих различий обработки, скрипты Greasemonkey часто не способны исправлять проблемы или ошибки до того, как они произошли. Как результат, такие сценарии вообще лучше всего подходят как добавочные расширения, а не как исправляющие проблематичные скрипты.

Хотя возможно использование нормального обнаружения адреса страницы, скрипты Greasemonkey должны обычно использовать блок комментария ==UserScript== для ограничения адресов страниц, на которых скрипты будут исполняться. В общем случае, JavaScript-код для каждого расширения содержится в его собственном файле, хотя это и не обязательно.

Так как скрипт выполнится непосредственно до запуска любых обработчиков onload событий, он может быть записан inline, но для предотвращения создания глобальных переменных, лучше использовать анонимную функцию, которая активизируется немедленно. Например, для предотвращения использования страницей target=”_blank” для открытия ссылок в новом окне, вы можете использовать следующее:

(function () {
  for( var i = 0; document.links[i]; i++ ) {
    if( document.links[i].target == '_blank' ) {
      document.links[i].target = '_self';
    }
  }
})();

Использование разметки Greasemonkey — эквивалентно созданию ожидания события ‘BeforeEvent.load’ в нормальном UserJS, так как показано в разделе Отмена событий и обработчиков событий.

Полезный совет: многие скрипты Greasemonkey используют ‘window._content’ для ссылки на объект окна. В Opera это не нужно, но для сохранения редактирования каждого файла, который использует это, вы можете просто добавить это к нормальному файлу UserJS:

window._content = window;

Контроль режима навигации

UserJS могут отменять режим навигации по истории в Opera для того, чтобы сделать его всегда быстрым, или всегда совместимым. Дополнительную информация о деталях этих режимов можно получить просмотрев статью в нашей базе знаний. Эти режимы могут быть установлены с использованием метода ‘setOverrideHistoryNavigationMode‘.

opera.setOverrideHistoryNavigationMode('fast')

Использование XSLT

Opera также предоставляет два метода, которые могут использовать UserJS для более легкого контроля применения XSLT к документу. Эти методы – ‘pushXSLTransform’ и ‘popXSLTransform‘. Метод ‘pushXSLTransform’ ожидает один из аргументов: любой документ, корневым элементом которого является или ‘xsl:stylesheet’ или ‘xsl:transform‘, или сам элемент ‘xsl:stylesheet‘.

Метод ‘pushXSLTransform’ позволяет использовать XSLT как таблицу стилей XSL в текущем документе. Если он вызывается более чем однократно, эффект суммируется так, что одна таблица стилей XSLT может быть применена к результатам действия другой таблицы. Метод ‘popXSLTransform’ удаляет последнее произведенное преобразование, создавая отображаемый документ из дерева результатов предыдущего преобразования.

var t = (new DOMParser()).parseFromString(
  "<stylesheet xmlns='http://www.w3.org/1999/XSL/Transform' version='1.0'>" +
    "<template match='/'>" +
      "Привет, мир!" +
    "</template>" +
  "</stylesheet>",
  "text/xml"
);
 
opera.pushXSLTransform(t);
 
if( !confirm("Хотите ли вы сохранить это изменение?") ) {
  opera.popXSLTransform();
}

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


Страница 3 из 4 < | >


Оригинал страницы: Take Control with User JavaScript – Examples of use

Copyright Opera Software ASA. Все права зарезервированы

2007. OperaFan.net. Ermir, неофициальный перевод.