JavaScript

Делаем комментарии Хабрахабра похожими на Reddit 5 марта 10

Я последнее время практически не бываю на Хабре, зато часто захожу на Reddit. По-моему на последнем гораздо удобнее читать комментарии, в первую очередь потому, что их можно отсортировать по рейтингу и читать только
наиболее «ценные».

Так вот. Сел и написал юзерскрипт, который делает просмотр комментариев на Хабре более удобным.

  • Комментарии сортируются по рейтингу (в пределах одного уровня).
  • Ветки комментариев можно сворачивать и разворачивать нажатием на ссылку [-] в заголовке коммента.
  • Ник автора подсвечивается синим и отмечается буквой [S].
  • Юзерпики убираются насовсем, чтоб не мельтешили.

Скачать Habrahabr ‘comments like reddit’ mod с UserScripts.
Проверено в Firefox 3.6 + Greasemonkey и в Chrome 5.

Область видимости переменной в Javascript (variable scope) – ликбез 22 декабря 09

Для меня одним из самых проблемных мест Javascript было управление переменными. Излагаю простым русским языком.

Области видимости переменных

Переменные в Javascript бывают глобальными и локальными. Глобальная переменная доступна везде, локальная – только в текущей области видимости.

Технически, глобальные переменные – всего лишь свойства объекта window, поскольку весь код выполняется в его контексте.

<script>
  alert(location); // сообщит window.location
</script>

Из этого следует, что глобальные переменные могут затирать свойства window (я уже молчу о том, что они зло, нарушают инкапсуляцию и все такое).

Объявление переменных

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

function foo() {
  a = 2;
  b = 3;
  return a+b;
}
alert(a); // undefined
a = 'очень важное значение';
alert(a); // очень важное значение
foo();
alert(a); // 2

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

Явно объявлять переменные можно и нужно ключевым словом var.

var a = 2;

Такая строка всегда создает новую локальную переменную. Если объявление происходит вне функций, то она будет глобальной, что вполне логично.

function foo() {
  var a = 2;
  var b = 3;
  return a+b;
}
alert(a); // undefined
var a = 'очень важное значение';
alert(a); // очень важное значение
foo();
alert(a); // очень важное значение

Как объявить глобальную переменную из функции? Как обратиться к глобальной переменной, если есть локальная с таким же именем? Очень просто – нужно обратиться к ней как к свойству window:

function foo() {
  var location = 'location';
  alert(location); // вернет 'location'
  alert(window.location); // вернет window.location
  window.a = 'переменная из функции';
}
alert(a); // undefined
foo();
alert(a); // переменная из функции

Наследование области видимости

Меня всегда смущало то, что в Javascript можно определять функции внутри функций, а использовать их потом где угодно. Ну да, если посмотреть, точно то же самое можно делать в Ruby, и, наверное, во многих других языках тоже.

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

function alertOnTimeout(message, timeout) {
 return setTimeout(function() { 
    // message будет доступен в безымянной функции, переданной таймауту
    alert(message); 
  }, timeout);
}

Передача кода по старинке – строкой, которая прогоняется через eval() – не попадает под это правило, код исполняется в той области видимости, где и определен.

Поскольку объекты в Javascript – это тоже типа функции, то свойство объекта определяется точно так же, как и переменная.

function myObject() {
  var property = 0;
  // Cамо собой, property будет доступно только внутри объекта.
}

А еще в Javascript область видимости переменной ограничивается только функциями, а не блоками типа if (привет, Паскаль). Потому удобнее всего объявлять переменные в начале функции.

this

А что this? А то, что эта переменная автоматически появляется в методах объектов и затирает значение this из предыдущей области видимости. Решение простое – переприсваивать ее значение другой переменной.

$('div.with-links').click(function() {
  var theDiv = this; //сохраняем значение this
  $(this).find('a').click(function() {
    alert($(this).attr('href')); // this - это ссылка
    theDiv.remove(); // а theDiv - это все еще дивак
  });
});

Отдельно замечу, что при оборачивании какой-то поведенческой логики в объект надо помнить, что в создаваемых DOM-событиях значение this самого объекта теряется.

function myObject() {
  var _this = this; // сохраняем ссылку на родительский объект
  var linkRemoved = false;
 
  $('a').click(function() {
    $(this).remove(); // this - это объект ссылки
    _this.linkRemoved = true; // _this - это родительский объект
  });
}

Javascript: Подсказки внутри INPUT 16 февраля 08

Второй обещанный скрипт с lyrified.com.

Вывод какого-то текста в <INPUT>, когда он пустой:


Как видите, работает и для <INPUT TYPE="password">
читать дальше →

Растягивание TEXTAREA по вертикали 15 февраля 08

Решил опубликовать пару скриптов, написанных для lyrified.com.

Итак, растяжка <TEXTAREA> по вертикали. Вообще-то, растяжка любого блочного элемента по вертикали, но применялась именно для текстовых полей.

Проблема: текстовые поля, как правило, или слишком большие, или слишком маленькие. И то, и другое неудобно. Хорошо бы дать возможность изменить высоту поля

Это выглядит вот так:

 

Тестировалось в IE 6, 7, Firefox 2, 3, Opera 9, Safari 2.
читать дальше →