Как стать автором
Обновить

Комментарии 215

Вопросы от VitaZheltyakov:
— Чем заменить eval?
— Как проиграть звук используя JS без flash? Какие форматы поддерживаются?
— На сколько использование глобальных переменных замедляет скрипты?
— Как определить какая кнопка мыши нажата на JS?
— Как запретить выделение текста на JS?
— Как решить проблему остановки gif-анимации при нажатии ESC, если эта клавиша забиндована?
мне кажется некоторый вопросы самому можно раскопать
1) смотря где заменять, погуглите, а так вот статейка javascript.about.com/library/bleval.htm
2) вот тут предоставлю слово авторам
3) не думаю что сильно замедляют, ведь по сути это свойста window (или другого коневого объекта). при обращении к переменной myvar js обходит цепочку объектов до родительского пока не найдёт вашу переменную или пока не дойдет до конца, от глобальных перменных скорее отказываются потому, что нельзя слишком засорять глобальное пространство имен, во избежание конфликтов
4) тут вам гугл в помощь и свойства объекта event
5) habrahabr.ru/blogs/webdev/18080/ но вопрос малоактуальный на практике
bleval.htm
просто бросилось в глаза…
3) Обращение к переменным из другого scope (замыкания) как правило занимает больше времени, чем обращение к элементам из текущего
я это и говорил.
Просто я не представляю где это может быть критично это раз, а во вторых где вы будите столько глобальных переменных использовать чтобы ощутить критичность?
Дело не только в количестве переменных, но и в количестве обращений. То есть, изменение глобальной переменной (или переменной не из локального scope) 1 миллиард раз будет медленнее, чем локальной.
Я когда-то делал (портировал с Java) спецэффект на canvas: media.chikuyonok.ru/ripple/
Так вот, он медленнее всего работал в FF 3.6. Во время профайлинга выяснил, что больше всего времени занимает доступ к переменным из другой области видимости (где-то на 2 уровня выше). Когда сделал локальные ссылки на них, производительность выросла в 2—3 раза.

Поянтное дело, что это исключительный случай, когда в цикле перебирается миллион элементов, но всё же на производительность может повлиять.
я не спорю! может!
Вообще хорошо когда все берёшь из контекста, это самое быстрое! а уже на уровень выше это должно сводиться к минимому. А глобальная это уже вообще на перечет
оффтоп: почему-то он на маке неправильно работает в фф (круги в неправильных местах рисует), а в хроме всё отлично
2) В Mozilla как раз сейчас экспериментируют с Audio API
НЛО прилетело и опубликовало эту надпись здесь
Спрашивайте. Если мы не сможем развернуто ответить, то будет рассчитывать на помощь DmitryBaranovskiy
Не надо на меня рассчитывать. Я не специалист по ExtJS.
Ага. Дмитрий с нами не пьёт!
Не наливают, вот и не пью.
Для чего используется такая конструкция?

(function() {

})();
1. Для эмуляции приватных свойств и методов в объектах
2. Для создания «атомизированного» кода. Например, если нужно в jQuery навесить какие-нибудь 2 события, чтобы они обменивались между собой данными, но захламлять глобальную область видимости не хочется, то можно сделать так:
(function() {
var sharedVar = 0;
$('a').click(function() {
    alert(sharedVar);
    sharedVar = 12;
});
$('a').dblclick(function() {
    alert(sharedVar);
    sharedVar = 25;
});
})();
alert(typeof sharedVar); //undefined
спасибо, ясно
это обычное замыкание. Читайте подробней про замыкания, там все описано. очень важная тема в js
Что такое замыкание (в пределах обычной функции) я знаю, меня интересовала именно эта хитрая конструкция.
А вообще, у нее есть еще какие-нибудь применения?
habrahabr.ru/blogs/webdev/38642/ почитайте, тут как раз этот случай рассмотрен
Конструкция не такая уж хитрая. Объявляется анонимная функция (если точнее — то это function expression) и тут же, на месте, вызывается.
Применений много, погуглите, например, module revealing pattern.
В эту функцию можно передать параметры и вызвать ее через call/apply
А что такое оператор (), с помощью которого замыкание создали?
Эта конструкция не имеет отношения к замыканиям. Точнее, не более чем любая другая функция в JS. Любая функция в JS может захватывать контекст, в котором она была объявлена.

Скобки, которые окружают объявление функции, просто меняют порядок, грубо говоря. Ср.:
new Date().getDate() и (new Date()).getDate().
Хотелось бы подробнее, что меняется от установок скобок вокруг чего-либо. Так как например проверка alert==(alert) дает true.
Тут я сам «плаваю», честно говоря.
Seldon, есть нет что ответить кроме «гугли» — лучше не отвечать =)
Для начало человек спросил что за конструкция, так как никто не сказал что замыкание, я это озвучил и отправил в гугл так в комментарии описать что такое замыкания невозможно. далее дал человеку ссылку на конкретное описание из топика хабра где есть пояснения, как опять же меня и просили habrahabr.ru/blogs/javascript/119851/#comment_3922470

так что к чему комент я не знаю
Для начала надо понять разницу между function expression и function declaration. Скобки вокруг позволяют сделать из неё не function declaration, а function expression. Есть и другие методы:
!function () {
  // source
}();

+function () {
  // source
}();

[function() {
  // source
}()];


Она используется в т.ч. в jQuery. Позволяет выделить весь код в один блок с локальной областью видимости. Это ускоряет доступ к внутренним переменным, позволяет на захламлять глобальное пространство имён и, главное, лучше сжимается минификаторами.
Это интересно. А если вкратце, то для чего нужны !, + и []? Последнее делает из функции список? А зачем?
Потому что если сделать просто:
function () {
  // source
}()

То это будет function declaration и оно не заработает. Нам надо вставить функцию в какое-либо выражение, чтобы сделать из неё function expression. Мы можем воспользоваться любым выражением, например
42 * function () {
  // source
}();

Просто те выражения, которые я показал самые короткие, потому используются чаще всего.
А, т.е. это по сути эквивалент оборачиванию в скобки?
Да.
Спасибо, ясно
Это и так function expression:
function () {
  // source
}

Ибо function declaration обязано иметь имя. И никакой иной вод кроме этого она не может иметь:
function blabla() {
  // source
}

Она не может стоять в состоянии выражения. На самом деле тут ошибка парсера.

Пример
function () {
  // source
}()
В этом случае мы получаем SyntaxError из-за отсутствия имени функции (функция-декларация всегда должна иметь имя).

function foo() {
  // source
}()
Во втором случае имя задано (foo), и по идее, декларация функции должна пройти нормально. Однако, мы всё равно имеем ошибку синтаксиса, но уже, касаемо оператора группировки без выражения внутри. Обратите внимание, в данном случае — это именно оператор группировки, который следует за декларацией функции, а не скобки вызова функции!

По материалам dsCode Тонкости ECMA-262-3. Часть 5. Функции. — Вопрос “о скобках”
я иногда немного в другом виде использую такое для выполнения блока кода с разными параметрами:

function DoOneThing(){
 ...
}
function DoOtherThing(){
 ...
}

(function f(name,cb){
 $('<button/>')
  .appendTo('#container')
  .addClass('commonClass')
  .text(name)
  .click(cb);
return f;})('Одна',DoOneThing)('Вторая',DoOtherThing);


Понятно, что можно так же объявить обычную функцию, но так просто короче.
Поступили ещё вопросы:
— Допустим у нас есть какой-нибудь DOM-объект с изначально заданными при помощи HTML и CSS параметрами «А». В процессе работы мы динамически меняем параметры на «В». Существует ли простой способ «сбросить» состояние объекта первоначальное состояние «А»? Аналогично с событиями. Как сделать откат на первоначальное состояние?

— Допустим на действия пользователя в ajax-системе сервер присылает ответ «alert('Бум!!!');». На клиенте полученный ответ прогоняется через eval() и выполняется. Как называется такая передача данных? Это не JSON, не XML, не HTML.

— Как корректно передавать js-команды с параметрами в ajax приложениях без возни с кавычками? Это относится к передаче данных в ajax-системе, описанной выше способом. При передаче сложных команд с несколькими уровнями вложенности параметров (например, «setTimeout('alert(»Бум!!!");', 200);" ) наблюдаются проблемы при использовании кавычек. Как их разрешить или есть ли какие-нибудь общие правила их оформления?

— Как корректно организовать очередь выполнения команд с задержкой без подвисания всего скрипта?
1) Очистить конкретное свойство с помощью jQuery можно так: $element.css({width: ''}); Если вы хотите сбросить все свойства, то нужно просто убрать атрибут style, через который и задаются все css-свойства с помощью javascript. $element.removeAttr('style'); Конечно, это уберет и те стили, которые вы задали прямо в html свойстве style, но им лучше вообще не пользоваться.

2) Это называется javascript :)

3) В функцию setTimeout можно передавать не строку с исходным кодом, а непосредственно функцию, которую нужно выполнить:
setTimeout(function() {
    alert("Бум!!!");
}, 200);
Вопрос не про передачу в функцию setTimeout, а передачу функции setTimeout, в которой определяется какая то функция, в другую функцию.

"заяц, а в зайце яйцо, а в яйце setTimeout, а в нем alert"
При использовании JSON все вложенные кавычки и прочие символы будут правильно encoded автоматически
1) Видимо имелось ввиду возврат к состоянию А из состояния В.
2) Это ближе к JSONP, чем к javascript
3) Передавайте данные в виде JSON или JSONP, сейчас практически для каждого языка программирования есть модуль для кодирования в JSON
4) Используйте WebWorkers: они не будут зависеть друг от друга
Не пишу на JavaScript, поэтому позвольте поинтересоваться:
Передача js-команд с прогоном через eval() секъюрна?
Вопрос возник потому что, будучи разработчиком на php/python, считаю более правильным реализовать JSON/JSON-RPC и хэндлить эксепшены, нежели мучаться с защитой eval()'а.
eval ещё и дорогая операция. Для каждого способа лучше конечно свой подход, но что вы понимаете под словом секьюрна в данном случае?
От eval лучше вообще отказаться. Для своей реализации JSON-RPC в одном из проектов использую примерно такой код с некоторыми модификациями и проверками:
/**
 * Invoke method of object by name
 *
 * @param {string} methodName Method name to invoke.
 * @param {array} params Arguments array.
 */
function invoke(methodName, params) {
	var arr = methodName.split('.');
	var parent = ((function () { return this; }).call(null)); // get global context
	var funcName = arr.pop();
	for(var i = 0; i < arr.length; i++) {
		parent = parent[arr[i]];
	}
	return parent[funcName].apply(parent, params);
}

// Example
var obj = {};
obj.foo = {};
obj.foo.bar = function(a, b) {
	return 'bar ' + (a + b);
}

alert(invoke('obj.foo.bar', [1, 2]));
3)
Первый пример javascript.ru/setTimeout отлично выполняется с передачей параметров.
Или я неправильно понял вопрос?

2) Это называется «у нас проблемы с архитектурой приложения»
Ок… как без кросдоменных вызовов прикажете мэшапы делать?
то есть вы еще и кроссдоменные запросы делаете?)
Что в этом такого, если соответствует задачам проекта?
Как корректно передавать js-команды с параметрами в ajax приложениях без возни с кавычками?

Вам нужен метод bind. И хотя он реализован только в современных браузерах — его можно реализовать даже в IE6. Он уже есть у вас, если вы используете MooTools.

В частности, ваш код будет выглядеть так:
setTimeout(alert.bind(window, 'boom'), 200)
2й кейс это JSONP.
Это НЕ JsonP.
Ок, это почти JSONP :)
Я бы сказал, что JSONP — это частный случай того, о чём спрашивает автор)
1. Я советую добавлять дополнительный класс к элементу. С переопределением свойств в CSS. Для восстановления исходного значения удалять класс.

3. можно например кодировать в base64

4. что-то типа этого:
actions = [...];

setTimeout(function() {
i = 0;
return function() {
actions[i](); i++;
if(i < actions.length)
setTimeout(arguments.callee , 200);
}
}(), 200)
А отвечать на вопросы тут в комментариях можно, или нужно сохранить интригу? :)
Отвечайте, чего тянуть ;)
1) Для чего в jQuery передавать window если он и так глобальный и зачем undefined? Вот тут:

(function(window, undefined) {
...
})(window);


2) Можно ли как-то узнать что юзер закончил ресайзить окно?
3) Как узнать в какую сторону юзер крутит колесо мыши?
4) Как при помощи window.open() открыть именно новое окно, а не вкладку?
5) Есть ли событие focus у элемента , если нет, то возможно ли его реализовать?
у элемента option
1) Для того, чтобы при сжатии window в агрументах и в теле этой функции заменился на короткий символ (например a):
(function(a){ a.do.something(); })(window);
3) Смотрите документацию объекта event, но вообще я рекомендую использовать готовые решения.
5) Есть события focus и blur
1) чтобы код внутри не переопределил эти важные значения.
2) событие onresize поступает именно в этот момент.
3) onscroll, потом определяем координаты текущего окна относительно документа
4) насколько я знаю, в общем случае, никак
5) есть
4) попробовать можно, но, например, в «Опере» это ничего не даст.
>>> событие onresize поступает именно в этот момент

Разве? Хорошо, тогда спрошу более конкретно. Как мне изменить размеры элемента только после того как я закончил ресайзить окно? В Хроме, ФФ и прочих хороших браузерах ресайз происходит сразу.
Вот этого вопроса я не понял, извините.
<!DOCTYPE HTML>











Видите, цифры при ресайзе окна меняются сразу (изменяйте размер окна мышкой). Возможно ли чтобы изменения происходили только после того как резайз окончен?
Не умею еще работать с редактором…
Не вижу никаких цифр и вообще ничего.
1) Для чего передавать window я не знаю, а вот с undefined история интересная:

Дело в том, что в JS нет зарезервированного слова, обозначающего этот тип данных, как например, false, или null:
>>> false = true
Unhandled exception:
Cannot assign to 'false'
>>> undefuned = 'foo'
"foo"

Переменная undefined имеет значение undefined точно также как и любая другая неопределенная переменная, лишь до тех пор пока её не определят. А определив её, можно порушить логику программ, сравнивающих значения if (a === undefined). Поэтому корректным способом проверки значения на undefined является довольно громоздкая конструкция typeof a == 'undefined'. Но конкретно в jQuery используется более изящный способ: анонимная функция объявляет, что она принимает второй параметр, но при вызове он не передается. Таким образом, переменная undefined внутри этой функции будет гарантированно иметь значение undefined.
Говорю же вам, это делается только для сжатия. И то это вопрос очень много оспаривали, потому что якобы он замедляет скрипт.
Вы неправильно говорите. В вопросе конкретный пример:
(function(window, undefined) {
...
})(window);

Какое уж тут сжатие.
(function(window, undefined) {
window.a = 1;
window.b = 2;
if (window.c === undefined) {
window.d = {
x: undefined
};
}
})(window);

превращается в:
(function(a,b){a.a=1;a.b=2;if(a.c===b)a.d={x:b}})(window);
Это для примера
Вы совершенно не читаете что вам другие люди пишут?

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

Идею homm я поял, в комментариях уже извинился. Но в основном это делалось по другим причинам.
Я прекрасно понимаю, что это может использоваться для сжатия.

Просто заданный вопрос был по другой теме.
«Для чего в jQuery передавать window если он и так глобальный...» разве не это было вопросом?
Мой ответ: «Для того, чтобы все упоминания window в коде были при сжатии заменены на короткий символ, и общий размер файла уменьшился»

Вы не видите логики в ответе? Я очень много общался с jquery contributors и, можете поверить, что это и есть главная цель данной хитрости
Теперь вижу.

undefined там тоже вторым параметром для этого? Боюсь, те контребьютеры, с которыми вы общались, просто не в теме, это обычный приём для защиты этих важный объектов для изменения.
Насчет, undefined соглашусь с вами и с homm, но и для сжатия это хорошо тоже
Всё-таки сжатием JS я иногда занимаюсь. Вот, например:

bolknote.ru/files/tank-1k-game-2/
Говорю же, не только (прочтите сначала, то что я написал).
Извините, невнимательно прочитал. (Хотя смысл в этом есть, но больше смысла будет при сжатии все-таки. Посчитайте, сколько раз undefined в коде встречается у них)
Для чего передавать window я не знаю

Очевидно, это просто замыкание, чтобы jQuery внутри себя как угодно мог менять объект window, но при этом в глобальной области видимости он не менялся.

console.log(window);

(function(window){
    window = 'a';
    console.log(window);
})(window);

console.log(window);
Если мы говорим о абстрактной функции и абстрактном параметре, то может и для этого использоваться. Конкретно в Jquery window внутри этой анонимной функции не меняется.
не меняется.


как минимум
window.jQuery = window.$ = jQuery;
homm имел в виду замену объекта целиком, вроде window = 'wtf with window???'
И что? window не изменяется, изменяются его свойства, которые точно также будут видны в console.log(window) после выполнения анонимной функции. Утверждение «чтобы jQuery внутри себя мог менять window, но при этом в глобальной области видимости он не менялся» не верно.
точно, косяк
Все сложные типы передаются по ссылке. Внутри можно как угодно менять, и он поменяется снаружи.
да, я забыл про это, мой косяк
>>> Таким образом, переменная undefined внутри этой функции будет гарантированно иметь значение undefined.

Спасибо! Интересно :)
можно покороче a === void(0)
Как эффективно сделать глубокое копирование (deep copy)? Как сделать неизменяемый обьект (freez)?
Как сделать аналог деструктора/финализатора? И вообщем, как управлять временем жизни объектов?
Возможно ли сделать кастомную реализацию DomElement так чтобы при разборе для подмножества тегов использовалась она?
var a = {prop: 'val'};Object.freeze(a);
Сказали бы тогда также, как лучше всего получить реализацию freeze в ES3?
Никак.
Можно ли сделать обработку бинарных данных? Если да, то как?
В ECMAScript 6+ (strawman) есть черновик StructType (это struct знакомый нам из С++ и других). Он нужен для упрощения работы с двоичными файлами. Вот как это может выглядеть в будущем:
const Point2D = new StructType({ x: uint32, y: uint32 });
const Color = new StructType({ r: uint8, g: uint8, b: uint8 });
const Pixel = new StructType({ point: Point2D, color: Color });
 
const Triangle = new ArrayType(Pixel, 3);
 
let t = new Triangle([{ point: { x:  0, y: 0 }, color: { r: 255, g: 255, b: 255 } },
                      { point: { x:  5, y: 5 }, color: { r: 128, g: 0,   b: 0   } },
                      { point: { x: 10, y: 0 }, color: { r: 0,   g: 0,   b: 128 } }]);
Какой клиентский MVC-фреймворк посоветуете? Я сегодня поглядел на Backbone.js — понравился.
Очень хорош Ext/Sencha, но он сильно привязывает к своей модели приложений. Более свободный в этом плане — Backbone.js тут я описал принцип работы с ним. Ещё стоит обратить внимание на knockoutjs.
Поступил ещё один вопрос:
Хотелось узнать про работу с файловой системой через JavaScript, например читать и писать в файлы. В большинстве учебников описывается JavaScript для браузеров, где работа с файлами не нужна, но например в серверном приложении или например в XUL- это необходимость, но документации крайне мало, если вообще она есть.
Касательно серверного приложения: в node.js все очень просто и понятно: nodejs.org/docs/v0.4.8/api/fs.html?
А по поводу браузеров — можно почитать тут: www.w3.org/TR/FileAPI/
Это не V8, это Webkit. А в целом, да
+ можно использовать моззиловский Rhino с Java классами. :(
Вы бы ещё некоторые вопросы и ответы выносили в сам топик. А то когда-нибудь потом, когда надо будет что-нибудь из приведенных вопросов, читать 100500 страниц вопросов, ответов и всяческого левого бреда не возникнет желания.

И вопрос в догонку: как объявить глобальную функцию в node.js, но во вспомогательном файле, так что бы его можно было вызвать через require() (надо создать библиотеку функций).
ответ нашёл сам:
global.echo=function(data){
	console.log(data);
}

продекларирует функцию echo для всего и вся.
можно ли каким-то образом эмулировать деструкторы/финализаторы у объектов?
Только если удалять их вручную, а не Garbage Collector'ом.
Как нормально обойти bugs.jquery.com/ticket/8836?
Сейчас как временное решение использутеся
if ($.browser.msie && parseInt($.browser.version, 10)) {
event.pageY = event.pageY - 32
}
Как воспроизвести баг?
вопрос:

var primer = function (){

вызываем_некую_функцию();
// функция инициализировала 100500 переменных внутри функции primer,
// приватных переменных, не глобальных

PROFIT();
}

можно ли так сделать вообще?
1. Можно предать ссылку на объект контекста primer в smth
2. Передать функцию, порождённую в контексте primer в функцию smth
var primer = function (){
    var a, b, c, d, e = {};

    smth(function () {
        a = 1; 
        b = 2;
        c = 3;
        d = 4;
    }, e);

    alert([a, b, c, d, e.pewpew]);
},
smth = function (callback, e) {
    callback();
    e.pewpew = "pewpew";
};

primer();

3. Раньше (FireFox 3.6-) можно было достучаться к контексту через __parent__, но в 4 версии выпилили эту возможность.
3) Слава богу
Спасибо!
Думал вообще говоря о другом, эти Ваши варианты понятны.

var primer = function (){
   // в теле данной функции до следующей строчки ВООБЩЕ НИЧЕГО НЕТ, не написано
   Unbelievable_Function_For_Instancing_Of_Our_Variables();
   // функция инициализировала 100500 переменных внутри функции primer,
   // например переменную This_Is_Awsome_Variable, для которой раньше
   // не было дано определения через var
   // но которая теперь есть, и она не из глобальной области
   // и теперь мы можем делать так:

   This_Is_Awsome_Variable = 'ПиуПиу';
  
   // не опасаясь, что она из глобалов.

    /// PROFIT !!!
}


* This source code was highlighted with Source Code Highlighter.
текущий контекст данной функции, «замкнутый»,
чтобы в него «вернулся» контекст другой функции, в котором определены переменные,
и чтобы потом их можно было использовать в primer()
так, как будто они в ней самой и определены.

вот.

Т.е. каким либо образом кинуть в
Unbelievable_Function_For_Instancing_Of_Our_Variables()
текущий контекст данной функции, «замкнутый»,
чтобы в него «вернулся» контекст другой функции, в котором определены переменные,
и чтобы потом их можно было использовать в primer()
так, как будто они в ней самой и определены.

вот, целиком.

Нельзя)
Спасибо :)

Знаю, что нельзя, но очена хочется…

Можыть каким-нибудь «декоратором»?
var test = function(){
  var a = 1;
  var s = 2;
  return a, s;
}

var tester = function(){
  test();
  alert(a);
  alert(s);
}
tester();


* This source code was highlighted with Source Code Highlighter.
Когда будет деструтированное присваивание (Ecma6), то можно будет так:
var test = function(){
  var a = 1;
  var s = 2;
  return [a, s];
}

var tester = function(){
  [a, s] = test();
  alert(a);
  alert(s);
}
tester();
только чтобы оно работало
Т.е. каким либо образом кинуть в
Unbelievable_Function_For_Instancing_Of_Our_Variables()
Поступил вопрос:
На сервере blabla.ru лежит картинка, сервер не отдает её если передал Referer с другого сервера (pewpew.com). Как получить содержимое картинки и показать пользователю?
Написать ответственному за blabla.ru или автору картинки и попросить скопировать её себе на сайт? ;)
Уточню, как я понял: Сайт pewpew.com — свой, а blabla.ru — чужой. Чужой сайт не пойдет на уступки. Необходимо как-то обойти ограничения по Referer.
Забыл табличку «Сарказм», простите.

Вопрос:
Как оптимальнее использовать динамическую подгрузку js-скриптов и как это влияет на распределение памяти?
Какие особенности подгрузки js-библиотек в разных браузерах?
Подобная реализация, помоему, отлично сделана в extjs4, но хотелось обсудить эту реализацию на чистом языке.
Если можно — хотелось бы услышать пару слов, об уборке мусора в js — как он работает.
Спасибо.
Ещё один вопрос:
«Почему eval = evil?»
Медленно и небезопасно.
Кроме того, что eval медленно выполняется сам по себе, так он ещё не позволяет браузерам оптимизировать:




Ну и IDE его не разбирают.
Ещё вопрос:
Касательно статьи "Пять способов вызвать функцию". Какой из этих N способов (в заголовке 5, в статье 4, несколько в комментариях) когда применять лучше и почему?
И вот ещё:
— Можно ли перехватывать события нажатия клавиш клавиатуры (стрелка вниз, вверх) в javascript, так чтобы браузер после этого не выполнял прокрутку окна? Есть ли особенности среди браузеров в таком поведении, если оно вообще возможно? Например есть таблица, которая не влазит на экран целиком, при этом перемещение по строкам реализовано с помощью стрелок клавиатуры. Нужно, чтобы браузер не пролистывал при этом страницу.
— GOTO в Javascript. Собственно вопрос как повторить поведение goto в JavaScript. (Про хороший стиль и goto рассказывать не нужно :) речь идёт про генерированный код. и восстановление блоков и циклов процесс весьма не тривиальный)
так чтобы браузер после этого не выполнял прокрутку окна

тут есть два основных способа как я понимаю:
1. return false (либо event.returnValue= false) в обработчике события приведет к тому, что стрелка отработает как написано в обработчике, но пролистывание страницы не произойдет.
2. event.preventDefault — приведет к тому, что обработчик по-умолчанию для события (в данном случае — пролистнуть страницу) — не выполнится.

Разница между этими двумя способами (вроде) в кроссбраузерности — в некоторых браузерах preventDefault не работает.

Кроме кроссбраузерности разница еще в бабблинге, если сделать return false то отработает обработчик только того элемента, c которым произошло событие, а если сделать preventDefault то по очереди вызовутся обработчики также всех родительских элементов.

Чтобы выключить бабблинг без выключения обработчика по-умолчанию надо использовать event.stopPropagation()
— GOTO в Javascript.
Частично может помочь label
Можно ли перехватывать события нажатия клавиш клавиатуры (стрелка вниз, вверх) в javascript, так чтобы браузер после этого не выполнял прокрутку окна?
Для этого необходимо отменить, так называемое действие по умолчанию(Default Action): стрелка вниз и колесо мыши скролит окно, правая кнопка мыши поднимает контекстное меню, по клику на sumbit выполняется form.submit(), при клике на input он получит фокус, при клике на анкор браузер перейдет по ссылке и т.д.

Используя jQuery это можно сделать так:
// ИЕ и сафари не отслеживает стрелки на keypress, а Опера глючит на keyup
$(window).bind($.browser.opera ? 'keypress' : 'keyup', function (event) {
    event.preventDefault();
    // или
    return false;
});

Тут есть важный момент. Необходимо выполнить preventDefault() до того, как выполнится defaultAction. Например при клике на input мы не хотим передавать ему фокус, тогда надо повесить обработчик на событие в цепочке до выполнения defaultAction — mousedown.
// ИЕ и сафари не отслеживает стрелки на keypress, а Опера глючит на keyup
$('input').bind('mousedown', function (event) {
    event.preventDefault();
    // или
    return false;
});

Сама цепочка такая:
1. mousedown
2. focus (перед фокусом сработает blur на другом объекте)
3. mouseup
4. click
Если мы повесим событие на focus и ниже, то ничего не получится т.к. defaultAction отработает после mousedown.
Наследование в JavaScript.

Есть например
var Human = function() {
    this.walk = function() {}
}

// Как идеологически правильно заэкстэндить Man и Woman от Human
var Man = function() {}
var Woman = function() {}
Про наследование в JS очень хорошо, полно и много написано у Ильи Кантора:
javascript.ru/tutorial/object/inheritance
Может пора уже научиться курить маны?
Как передать scope выполнения одной функции в другую?
Pavel Pavlov:
Здравствуйте, очень бы хотелось узнать про работу с файловой системой через JavaScript, например читать и писать в файлы. В большинстве учебников описывается JavaScript для браузеров, где работа с файлами не нужна, но например в серверном приложении или например в XUL- это необходимость, но документации крайне мало, если вообще она есть.


Дмитрий:
Привет. В рамках поста из темы и ликвидации безграмотности хочу задать свой вопрос.
Можно ли перехватывать события нажатия клавиш клавиатуры (стрелка вниз, вверх) в javascript, так чтобы браузер после этого не выполнял прокрутку окна? Есть ли особенности среди браузеров в таком поведении, если оно вообще возможно?

Например есть таблица, которая не влазит на экран целиком, при этом перемещение по строкам реализовано с помощью стрелок клавиатуры. Нужно, чтобы браузер не пролистывал при этом страницу.

С уважением к вам и вашему времени


Anatoliy Elsukov:
День добрый,
ну раз уж написал, задавайте вопросы по JavaScript, то ловите:

GOTO в Javascript.
Собственно вопрос как повторить поведение goto в JavaScript.
(Про хороший стиль и goto рассказывать не нужно :) речь идёт про генерированный код. и восстановление блоков и циклов процесс весьма не тривиальный)

Ой, некоторые уже скопировали, сорри.)
Возможно ли устроиться javascript программистом без копания в верстке и server-side?
Можете изучить Canvas =)
Хотя, я думаю, если знаете ExtJS, то можно.
Ну и, верстку достаточно знать очень поверхностно.
Reflow, repaint и методы их минимизации.
НЛО прилетело и опубликовало эту надпись здесь
1) Они используют Google Web Toolkit
2) JSON, JSONP, XML? Поясните, пожалуйста, вопрос, если я вас неправильно понял
gmail использует Google Closure, а не GWT.
Я, конечно, не знаю деталей того, что использует Google, но в чём проблема использовать GWT вместе с Google Closure? Ведь код на Java при помощи GWT может транслироваться в JavaScript код на базе GC.
Может так и можно, не уверен, но конкретно GMail GWT не пользуется. А Wave, в свою очередь, пользуется. Я просто уточнил.
Хотелось бы увидеть вопросы оптимизации элементарного кода, чтобы они находились в одном FAQ.
Например что лучше:
obj.attr или obj[«attr»]
Как лучше складывать строки:
str1 + str2 или str1.concat(str2)
Что лучше:
var a1 = new Array() или var a1 = []
И т.д.
1) obj.attr
2) для небольшого размера строк и маленького количества лучше просто «a + b», а если много: [a, b, ..., c].join('')
3) var a = [];
Вопрос от меня. Как корректно получить глобальный объект без его прямого указания, без eval и при 'use strict'.
// не подходит, т.к. явное указание
var global = GLOBALS || window;

// Не подходит, т.к. не сработает в strict-mode.
var global = function () { return this; }();

(function(){
    "use strict";
    var globalObject = (0, eval)("this"); // Магия :)
    return globalObject;
}());
Прикольно) Но слишком волшебно( Неизвестно, когда и где перестанет работать. Тем более, была просьба «без eval», т.к. плохо парсится IDE и плохо оптимизируется.
По-моему в данном случае eval не должен влиять на парсинг и оптимизацию, т.к. это просто функция как объект, а не исполнение.
тот же eval — вид сбоку
Простите, не нашёл ответа на свой вопрос. Не могли бы вы процитировать?
> «use strict»;
> var global = (function(){ return this || (1,eval)('this') })();
Хочется без eval…
Хочешь чего-то невозможного :)
Там как раз описывается, что согласно спецификации такое возможно только при косвенном вызове eval.
А вообще, так не подойдет?

«use strict»;

(function( global ) {
return global;
})( this )
Не сработает
проверил — сработало.
пересмотрел стандарт, там говориться только про в this в функции, которая вызывается вне объекта.
по сути, this в глобальном контексте, указывает на глобальный контекст, а this в функции не получит доступ к глобальному контексту
А в node.js — не сработает ;)
Они же там v8 используют.
Так, что, нужно посмотреть, google это реализует.
Да ну (но в V8 пока нет "use strict"):
$ node -v
v0.4.5
$ node
> (function(){ return this || (1,eval)('this') })() === global;
true
Не совсем чистый JS.
Можно ли подцепить(эмулировать) поведение DOMInputElement'a с помощью обыных DOMElemen'ов(div)?
Например событие blur.
Мне было бы больше всего интересно послушать про паттерны. Какими чаще всего пользуетесь вы в разработке? В каких ситуациях стоит их использовать, а в каких не стоит? Какие есть реализации одних и тех же паттернов и какие между ними различия? Хотелось бы вообще увидеть большую развернутую статью на эту тему. Спасибо.

P.S. А на мой вопрос по канвасу так и не ответили (((
P.S. А на мой вопрос по канвасу так и не ответили (((

Это какой?
Нашел.
Нашёл.
Мне было бы очень интересно послушать про типовые реализации основного функционала canvas-библиотек, таких как: эмуляция слоев, определение активного элемента (на котором в данный момент находится курсор), создание системы управления событиями и т. д.


Я даже целый топик вам в ответ написал)
Вообще не понял, как это я умудрился пропустить.)) Большое спасибо.
Добрый день, подскажите возможно ли в javascript после перехвата события перезапустить его позднее, например:
$('#smth').click(function(e){
  //прервать событие
  e.preventDefault();
  // передать левому объекту
  leftObject.setSomeEvent(e);
})
// а затем внутри того "левого объекта" запустить начальное событие со всеми его свойствами и т.п.

Надеюсь приблизительно понятно объяснил.
use callback functions?
event не несет никакой нагрузки это просто дескриптор события. Но можно явно передать ссылку на обработчик события, вот так:
$('#smth').click(function onSmthClick(event){
    //прервать событие
    event.preventDefault();
    // Прописать обработчик
    event.handlerFunction = onSmthClick;
    event.handlerContext = this;
    // передать левому объекту
    // теперь otherObjectSetSomeEvent может использовать event.handlerFunction и вызывать обработчик
    otherObjectSetSomeEvent(event);
});
Но это не удачное решение, т.к. придется ещё много чего лишнего накрутить. И логика получается очень запутанная.

Лучше переделать логику и разделить общий обработчик на 2 части:
$('#smth').click(function handler1(event){
    //прервать событие
    event.preventDefault();
    // передать левому объекту
    leftObjectSetSomeEvent(event, function handler2(e) {
        // делаем что-нибудь с event или e
    });
});

function leftObjectSetSomeEvent(event, callback) {
    callback(event);
    // делаем что-нибудь с event
}
Ещё один вопрос:
«У меня есть проблема с пониманием прототипной модели, привык к «классической» классовой :) но вот решил изучить JS. Просьба, если возможно, напишите статью где в виде паттернов объясните возможные варианты построения «классов», разных уровней видимости методов и переменных. Понимаю что подобные статьи можно найти в огромной кол-ве, понимаю что в JS как-бы «не нужны» уровни видимости. Но я бы хотел что-то типа ответа здесь stackoverflow.com/questions/1635116/javascript-class-method-vs-class-prototype-method»
В jquery 1.6 перестало работать свойство curAnim. Как модифицировать код первой странички сайта, чтобы перейти на 1.6? Советуют jquery ui, но как-то уж больно общий получается совет. Мне бы пример.
Два часа в дебаггере решают проблему с curAnim. Необходимую информацию удалось извлечь из fx.end.
а вы не думали написать свой справиочник по js?
Писал немного на JS использовал чуть чуть jQuery, и т.п.
Подскажите где углубленно изучить JavaScript?
Книги, туториалы?
Спасибо
НЛО прилетело и опубликовало эту надпись здесь
Неплохой подход. По крайней мере лучше, чем объявлять все методы в конструкторе)) Но чем плоха идея с префиксом-подчёркиванием?
Можно ещё его видоизменить так:

// our constructor
function Person(name, age){
    this.name = name;
    this.age  = age;
};

// prototype assignment
Person.prototype = new function(){

    // we have a scope for private stuff
    // created once and not for every instance
    function toString(){
        return this.name + " is " + this.age;
    };

    // create the prototype and return them
    this.constructor = Person;

    this._protectedMethod = function (){
        // act here
    };

    this.publicMethod = function() {
        this._protectedMethod();
    };

    // "magic" toString method
    this.toString = function(){
         // call private toString method
         return toString.call(this);
    }
};

НЛО прилетело и опубликовало эту надпись здесь
Таковы особенности языка, заложенные ещё при рождении, перетекшие из Self, Scheme
Ещё интересен модульный подход. В последнее время я его часто практикую:
var Module = (function (window) {
    function privateFunction() {
        console.log('pass');
    };

    var privateClass = function () {};

    var publicClass = function () {};
    publicClass.prototype.publicMethod = function () {
        privateFunction(); // ...
    };
    
    return { // Экспортируем
        publicClass: publicClass
    };
}(this));

// Используем
(new Module.publicClass()).publicMethod();
НЛО прилетело и опубликовало эту надпись здесь
Там другое, но возможно написать один модуль, который будет работать и в Node.js и в браузере и в воркерах. Вот, например, NumberConverter.js
Ещё вопрос:
«Как с помощью JS сделать одновременный выбор и загрузку нескольких файлов?»
Какие есть ли в JavaScript аналоги декларациям/аннотациям (термины из Python/Java соответственно)?
Никаких
Для чего они вам требуются? Могли ли бы вы привести пример?
Например, из моего текущего проекта: модуль приложения состоит из кучи функций, и надо часть из них пометить как доступные из других модулей по определённому сетевому механизму IPC. Сейчас это делаю с помощью
function anExampleFunctionWithLongDescriptiveName() { ... }
anExampleFunctionWithLongDescriptiveName.public = true;
anExampleFunctionWithLongDescriptiveName.args = {first: String, second: Object}
anExampleFunctionWithLongDescriptiveName.comment = "An example public function.";

Было бы идеально что-нибудь типа
@public
@args({first: String, second: Object})
@comment("An example public function.")
function anExampleFunctionWithLongDescriptiveName() { ... }
Как на JS перехватить все клики на странице по любым элементам? То есть сделать единый обработчик для кликов.
// jQuery
$(window).bind('click', function (e) {
    console.log('Clicked on ', e.target);
});
При загрузке файлов с использованием FIle и FormData — как определить не пытается ли пользователь загрузить директорию. Свойство File.type к сожалению не помогает (для некторых типов, как и для дир — пустая строка), свойство size — тоже (ff и сафари по разному показывают)
Вопрос:
«Суть такая мне нужно не используя jquery (будет как собственное АПИ сайта) создать аналог функции $.ajax (а/синхронный запрос )
нашел в интернете пример создания объектов: ru.wikipedia.org/wiki/XMLHttpRequest
но проблема в firefox, не работает, но проблем больше чем просто firefox, то авторизация то еще что нибудь)
Создал тему на форуме www.sql.ru/forum/actualthread.aspx?tid=853420 даже на таком форуме ответов нет.
Есть ли какая нибудь универсальная кросс браузерная функция ?»

С форума sql:
The ISA Server requires authorization to fulfill the request. Access to the Web Proxy filter is denied.

Ответ: Приведу в качестве примера недавно созданную функцию. Похоже ваш сервер требует basic auth, поэтому сразу изменю функцию:
function xhr(m,u,c,p,l,s,x){
    with(new(this.XMLHttpRequest||ActiveXObject)("Microsoft.XMLHTTP"))
    onreadystatechange=function(x){readyState^4||c(x)},open(m,u,false,l,s),send(p)
}
// Использование
xhr('get', 'http://path.to/server?with=parameters', function (xhr) {
    alert(xhr.status + ':' + xhr.responceText);
}, null, "username", "password");
Вопрос:
Какая модель создания объектов наиболее удобная? Если с new, то как защищаетесь от ошибок:
1. Функции-конструкторы пишу всегда с большой буквы;
2. Проверяют валидность создания через this instanceof Имя_функции (избегаю this instanceof arguments.callee по соображения производительности)
3. Аналогично второму, но сверяюсь с window, т.к. не хочу хардкодить имя и не пишу скрипты для out-of-browser сред.

Ответ:
Лучше, привычнее и идеологические создавать объекты через new. Конструкторы стоит называть с заглавной буквы.
Я предпочитаю основываться на соглашениях и не проверяю this внутри конструктора — вызвал конструктор без new и поэтому утекло в глобалы — значит «сам дурак». И не в коем случае не поощряю ошибку с new — некоторые проверяют если this это глобал значит пользователь вызвал конструктор без new и создают внутри конструктора объект и возвращают его — это поощрение ошибки и идеологически не верный подход.

Используя "use strict" все значительно проще:
var Obj = function () {
    "use strict";
    this.pew = 100;
};

// Правильно
new Obj.pew++;

// пользователь словит ошибку
Obj(); // TypeError: this is undefined

new не приемлем для factory методов, и коротких конструкторов — jQuery
Вопрос:
Стоит ли использовать childProcesses в node.js для каждого запроса в высоко-нагруженных проектах?

Ответ:
Для каждого запроса ни в коем случае не стоит использовать childProcesses потому, что мы получаем слишком много накладных расходов (это как PHP с апачем): выделение памяти, время форка, время инициализации (jid компиляция) и т.п. Node.js очень хорошо распределяет нагрузку и загружает одно ядро процессора в своем «evented processing loop» — основной поток приложения. Идеальная загрузка для Node.js — по 1му форку на ядро, лучше всего форкать, используя github.com/LearnBoost/cluster Кластер будет выступать в роли мастеров(балансир), а форки — слэйвы. Оправдано использование childProcesses для тяжелых запросов.
Можно ещё почитать тут: stackoverflow.com/questions/3491811/node-js-and-cpu-intensive-requests

Вопрос:
В node.js при использовании runInNewContext пропадают глобалы, а именно нет console.log Как правильно с этим бороться? Можно конечно в контекст добавить ссылку на console, но если понадобится еще какой-то глобальный элемент, а потом еще и еще… не прописывать же все? Думаю можно пройти в цикле по глобалу и передать все доступные объекты в контекст. Но насколько это правильно, может существует другое решение?
Речь идет о node-js.ru/12-control-context-using-runinnewcontext

Ответ:
Если понадобится другой объект, то придется добавить — такова политика сендбоксинга.
Единственное применение данной технологии я вижу для запуска чужого, потенциально опасного кода (так делает хостинг Node.js — nodester). Если же критической в этом необходимости нет, то я категорически против этого — это совершенно не нужная обертка, которую можно не использовать если выбрать правильную архитектуру приложения и использовать договоренности при разработке. Чем плохо: создание/удаление контектса — выделение памяти как следствие частый GC (который блокирует все приложение). Думаю будут проблемы с поддержкой такого кода.
запоздало, но только сёдня столкнулся лбом.

как грамотно привести небраузерные, синхронные CommonJS модули в потребный для браузера, асинхронный вид?
например, съедабельный RequireJS или Yabble, или что ещё есть на эту тему?
1. Асинхронная загрузка с использованием LABjs, $script.js, RequireJS и других.
require('pewpew.js', function () {
    new Pewpew();
});

2. Сбор одного цельного файла в препроцессоре.
/** #require('pewpew.js') */
new Pewpew();

// Препроцессор переделает этот код в какой-то такой вид:

/* pewpew.js */
var Pewpew = function () {};
// остальной код Pewpew...
new Pewpew();

Первый метод подойдет для каких-нибудь тяжелых API (карты). Второй для интерфейсов в которых надо все сразу (чаще так и бывает). Со вторым методом работать гораздо проще.
не совсем понял.
например есть три модуля:
foo.js:
exports.Foo = чонить;

bar.js:
exports.Bar = чонить;

main.js:
var foo = require('foo');
var Bar = require('bar').Bar;


как их сделать загружабельными в браузере?
Приводите их к универсальному модулю (чтобы они работали везде и в браузере и в ноде и в воркере)
// foo.js
(function(exports){}
    exports.Foo = чонить;
(typeof exports === "undefined" ? this : exports));

1. Подключаете как есть через тег script (они будут в window) в этом случае require('foo') не нужны
2. Используете любой асинхронный загрузчик модулей
// main.js
require('foo.js', 'bar.js', function () {
    new Pewpew();
});

3. Склеиваете все все скрипты и модули в 1-н большой файл с помощью препроцессора
// main.js
/** #require('foo.js') */
/** #require('bar.js') */

new Pewpew();

Препроцессор переделает этот код в какой-то такой вид:
// main.js
(function(exports){}
    exports.Foo = чонить;
(typeof exports === "undefined" ? this : exports));
(function(exports){}
    exports.Bar = чонить;
(typeof exports === "undefined" ? this : exports));

new Pewpew();
Добрый день!

а существует метод ограничить доступ функции к глобальным переменным (но не всем). Моей целью является дать пользователям небольшого приложения самим делать JS виджеты для манипуляции формами, но я не хочу, чтобы они были в состоянии отправлять AJAX запросы и пользоваться $ функциями.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории