Pull to refresh

jQuery без рамок

Reading time 4 min
Views 3.6K
Фреймворк — набор инструментов, но не традиций или конвенций программирования, а цель любого приложения — это скорость выполнения и правильность результатов. В опубликованной статье показано эффективное использование запросов к DOM, но не только от этого приложение на jQuery будет работать быстрее.


Не используйте each


Вернее «не совсем», а там, где это не оправдано:
var a = [1,2,3,4];

$.each(a, function ()
{
 console.log(this);
});

// это крайне медленно!

лучше так:
for (var i = 0, l = a.length; i < l; i++)
{
 console.log(a[i]);
}
При обычном подходе вы не тратите время на вызовы callback-функций и ненужные проверки на прекращение цикла. Еще пример:
var b = {c: 1, d: 2, e: 3};

$.each(b, function (k)
{
 console.log(k, this);
});

// опять медленно
лучше так:
for (var k in b)
{
 if ( b.hasOwnProperty(k) )
 {
  console.log(k, b[k]);
 }
}

Пишите плагины


Пишите плагины на все, что движется и шевелится. 10 минут, потраченные сегодня на оформление плагина, дадут прирост в скорости разработки завтра.

Пример из жизни. Понадобилось нам включать/отключать кнопку сабмита в зависимости от наличия текста в поле textarea. Первым родился плагин:
$.fn.inputChange = function (callback)
{
 return this.bind(
 {
  mousedown: callback,
  keyup: callback,
  blur: callback
 });
};
и работает он так:
var submit = $("#submit");

// вариант 1
$("#text").inputChange( function ()
{
 submit[0].disabled = this.value.length === 0;
});

// вариант 2
$("#text").inputChange( function ()
{
 if (this.value.length === 0)
 {
  submit.attr("disabled", "disabled");
 }
 else
 {
  submit.removeAttr("disabled");
 }
});
Однако оба варианта далеки от идеала: 1 может упасть с ошибкой, если вдруг не окажется элемента внутри submit, 2 — слишком громоздкий.

Родился второй плагин:
$.fn.disable = function (bool)
{
 return this.each( function ()
 {
  this.disabled = bool;
 });
};
и работает этот плагин в связке с $.fn.inputChange так:
$("#text").inputChange( function ()
{
 submit.disable(this.value.length === 0);
});
Однако возникла проблема, что ни одно событие, указанное в inputChange, не может обработать вставку из буфера обмена. Погуглив, пришли к решению:
$.fn.paste = function (listener)
{
 if ($.browser.msie)
 {
  return this.bind("paste", function (event)
  {
   var that = this;

   setTimeout(
    function ()
    {
     listener.apply(that, [event]);
    },
    .001
   );
  });
 }
 else
 {
  return this.bind("input", function (event)
  {
   listener.apply(this, [event]);
  });
 }
};
а плагин inputChange принял следующий вид:
$.fn.inputChange = function (callback)
{
 return this
  .paste(callback)
  .bind(
  {
   keyup: callback,
   blur: callback
  });
};
Так «по кирпичикам» мы собрали работающий функционал, дополнив библиотеку отличными плагинами, которые нам непременно пригодятся, а возможно и вам…

Нативный код


У многих бытует мнение, что jQuery умеет все. И в какой-то мере они правы, но это право не дает им повода забывать о нативном JS.

Приведу пример:
function warning(text)
{
 $("<div id='alert' class='warning'></div>")
  .appendTo( $(document.body) )
  .css(
  {
   "padding": "10px",
   "background-color": "red",
   "color": "white"
  })
  .html(text)
  .append(
   $("<button>OK</button>").attr("title", "Close me!").click( function ()
   {
    $(this).parent().remove();
   }) 
  );
}
Во многом код высосан из пальца, но исключительно в целях демонстрации. Теперь попробуем переписать код на чистом JS:
function warning(text)
{
  var div = document.createElement("div");
  div.id = "alert";
  div.className = "warning";

  div.style.padding = "10px";
  div.style.backgroundColor = "red";
  div.style.color = "white";

  div.innerHTML = text;

  var button = document.createElement("button");
  button.setAttribute("title", "Close me!");
  button.innerHTML = "OK";

  $(button).click( function ()
  {
   div.parentNode.removeChild(div);
  });

  div.appendChild(button);
  document.body.appendChild(div);
}
Я умышленно добавил событие, используя jQuery, так как jQuery хорошо инкапсулирует кроссбраузерные вызовы addEventListener/attachEvent, стирая границы между браузерами и за это создателям jQuery большой респект. В остальном используются стандартные методы для работы с DOM.

Оба примера хороши: первый — изящный, второй — быстрый. Во многом нет ограничений, как вы работаете с DOM, но если вы используете jQuery (MooTools, Prototype, ExtJS и тд), то не забывайте про нативный JS, который всегда быстрее. Ведь любой фреймворк не ставит вас в рамки, а лишь дает инструменты.
Tags:
Hubs:
+32
Comments 40
Comments Comments 40

Articles