Букмарклет: розбір суттєвих моментів, частина друга, довантажувати

    Нагадаємо, що букмарклет це невеликий javascript-код, що зберігається в закладках браузера, і призначений для виконання будь яких завдань на поточній веб-сторінці.
 
Як було відзначено в попередньому пості букмарклет можна розділити на 3 взаємодіючі частини:
 
     
  1. Перша частина, невеликий, до 2000 символів javascript-код, який зберігається в закладках браузера і, в простому випадку може виконувати всю роботу, але зазвичай служить для ініціації роботи букмарклета.
  2.  
  3. Друга, довантажувати частина букмарклета: javascript-код підвантажуємий в поточний документ в процесі ініціації букмарклета і забезпечує основну функціональність.
  4.  
  5. Третя, резервна частина букмарклета яка спрацьовує якщо довантажити javascript в поточний документ не вдалося.
  6.  
Перша частина букмарклета була досконально розібрана в попередньому пості на живому прикладі букмарклета веб-сервісу TheOnlyPage (сервіс зберігання закладок, нотаток і html-фрагментів)
 
На цей раз зупинимося на довантажувати частини букмарклета.
 
Різноманітність можливих дій довантажувати частини букмарклета неосяжно, поетом розглянемо тільки найбільш суттєві моменти.
 
На цей раз ми не будемо рядок за рядком розглядати вихідний код, а розберемо окремі проблемні моменти і кращі способи їх вирішення. Таким чином, ви отримаєте наступний набір окремих вузлів для створення загружаемой частини букмарклета:
 
 
     
  1. Обгортка — ізоляція коду букмарклета від зовнішнього середовища
  2.  
  3. Включення і скасування індикатора завантаження / вимикання
  4.  
  5. Скидання CSS стилів
  6.  
  7. Завантаження бібліотек
  8.  
Для наочності будемо ілюструвати розглянутий матеріал, звертаючись до роботи букмарклета веб-сервісу TheOnlyPage . Детальну інформацію про те як встановити цей букмарклет можна отримати в довідкової системі веб-сервісу
 
 Обгортка — ізоляція букмарклета від зовнішнього середовища
В попередній публікації ми вже говорили про те, що javascript-код букмарклета необхідно розмістити всередині анонімної функції. Теж справедливо і для коду другий, довантажувати частини букмарклета. Цей код повинен бути обгорнутий в анонімну функцію приблизно таким чином:
 
 
(function (window, undefined) {
// здесь весь код букмарклета
})(window);

Анонімна функція містить 2 параметра
window
і
undefined
, що зроблено для того, щоб замість багаторазово використовуваних глобальних змінних
window
і
undefined
в тілі функції використовувалися локальні змінні
window
і
undefined
, які легко скорочуються за допомогою мініфікаторов javascript-коду.
Виклик анонімної функції передає тільки один параметр:
window
. Другий параметр автоматично приймає необхідне значення
undefined
, не будучи переданим в функцію.
 
 Включення і скасування індикатора завантаження / вимикання
Після того як друга, загружаемая частина букмарклета виявляється успішно завантаженою, саме час відключити індикатор завантаження , який в Букмарклет веб-сервісу TheOnlyPage має наступний вигляд: image.
Просте дію з відключення індикатора завантаження здійснюється наступним чином:
 
 
//  id индикатора загрузки: theonlypageAjaxLoaderGif
var image = window.document.getElementById('theonlypageAjaxLoaderGif');
// удаляем картинку
image.parentNode.removeChild(image);

При додаванні в поточний документ додаткових візуальних елементів, має сенс обернути їх у загальний контейнер. В Букмарклет веб-сервісу TheOnlyPage це реалізовано так:
 
 
// создаем элемент div
var veil = window.document.createElement('div');
// назначаем ему уникальный id
veil.id = 'theonlypageContainer';
// далее, обычно,  еще ряд действий… 
// …по наполнению контейнера содержимым 
// … и установки атрибутов
// встраиваем созданные элементы в текущий документ
window.document.body.appendChild(veil);

Як вже говорилося в попередній публікації важливим моментом є використання на чужій веб-сторінці гарантовано унікальних
id
. Для цього в
id
можна використовувати назву веб-сервісу. У нашому випадку це
theonlypageContainer
.
 
Якщо елементи розмітки, що додаються Букмарклет поміщаються в контейнер, відзначений певним
id
, то при повторному завантаженні можна реалізувати механізм вимикання букмарклета:
 
 
var veil = window.document.getElementById('theonlypageContainer');
if(veil){
// если  в текущем документе уже присутствует контейнер
// удаляем его из текущего документа
	veil.parentNode.removeChild(veil);
	// и завершаем работу букмарклета
	return;
}

Видаляються всі візуальні елементи з поточної сторінки і букмарклет відключається. Таким чином реалізується механиз включення / вимикання букмарклета при послідовному кліці по посиланню букмарклета в панелі закладок браузера.
 
 Скидання CSS стилів
При впровадженні своїх елементів розмітки в чужій документ, треба мати на увазі, що ці елементи можуть успадковувати CSS властивості поточного документа. І, в результаті, наш
div
буде, наприклад, мати зовсім непотрібні відступи, а наш
iframe
всередині нього, наприклад, абсолютно недоречні тіні.
 
Щоб позбутися від можливих заокруглень, квітів, відступів, анімаційних ефектів та інших непотрібних нам властивостей, необхідно скидати стилі кожного створюваного елемента таким чином:
 
 
// задаем переменную содержащую весь CSS код сброса параметров
var ResetCSS = "animation:none;animation-delay:0;animation-direction:normal;animation-duration:0;animation-fill-mode:none;animation-iteration-count:1;animation-name:none;animation-play-state:running;animation-timing-function:ease;backface-visibility:visible;background:0;background-attachment:scroll;background-clip:border-box;background-color:transparent;background-image:none;background-origin:padding-box;background-position:0 0;background-position-x:0;background-position-y:0;background-repeat:repeat;background-size:auto auto;border:0;border-style:none;border-width:medium;border-color:inherit;border-bottom:0;border-bottom-color:inherit;border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom-style:none;border-bottom-width:medium;border-collapse:separate;border-image:none;border-left:0;border-left-color:inherit;border-left-style:none;border-left-width:medium;border-radius:0;border-right:0;border-right-color:inherit;border-right-style:none;border-right-width:medium;border-spacing:0;border-top:0;border-top-color:inherit;border-top-left-radius:0;border-top-right-radius:0;border-top-style:none;border-top-width:medium;bottom:auto;box-shadow:none;box-sizing:content-box;caption-side:top;clear:none;clip:auto;color:inherit;columns:auto;column-count:auto;column-fill:balance;column-gap:normal;column-rule:medium none currentColor;column-rule-color:currentColor;column-rule-style:none;column-rule-width:none;column-span:1;column-width:auto;content:normal;counter-increment:none;counter-reset:none;cursor:auto;direction:ltr;display:inline;empty-cells:show;float:none;font:normal;font-family:inherit;font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;height:auto;hyphens:none;left:auto;letter-spacing:normal;line-height:normal;list-style:none;list-style-image:none;list-style-position:outside;list-style-type:disc;margin:0;margin-bottom:0;margin-left:0;margin-right:0;margin-top:0;max-height:none;max-width:none;min-height:0;min-width:0;opacity:1;orphans:0;outline:0;outline-color:invert;outline-style:none;outline-width:medium;overflow:visible;overflow-x:visible;overflow-y:visible;padding:0;padding-bottom:0;padding-left:0;padding-right:0;padding-top:0;page-break-after:auto;page-break-before:auto;page-break-inside:auto;perspective:none;perspective-origin:50% 50%;position:static;right:auto;tab-size:8;table-layout:auto;text-align:inherit;text-align-last:auto;text-decoration:none;text-decoration-color:inherit;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-shadow:none;text-transform:none;top:auto;transform:none;transform-style:flat;transition:none;transition-delay:0s;transition-duration:0s;transition-property:none;transition-timing-function:ease;unicode-bidi:normal;vertical-align:baseline;visibility:visible;white-space:normal;widows:0;width:auto;word-spacing:normal;z-index:auto;";
// и далее, при назначении свойств создаваемому элементу …
// … всегда используем CSS код сброса параметров …
// … при необходимости добавив CSS код специфический для данного элемента
veil.style.cssText = ResetCSS + 'position:absolute ;background-color:rgba(0,0,0,.2); cursor:pointer; '; 

 
 Завантаження бібліотек
Довантажувати частина букмарклета TheOnlyPage не використовує додаткові бібліотеки, однак, при необхідності, скористатися додатковими бібліотеками нескладно.
 
Розглянемо найбільш широко затребуваний варіант — завантаження бібліотеки jQuery
 
 
// минимально подходящая версия jQuery
var v = "1.11.1";
if (window.jQuery===undefined||window.jQuery.fn.jquery<v){
// если библиотека jQuery не загружена или версия jQuery слишкмо старая
// загружаем библиотеку
	// создаем элемент который будет загружать библиотеку
	var script=document.createElement('script');
	// указываем адрес по которому скачивается библиотека
	script.src="https://ajax.googleapis.com/ajax/libs/jquery/"+v+"/jquery.min.js";
	script.async=true;
	// внедряем скрипт в дом 
	var entry=document.getElementsByTagName('script')[0];
	entry.parentNode.insertBefore(script,entry);
	script.onload=script.onreadystatechange=function(){
		var readyState=script.readyState;
		if (!readyState||/complete|loaded/.test(script.readyState)){
			// если библиотека загружена
			// переходим к выполнению основной части кода букмарклета
			main();
			// отменяем обработчик чтобы не допустить... 
			// ...возможную в некоторых случаях утечку памяти
			script.onload = null;
			script.onreadystatechange = null;
		}
	};
}else{
	main();
}
var main=function(){
	// здесь весь оставшийся основной код букмарклета
}

 
 Важливий момент , на який вже звертали увагу в попередній публікації якщо у загружаемого javascript-коду протокол адреси:
http://
то будуть виникати помилки, при роботі на поточній сторінці, протокол адреси якої:
https://
. Причина цього: обмеження, що накладаються на змішаний активний контент (mixed active content ), які забороняють завантажувати код з незахищених адрес в документ, захищений по протоколу TLS (SSL). Є 2 способи забезпечити, щоб javascript-код завжди нормально завантажувався:
 
     
  1. або розміщувати його за адресою с протоколом
    https://
  2.  
  3. або використовувати спеціальну нотацію
    //
    , наприклад:
     
    script.src='//ajax.googleapis.com/ajax/libs/jquery/v.1.11.1/jquery.min.js'

    що означає використання того ж протоколу що і у батьківського документа. Тоді, в залежності від протоколу самої поточної веб-сторінки
    http://
    або
    https://
    використовуватиметься відповідний адресу:
     
    http://ajax.googleapis.com/ajax/libs/jquery/v.1.11.1/jquery.min.js

    або
     
    https://ajax.googleapis.com/ajax/libs/jquery/v.1.11.1/jquery.min.js
  4.  
До речі, якщо передбачається використовувати бібліотеку jQuery , то варто звернути увагу на наступний важливий момент : щоб уникнути можливі конфлікти недопустимо використовувати скорочення
$
глобальної змінної
jQuery
, так як глобальна змінна
$
, з великою ймовірністю, може вже використовуватися в скриптах поточного документа, не як псевдонім для
jQuery
, а як інша глобальна змінна, наприклад з бібліотеки Prototype.JS . Тому використовуємо тільки
jQuery
, без скорочень.
 
Ми розглянули всі базові елементи загружаемой частини букмарклета , але є ще дві теми для обговорення:
 
     
  1. крос-доменний обмін повідомленнями з сервером;
  2.  
  3. аутентифікація користувачів веб-сервісу при роботі з Букмарклет.
  4.  
Однак ці теми потребують окремого місця і часу і їм будуть присвячені окремі публікації.
    
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.