Заметки с тегом «hint» (страница 2)

Однократный вызов функции с таймаутом

Бывает нужно подписаться на какое-то событие, но нет уверенности, что оно вообще может наступить. Можно условиться о неком интервале, в течение которого мы ожидаем это событие.


/**
 * @param {Function} fn function which needs to be called only once
 * @param {Number} timeout for external call
 * @param {Object} [context]
 * @returns {Function}
 */
function withTimeout(fn, timeout, context) {
  var timerId, state = true;

  function cb() {
    if (timerId) {
      clearTimeout(timerId);
      timerId = null;
    }
    if (state) {
      state = false;
      fn.apply(context || window, arguments);
    }
  }

  timerId = setTimeout(cb, timeout);

  return cb;
}

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

Комментарии к заметке: 1

Вызов функции «чуть позже»

Мы уже привыкли пользоваться setTimeout(fn, 0) , чтобы запланировать вызов некой функции и продолжить выполнение текущего кода. Мы ожидаем, что запланированный вызов произойдёт максимально быстро на сколько это возможно. Однако у всех JavaScript движков есть ограничение — 4 миллисекунды. Побороть это ограничение можно, если пользоваться requestAnimationFrame или setImmediate.


/**
 * Runs the callback at the next available opportunity.
 * @see https://developer.mozilla.org/en-US/docs/Web/API/window.setImmediate
 */
var setImmediate = function(callback) {
  return (
    window.setImmediate ||
    window.requestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.setTimeout
  )(callback, 0);
};

/**
 * Clears a callback previously registered with `setImmediate`.
 * @param {id} id The identifier of the callback to abort
 */
var clearImmediate = function(id) {
  return (window.clearImmediate ||
    window.cancelAnimationFrame ||
    window.webkitCancelAnimationFrame ||
    window.mozCancelAnimationFrame ||
    window.clearTimeout)(id);
};

Метод setImmediate объекта window был реализован в IE10 и Node.js 10+, но встретил сопротивление со стороны разработчиков Firefox и WebKit из-за неясности спецификации.

Комментарии к заметке: 4

Редирект на другой URL с помощью mod_alias

В HTTP-сервере Apache для редиректов в основном используется mod_rewrite. Без сомнения, это очень мощный инструмент. Для редиректа с одного адреса на другой я чаще всего применяю mod_alias.

Для редиректа используется директива Redirect или RedirectMatch.

Первым опциональным аргументом идёт HTTP-статус код. Если он не задан явно, то считается равным 302 (временный редирекс). Вместо цифровых кодов можно применять ключевые слова: permanent (301), temp (302), seeother (303), gone (410). Технически, в качестве кода статуса можно использовать любое допустимое значение.

Redirect permanent /one /two

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


Redirect /path/file.txt /assets/data/file.txt
Redirect 301 /report-2013.pdf http://example.com/reports/2013/report.pdf

Итак, директивы mod_alias выглядят гораздо проще и понятнее по сравнению с аналогами в mod_rewrite и прекрасно подходят для простых редиректов.

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

Колбек в триггере события

Изначально не предполагается, что обработчик события может вернуть какие-то данные функции, которая сгенерировала это событие.

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


var a = {};

$(a).on("customEvent", function (e, callback) {
  callback(Math.random());
});

$(a).trigger("customEvent", [
  function (v) { alert(v); }
]);

Пример на jsfiddle.net

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

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

Истинные размеры изображения

Когда картинка появилась на странице, то к ней сразу же начинают применяться стили и узнать её истинные габариты через свойства width и height уже нельзя.

Во всех современных браузерах (включая IE9 и старше) есть свойства naturalWidth и naturalHeight, которые после полной загрузки картинки принимают значения ширины и высоты изображения, соответственно.


var img = document.getElementById("gallery-image"),
    width = img.naturalWidth,
    height = img.naturalHeight;

В IE8 и младше этих свойств нет. Получить не модифицированные размеры можно, если создать новый элемент с тем же самым значением атрибута src и уже у него прочитать свойства width и height.


function getDimensions(sourceImage) {
    var img = new Image();
    img.src = sourceImage.src;
    return {
        width: img.width,
        height: img.height
    };
}
Комментарии к заметке: 2