Javascript.RU

Букмарклеты и правила их написания

Букмарклет(bookmarklet) - это javascript-код, который сохраняется как закладка в браузере. Он работает за счет использования протокола <a href="javascript:...">.

Выбирая такую закладку, вы запускаете яваскрипт-код в контексте текущей страницы. А дальше он уже может делать что угодно: править страницу, делать запросы к серверу и, вообще, использовать всю мощь современного javascript.

Поэтому де-факто букмарклет - это javascript-плагин к браузеру.

Для примера сделаем букмарклет, который осуществляет поиск выделенного текста в гугле.

Функция на javascript была бы такая:

function searchGoogle() {
  var selected
  
  if (window.getSelection) selected = window.getSelection()
  else if (document.getSelection) selected = document.getSelection()
  else selected = document.selection.createRange().text
  var q = "" + selected

  if (q)  location="http://www.google.com/search?q="+encodeURIComponent(q);
  void 0;
}

В конце функции searchGoogle стоит void 0. Это кроссбраузерно останавливает обработку ссылки браузером, предотвращая ненужный переход.

Испытаем ее:

<a href="javascript:searchGoogle();">Искать выделенное</a>

Выделите текст и кликните: Искать выделенное

Чтобы превратить функцию в букмарклет - достаточно "запаковать" ее в одну строку и заменить кавычки на одинарные (или на &quot;,), чтобы не было конфликта с закрывающими кавычками javascript:

<a href="javascript: if (window.getSelection) selected = window.getSelection(); else if (document.getSelection) selected = document.getSelection(); else selected = document.selection.createRange().text; q = &quot;&quot;+selected; if (q) location=&quot;http://www.google.com/search?q=&quot;+encodeURIComponent(q);  void 0; ">Искать выделенное</a>

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

После этого достаточно выделить текст на странице и кликнуть на закладку, чтобы найти выделенный текст в гугл.

Открытый документ может представлять собой фреймсет. При этом способы обращения к содержимому, использованные в нашем примере, работать не будут. Текст надо искать во фреймах, а не в текущем окне.

Есть несколько способов обойти эту проблему.

Если букмарклет не задуман для работы с фреймами - можно проверять их наличие и выводить предупреждение.

Для более надежной работы исключим ифреймы: в подавляющем большинстве сайтов они используются чисто технологически: в ajax, для обхода некоторых багов и тому подобное.

if(frames.length > document.getElementsByTagName('iframe').length)
  alert('Извините, фреймы не поддерживаются.');
else{
  /* код букмарклета */
}

С другой стороны, поддержка фреймов - хорошая фича. Например, букмарклет для поиска в гугл должен работать на сайтах с фреймами.

Решение - рекурсивный обход фреймов:

function traverse(win){
  try{
    /* Работа с win.document */
    ...
  } catch(e){
    /* Ошибка доступа к фрейму */
  }

  /* Вызов traverse для вложенных фреймов */
  for(var i=0; i<win.frames.length; i++) {
      traverse(win.frames[i]);
  }
}
traverse(window);

Вызов traverse(window) рекурсивно обрабатывает(например, ищет выделение) все фреймы, начиная с текущего окна.

В нее добавлена конструкция try ... catch для обработки возможных ошибок безопасности браузера, которые происходят, если доступ к фрейму противоречит политике Same Origin. Например, когда ифрейм используется для показа рекламы с другого домена.

Так как букмарклет закрыт в двойные кавычки - желательно использовать в коде либо &quot;, либо одинарные.

Например, в букмарклете для поиска в гугл можно заменить все &quot; на одинарные кавычки. Тоже будет работать:

<a href="javascript: if (window.getSelection) selected = window.getSelection(); else if (document.getSelection) selected = document.getSelection(); else selected = document.selection.createRange().text; q = ''+selected; if (q) location='http://www.google.com/search?q='+encodeURIComponent(q);  void 0; ">Искать выделенное</a>

Если функция или операция присваивания возвращает значение - то, какое бы оно ни было, букмарклет перенаправит посетителя на новую страницу, которая показывает это значение.

Иногда это можно грамотно использовать. например показать сводку по ключевым словам в документе. Обычно же это значение перехватывают и обнуляют при помощи void. Типичное решение - поставить в конце букмарклета:

void 0;

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

<a href="javascript: (function(){ .... })()">переколбасить страницу</a>

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

Букмарклет работает в глобальной области видимости.

Это значит, что даже переменная, объявленная с var, будет глобальной:

<a href="javascript: var a = 5; void 0">Запишет в window.a</a>

Чтобы это обойти - используют 2 способа.

Первый - назначить переменным уникальные имена типа aBBZZ. Это криво.

Второй - оборачивать букмарклет в анонимную функцию:

<a href="javascript:(function(){ var a = 5; })()">Запишет в локальную переменную</a>

При этом также отпадает необходимость в void.

Так выглядит поисковый букмарклет, обернутый в анонимную функцию:

<a href="javascript:(function(){ var selected; if (window.getSelection) selected = window.getSelection(); else if (document.getSelection) selected = document.getSelection(); else selected = document.selection.createRange().text; var q = ''+selected; if (q) location='http://www.google.com/search?q='+encodeURIComponent(q);})(); ">Искать выделенное</a>

В отличие от исходного варианта, он не загрязняет глобальную область переменными selected и q.

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

Вот некоторые данные:

Браузер Максимальное кол-во символов
Netscape > 2000
Firefox > 2000
Opera > 2000
IE 4 2084
IE 5 2084
IE 6 508
IE 6 SP 2 488
IE 7 2084

Как видите, Internet Explorer 6.0 держит до 508 символов, а Internet Explorer 6.0 SP2 - еще хуже, всего лишь 488 символов. Так что, если вы хотите быть уверенными, что букмарклет запустится в IE6 - ограничьте его 488 символами.

Это ограничение не относится напрямую к размеру скрипта в <a href="javascript:...">. Оно срабатывает когда букмарклет добавляют в избранное. Вы можете сделать замечательный букмарклет, он будет работать на странице, но при добавлении в избранное код будет обрезан.

Чтобы это обойти, букмарклет в IE может подключать внешние скрипты:

...
var script=document.createElement('script')
script.src='http://my.bookmarklet.ru/myscript.js'
document.getElementsByTagName('head')[0].appendChild(script)
...

Альтернативный подход - разрабатывать букмарклет только для "Продвинутых браузеров". Это работает, если букмарклет представляет собой полезный инструмент, ради которого не лень и браузер сменить.

Например, многие SEO'шные букмарклеты сделаны именно так. Хочешь использовать - поставь FF и инструмент к твоим услугам.

Успешного плагинописания!


Автор: Gvozd, дата: 25 октября, 2008 - 17:46
#permalink

Грамотная статья!
раскрыты некоторые особенности, про которые нет ни слова в других статьях про букмарклеты.
Большое спасибо


Автор: Lex1 (не зарегистрирован), дата: 16 ноября, 2008 - 18:12
#permalink

> Максимальное кол-во символов
Google Chrome > 2000 (проверено с ~16000 символами)
Safari Win - около 2000 символов


Автор: Mussolini (не зарегистрирован), дата: 14 января, 2009 - 12:47
#permalink

Ну наконецто хоть тут раскрыты некоторые особенности.


Автор: Time (не зарегистрирован), дата: 15 января, 2009 - 12:59
#permalink

Для надежной работы надо исключить ифреймы полностью.


Автор: Grif (не зарегистрирован), дата: 16 января, 2009 - 12:51
#permalink

Грамотная статья! и очень понятная


Автор: Life (не зарегистрирован), дата: 19 января, 2009 - 15:06
#permalink

Для меня лично непонятно даже мой друг непонял..


Автор: Гость (не зарегистрирован), дата: 16 февраля, 2009 - 18:52
#permalink

а можно ли выбрать window.getSelection() из нужного div?


Автор: FRACTAL (не зарегистрирован), дата: 20 февраля, 2009 - 11:43
#permalink

Хорошая статейка, СПАСИБО! А хто-нить подскажет, каг сделать чтобы этот выделенный текст, который потом ишет Гугл, открывался в новой вкладке?


Автор: Гость (не зарегистрирован), дата: 26 марта, 2009 - 13:47
#permalink

 open('http://www.google.com/search?q='+encodeURIComponent(q))
вместо
location='http://www.google.com/search?q='+encodeURIComponent(q)


Автор: dantistus (не зарегистрирован), дата: 9 апреля, 2009 - 21:58
#permalink

Офигенская статья, спасибо вам большое! Только что открыл для себя удивителный мир букмарклетов, буду думать, как его можно использовать для себя


Автор: vk (не зарегистрирован), дата: 20 апреля, 2009 - 01:38
#permalink

Да, здорово!
Как я понимаю, поколдовав с запросом и кодом, можно как проводить google-поиск по конкретному сайту или сайтами, а может и выводить результаты в рамках своего ресурса.


Автор: Гость (не зарегистрирован), дата: 21 декабря, 2009 - 01:44
#permalink
if (top != window) ...

Это к предмету вывода "в рамках"


Отправить комментарий

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
4 + 4 =
Введите результат. Например, для 1+3, введите 4.
 
Текущий раздел
Поиск по сайту
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Стандарт языка

Разное

Дерево всех статей

Статьи и мероприятия

Будьте в курсе наших последних новостей!

Ответьте, пожалуйста..
Новая подсветка лучше старой?

Недавно сайт перешел на новую подсветку синтаксиса. Подробнее http://javascript.ru/formatting


Последние обсуждения на форуме
Forum
Последние комментарии