Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Кто же так обработчики событий назначает? Делаем правильно.a.setAttribute('ommouseover', '__osb.someOtherFunction(\'asdf\', this);')
В этом случае в глобальную область видимости попадает ourSuperBookmarklet и __osbЧтобы не таскать 2 глобальных переменных, можно было сделать Ваш ourSuperBookmarklet синглтоном — все равно больше одного экземпляра Вам не нужно.
alt="Bookmarklet Title"Используя нативные функции для работы с DOM я гарантирую, что скрипт будет работать так, как хочу я.Иногда, то что вы ожидаете !== то что браузер на самом деле выполняет (взгляните хотя бы на эвенты). Фрэймворки многое дотачивают за вас. Не стоит их так не любить. Многие не используют фрэймворки из-за того, что они много занимают, мне, например, время важнее.
(function (window) {
var myBookmarklet = {
init: function () {
// Создаем кнопку
var e = document.createElement('button');
e.addEventListener('click', function () {myBookmarklet.onActionButtonClick.call(myBookmarklet)});
this.actionElem = e;
/* add button to DOM tree */
},
onActionButtonClick: function () {
// какие-то дествия на клик
this.requestData(someParams, function () {/* callback */});
this.processData(someParams);
},
...
processCallback: function () {
}
};
// вытаскиваем Callback наружу это единственное, что видно в глобале
window.myBookmarkletCallback = function (data) {
// proxy
myBookmarklet.processCallback(data);
}
myBookmarklet.init();
}(this));В замыкание должны быть переданы все внешние объекты, в моём случае это window. И не должны быть экспортировны в глобалы, не использующиеся извне объекты. Все это это гарантирует более быструю работу скрипта и лучшую сжимаемость «умными» сжимателями (Closure compiler, YUI Compresor).(function () {
...
var g = document.getElementsByTagName;
(g('head')[0] || g('body')[0] || g('*')[0]).appendChild(script);
}());Сейчас огромное количество сайтов использует jQuery вы бы могли тоже использовть jQuery в букмарклетах. Если есть jQuery на сайте — хорошо, не загружаем. Если нет, то подгружаем с CDN (yandex, google, bing) уверен, что будет в кэше браузера и браузеру не придется закачать дополнительный объем данных.var g = function(tag){return document.getElementsByTagName(tag)};var g = document.getElementsByTagName;
alert(typeof g); // undefined getElementsByTagName это особый метод, которая возвращает живую коллекцию элементов, на него нельзя создать ссылку извне (getElementById аналогично).var g = document.querySelectorAll; // CSS selectors engine
alert(typeof g); // function вроде бы все ок!
alert(typeof g('*')); // но на самом деле тут будет ошибка "Illegal operation on WrappedNative prototype object"
alert(g.call(document, '*') instanceof NodeList); // true это работает и возвращает корректный результатЯ тоже поторапился и написал кривой код выше.
var obj = {
fnc: function(){return this.document},
document: 'Hello, world!'
};
var p = obj.fnc;
alert( [obj.fnc(), p()] )
При вызове функции p this внутри будет указывать на window и функция вернет window.document, а не obj.document, как в первом случае. Соответственно, все эти нативные функции просто проверяют, является ли this экземпляром нужного «класса» HTMLDocument. Если нет — выбрасывают исключение. var p = obj.bind(obj);var g = document.getElementsByTagName;
alert(typeof g); // function
alert(g.call(document, '*') instanceof HTMLCollection); // trueC поведением this знаком. Отличное описание дано тут dmitrysoshnikov.com/ecmascript/ru-chapter-3-this/ На самом деле это давнольно распостраненная проблема (аналогично Date, RegExp) из-за:Многие привыкли, что ключевое слово this в языках программирования тесно связано с объектно-ориентированным программированием, а именно, указывает на текущий порождаемый конструктором объект.
Tips & tricks в разработке букмарклетов