совсем недавно очередной раз реализовывал. совсем по-другому получилось, но за статью спасибо — редко у кого хватает терпения для столь доступного стиля.
// сам класс:
function _WithEvent(types) {
var listeners = {}; // список слушателей, разделенный по типам событий
for (var i=0, l=types.length; i<l; i++) {
listeners[types[i]] = [];
}
this.addListener = function(type, fn, args, context) {
// добавляем случателя на события type:
// fn - исполняемя функция, args - 2й+ аргументы, context - this в исполняемом методе
listeners[type].push( new Listener(fn, args, context) );
};
this.fireEvent = function(type, data) {
// запускаем событие type, все св-ва из data перекочуют в первый аргумент
var evt = new Event(type, data);
for (var i=0, l=listeners[type].length; i<l; i++) {
if (evt.stoped) break;
evt.lastRet.push( listeners[type][i].fire(evt) );
}
return !evt.stoped;
};
function Listener(fn, args, context) {
// класс слушателей
this.fire = function(evt) {
try {
return fn.apply(context || this, [evt].concat(args || []));
} catch(er) {
return;
}
};
}
function Event(type, data) {
// класс события
if (typeof(data)=="object") {
for (var key in data) {
this[key] = data[key];
}
}
this.type = type;
this.lastRet = [];
this.stoped = false;
this.stop = function() {
this.stoped = true;
};
}
}
// и пример использования:
function Q(map) {
_WithEvent.call(this, [ "q", "w" ]);
var countQ = 0, countW = 0;
this.q = function() {
// запускаем событие "q" и смотрим (!success), не застопили его
var success = this.fireEvent("q", {curValue: countQ, nextValue:countQ+1});
if (!success) return;
// если не застопили
countQ++;
};
this.w = function() {
// аналогично q
var success = this.fireEvent("w", {curValue: countW, nextValue:countW+1, q: countQ});
if (!success) return;
countW++;
};
}
// подписываемся
var obj = new Q();
obj.addListener("q", myAlert);
obj.addListener("w", onW);
obj.addListener("w", myAlert);
obj.q();
obj.w(); // событие стопится, т.к. evt.q==1
obj.q();
obj.w();
function myAlert(evt) {
alert(evt.type +": "+ evt.curValue +" >> "+ evt.nextValue);
}
function onW(evt) {
if (evt.q==1) evt.stop();
}
да я не придираюсь, мне мой первый коммент показался самодостаточным (видимо, рабочая привычка).
кондишны… ну это как сказать, боремся-то мы с браузером и не хотим, чтобы пользователю из-за наших верстальщицких трюков хоть чуть-чуть хуже было. а тут секунда ради «без экспрешнов» — не думаю, что это логично. секунда-то она секундой, а когда пол-минуты?
ничего от такого экспрешна тормозить не будет, особенно учитывая, что body || documentElement зависит от доктайпа и (на продакшне) можно дополнительно сократить условие.
не похоже, чтобы «fixed разбирался», т.к. «считается по тегам COL».
так и думал, что спека сейчас будет, но практику тоже надо смотреть и обдумывать. дело в том (повторюсь), что табличка в ие6 по мере загрузки (как дивы) отображаться не будет. повторюсь, не будет. это очень большой минус, переводящий решение в ранг неполноценного.
без fixed — неполноценность в ие6 (и, думаю, не только в ие6), а с ним — не работает. только это упорно игнорируется. вот к чему весь сарказм.
«получаем» это не «у меню не срастается», а «у вас выходит». просто я объясняю (к сожалению, долго и упорно) почему решение мертворожденное, а вы ценность какую-то ищете…
PS я не злой, просто однобоких недорешений не люблю, особенно, когда они отстаиваются на пустых аргументах. «нет экспрешнов» — это действительно такой уж плюс по сравнению с табличкой? табличка в лаёуте — действительно только дело вкуса?
диалог, как в сказке: чем дальше — тем страшнее. но все предсказуемо.
ощутив нехватку знаний, вы полезли-таки в гугль. респект. но есть пара ньюансов: 1) вычитали не все и, соотв., 2) не смогли понять, зачем я написал первый коммент. // гугль, он такой, все ответы знает, только лениться не надо
чтобы добиться нормального блочного поведения (всегда пожалуйста, ваш КО), надо врубить fixed, а когда врубится fixed… // нет, действительно, в думалке ничего по этому поводу не созрело?
но это проза. подумав, получаем или еще один (sic!) tr (и, да, в ие6 не заработает), или недостраничку.
таблички показываются только тогда, когда целиком загружены (в ие6 точно), т.к. в table-layout по умолчанию значится auto (даже если width проставить всем ячейкам первой строчки), а при fixed — контент показывается в процессе загрузки таблицы. так-то.
«Кроссбраузерный min- и max-width на чистом HTML+CSS» слишком амбициозно звучит, чтобы автора дополнять, а кому надо — тот знает. точнее, помнит.
а с экспрешном в три действия, который min/max регулирует, думаете, будут жуткие подвисания с тормозами? в чем выигрыш-то, кроме как возможность делать min/max без мини-минимальнейших знаний о dom'е? только, плиз, не надо о ie6-пользователях без js: они js отключить могли специально для того, чтобы сайтики на все окошко тянулись ;)
приплыли… и что, действительно, по вашему скромному, это такой супер-пупер новый метод?
кста, уж раз браться за олд-скульные методы, то и про table-layout (который fixed) надо было бы черкануть.
1. структурные и порождающие шаблоны проектирования. оператор call :) с помощью которого можно добиваться private-поведения переменных; и это не будет особым извратом, поскольку, в отличие от (ручной) эммитации protected, call не требует лишних телодвижений от базового класса. классы могут находиться внутри других классов, это и к 1.1. относится.
1.1. перечислить наврядли, но паттерны как раз про это.
1.2. с головой, да, только, когда метод занимает три экрана, пора бы подумать о выведении части действий в другие методы, наверняка их можно обособить и потом реюзать. семь — число относительное, не помню где я его взял, но просто опираясь на него, тяжелее писать громоздкий, не структурированный код.
1.2.1. из любого правила есть исключения.
2. «методы должны описывать поведение сущностей» — просто и понятно, в отличие от моей копипасты, спасибо, запомню.
3.2. значит, у Вас уже есть, что написать :)
4. 90% кодеров, говоря «JS» — подразумевают: «jQuery». к сожалению, у них нет ни предпосылок, ни мотивации задумываться об этом.
5. скорость выполнения — это всегда хорошо, но, опять же, однозначного ответа быть не может.
речь о том, чтобы можно было быстро понять, что делает do1:
1. за счет краткости, а экран кода это совсем не мало
2. и не увлекаться бытовым ИИ, а делать вещи простыми, проще разобраться в 5 методах из 7 строк, чем в одном «умном» методе на 70 строк
3. умеренное использование упрощенных записей, т.к. в одну строчку можно и управлятор мира написать
// сам класс: function _WithEvent(types) { var listeners = {}; // список слушателей, разделенный по типам событий for (var i=0, l=types.length; i<l; i++) { listeners[types[i]] = []; } this.addListener = function(type, fn, args, context) { // добавляем случателя на события type: // fn - исполняемя функция, args - 2й+ аргументы, context - this в исполняемом методе listeners[type].push( new Listener(fn, args, context) ); }; this.fireEvent = function(type, data) { // запускаем событие type, все св-ва из data перекочуют в первый аргумент var evt = new Event(type, data); for (var i=0, l=listeners[type].length; i<l; i++) { if (evt.stoped) break; evt.lastRet.push( listeners[type][i].fire(evt) ); } return !evt.stoped; }; function Listener(fn, args, context) { // класс слушателей this.fire = function(evt) { try { return fn.apply(context || this, [evt].concat(args || [])); } catch(er) { return; } }; } function Event(type, data) { // класс события if (typeof(data)=="object") { for (var key in data) { this[key] = data[key]; } } this.type = type; this.lastRet = []; this.stoped = false; this.stop = function() { this.stoped = true; }; } } // и пример использования: function Q(map) { _WithEvent.call(this, [ "q", "w" ]); var countQ = 0, countW = 0; this.q = function() { // запускаем событие "q" и смотрим (!success), не застопили его var success = this.fireEvent("q", {curValue: countQ, nextValue:countQ+1}); if (!success) return; // если не застопили countQ++; }; this.w = function() { // аналогично q var success = this.fireEvent("w", {curValue: countW, nextValue:countW+1, q: countQ}); if (!success) return; countW++; }; } // подписываемся var obj = new Q(); obj.addListener("q", myAlert); obj.addListener("w", onW); obj.addListener("w", myAlert); obj.q(); obj.w(); // событие стопится, т.к. evt.q==1 obj.q(); obj.w(); function myAlert(evt) { alert(evt.type +": "+ evt.curValue +" >> "+ evt.nextValue); } function onW(evt) { if (evt.q==1) evt.stop(); }я вот, например, в очередной раз потратил 5 минут своей жизни, купившись на классный заголовок.
кондишны… ну это как сказать, боремся-то мы с браузером и не хотим, чтобы пользователю из-за наших верстальщицких трюков хоть чуть-чуть хуже было. а тут секунда ради «без экспрешнов» — не думаю, что это логично. секунда-то она секундой, а когда пол-минуты?
так и думал, что спека сейчас будет, но практику тоже надо смотреть и обдумывать. дело в том (повторюсь), что табличка в ие6 по мере загрузки (как дивы) отображаться не будет. повторюсь, не будет. это очень большой минус, переводящий решение в ранг неполноценного.
без fixed — неполноценность в ие6 (и, думаю, не только в ие6), а с ним — не работает. только это упорно игнорируется. вот к чему весь сарказм.
«получаем» это не «у меню не срастается», а «у вас выходит». просто я объясняю (к сожалению, долго и упорно) почему решение мертворожденное, а вы ценность какую-то ищете…
PS я не злой, просто однобоких недорешений не люблю, особенно, когда они отстаиваются на пустых аргументах. «нет экспрешнов» — это действительно такой уж плюс по сравнению с табличкой? табличка в лаёуте — действительно только дело вкуса?
ощутив нехватку знаний, вы полезли-таки в гугль. респект. но есть пара ньюансов: 1) вычитали не все и, соотв., 2) не смогли понять, зачем я написал первый коммент. // гугль, он такой, все ответы знает, только лениться не надо
чтобы добиться нормального блочного поведения (всегда пожалуйста, ваш КО), надо врубить fixed, а когда врубится fixed… // нет, действительно, в думалке ничего по этому поводу не созрело?
но это проза. подумав, получаем или еще один (sic!) tr (и, да, в ие6 не заработает), или недостраничку.
// а в гугле такого не написано?
а с экспрешном в три действия, который min/max регулирует, думаете, будут жуткие подвисания с тормозами? в чем выигрыш-то, кроме как возможность делать min/max без мини-минимальнейших знаний о dom'е? только, плиз, не надо о ie6-пользователях без js: они js отключить могли специально для того, чтобы сайтики на все окошко тянулись ;)
кста, уж раз браться за олд-скульные методы, то и про table-layout (который fixed) надо было бы черкануть.
1.1. перечислить наврядли, но паттерны как раз про это.
1.2. с головой, да, только, когда метод занимает три экрана, пора бы подумать о выведении части действий в другие методы, наверняка их можно обособить и потом реюзать. семь — число относительное, не помню где я его взял, но просто опираясь на него, тяжелее писать громоздкий, не структурированный код.
1.2.1. из любого правила есть исключения.
2. «методы должны описывать поведение сущностей» — просто и понятно, в отличие от моей копипасты, спасибо, запомню.
3.2. значит, у Вас уже есть, что написать :)
4. 90% кодеров, говоря «JS» — подразумевают: «jQuery». к сожалению, у них нет ни предпосылок, ни мотивации задумываться об этом.
5. скорость выполнения — это всегда хорошо, но, опять же, однозначного ответа быть не может.
NaN очень тяжело получить, когда все операции над переменной speed производятся в одном объекте.
зато вот так нельзя сделать
1. за счет краткости, а экран кода это совсем не мало
2. и не увлекаться бытовым ИИ, а делать вещи простыми, проще разобраться в 5 методах из 7 строк, чем в одном «умном» методе на 70 строк
3. умеренное использование упрощенных записей, т.к. в одну строчку можно и управлятор мира написать