проще перечислить с кем русские не успели разжопиться...
понедельник, сентября 24, 2007
пятница, сентября 21, 2007
\(^_^)/
d(^_^)b - в наушниках
o_0 - офигевший
^,__,^ - вампир
^_^' - смущён
\m/(^_^)\m/ - на пальцах
=^.^= - майский котик
/X\(o.o)/X\ - поучок
^(oo)^ - свинтус
@(*о*)@ - коала
(='_'=) - покемон
>^,,^< - летучая собака
*\o/* - девушка из группы поддержки
(<>..<>) - инопланетянин
__\o/__ - утопающий
(+_+) - трупик
неплохая подборка смайлов:
http://www.itc.ua/article.phtml?ID=13123&IDw=53&pid=21
ещё одна:
http://smayly.net.ru/static/txt.html
вторник, сентября 18, 2007
установка обработчиков событий в javascript
Я уже говорил, что люблю яваскрипт? Если нет, то: "лучше языка я ещё не встречал!". Есть, конечно и недостатки, но многие из них можно обойти...
Но сейчас пойдёт речь не о недостатках, а наоборот, об одном элегантном решении...
Самый простой способ повесить обработчик события - это просто написать:
Метод довольно простой и наглядный, но основной его недостаток - для одного события у одного узла можно назначить только один обработчик, что очень неудобно.
Более сложный способ, лишённый этого недостатка, - это воспользоваться методами addEventListener (DOM) и attachEvent (IE). Например: http://php.ru/forum/viewtopic.php?t=7374
Работает, конечно, замечательно, но у него есть один существенный недостаток - мы не можем создавать свои события и вешать на них обработчики. В первом варианте у нас такая возможность есть, но обработчик мы можем повесить только один и соответственно городить огород нет особого смысла.
И тут мы подходим к самому главному! В яваскрипте любая функция является объектом, а значит она может иметь дополнительные свойства. В частности, можно задать каким-нибудь свойством массив обработчиков, а функция должна просто пройтись по каждому из них и запустить. В итоге у меня получился такой код:
то есть, мы расширяем html-ноду ( хотя, в ИЕ наврятли удастся расширить что-то отличное от html-елемента -_- ну да не суть ) двумя функциями, одна из которых добавляет обработчик, а вторая - удаляет.
Примеры использования:
upd: кстати, на событие 'onbeforeunload' и возможно на ещё какие-то нельзя вешать обработчики с помощью addEventListener/attachEvent, ибо некроссбраузерно.
upd2: мля... не работает в мозилле в designMode... придётся оной подпорки делать...
Но сейчас пойдёт речь не о недостатках, а наоборот, об одном элегантном решении...
Самый простой способ повесить обработчик события - это просто написать:
node.onclick= function( e ){
if( !e ) e= window.event;
alert( e );
}Метод довольно простой и наглядный, но основной его недостаток - для одного события у одного узла можно назначить только один обработчик, что очень неудобно.
Более сложный способ, лишённый этого недостатка, - это воспользоваться методами addEventListener (DOM) и attachEvent (IE). Например: http://php.ru/forum/viewtopic.php?t=7374
Работает, конечно, замечательно, но у него есть один существенный недостаток - мы не можем создавать свои события и вешать на них обработчики. В первом варианте у нас такая возможность есть, но обработчик мы можем повесить только один и соответственно городить огород нет особого смысла.
И тут мы подходим к самому главному! В яваскрипте любая функция является объектом, а значит она может иметь дополнительные свойства. В частности, можно задать каким-нибудь свойством массив обработчиков, а функция должна просто пройтись по каждому из них и запустить. В итоге у меня получился такой код:
node.observe= function( event, func ){
if( !node[event] ){
node[event]= function f( e ){
if( !e ) e= window.event;
var funcs= node[event].funcs;
for( var i= 0; i < funcs.length; ++i ){
if( funcs[i] ) funcs[i]( e );
});
};
node[event].funcs= [];
}
var funcs= node[event].funcs;
for( var i in funcs )
if( funcs[i] == func ) return;
funcs.push( func );
}
node.unobserve= function( event, func ){
var funcs= node[event].funcs;
for( var i in funcs )
if( funcs[i] == func )
delete funcs[i];
}то есть, мы расширяем html-ноду ( хотя, в ИЕ наврятли удастся расширить что-то отличное от html-елемента -_- ну да не суть ) двумя функциями, одна из которых добавляет обработчик, а вторая - удаляет.
Примеры использования:
function ping( e ){
alert( e );
}
node.observe( 'onclick', ping );
node.unobserve( 'onclick', ping );
node.observe( 'onmyevent', ping );
node.onmyevent( { keyCode: 1 } );upd: кстати, на событие 'onbeforeunload' и возможно на ещё какие-то нельзя вешать обработчики с помощью addEventListener/attachEvent, ибо некроссбраузерно.
upd2: мля... не работает в мозилле в designMode... придётся оной подпорки делать...
понедельник, сентября 10, 2007
одна большая дырка
правильно, речь пойдёт об ИЕ ^_^
недавно (ну, месяца два назад) c удивлением обнаружил, что в ИЕ работает даже такая конструкция:
<img src="javascript:alert(1)" />
что тут можно сказать? только сабж ^_^
недавно (ну, месяца два назад) c удивлением обнаружил, что в ИЕ работает даже такая конструкция:
<img src="javascript:alert(1)" />
что тут можно сказать? только сабж ^_^
пятница, сентября 07, 2007
выделение, визивиг и изменение контента
при реализации визивига некоторые вещи приходится вытворять по схеме: сериализация->обработка->десериализация
в качестве примера - реализация динамической подсветки кода. одними только dom-функциями это реализовывать - страшный геморрой, а ещё и очень медленно. гораздо быстрее и проще пройтись парой регулярок по сериализованному документу.
но тут нас подстерегает одна гадость - после обработки хорошо было бы восстановить выделение или хотябы позицию курсора. очевидно, пока выделение ещё существует, нужно сохранить его позиции в dom-е, обработать и по оставленным меткам восстановить выделение.
очевидно, что метки начала и конца выделения должны быть неиспользуемой последовательностью символов юникода. также они должны иметь нулевую ширину, дабы при вводе текста не было скачков. я остановился на парах диактрических знаков: '\u0300\u0301' и '\u0302\u0303'. вроде как маловероятно, чтобы в тексте потребовалось их применить последовательно. ширины они точно не имеют. единственный недостаток: они имеют визуализацию, но с учётом того, что обработка должна быть "мгновенной" (ибо рилтаймовая подсветка) - кратковременное появление маленьких значков не должно быть заметно на глаз.
пришлось несколько погеморроиться с реализацией этого дела, но всё получилось. отдельный пример не выкладываю ибо его сложно выдрать из фреймворка - выпущу фреймворк - можно будет посмотреть в действии.
в ИЕ всё оказалось весьма шоколадно...
сохранение меток выглядит так:
var range= document.selection.createRange();
range.pasteHTML( '\u0300\u0301' + range.htmlText + '\u0300\u0301' );
восстановление несколько менее тривиально:
var ran= document.body.createRange();
var tr= document.body.createRange();
tr.findText( '\u0300\u0301' );
tr.text= '';
ran.setEndPoint( 'StartToStart', tr );
tr.findText( '\u0302\u0303' );
tr.text= '';
ran.setEndPoint( 'EndToEnd', tr );
ran.select( );
а вот реализуя то же самое для остальных браузеров пришлось несколько попотеть...
сохранение меток:
var ran= window.getSelection().getRangeAt(0);
var rane= ran.cloneRange( );
rane.collapse( false );
var node= document.createTextNode( '\u0302\u0303' );
rane.insertNode( node );
var node= document.createTextNode( '\u0300\u0301' );
ran.insertNode( node );
а для восстановления соответственно приходится бежать по всему дому в поисках открывающей и закрывающей пар node+offset, после чего наведение выделения с помощью функций setStart и setEnd. почему w3c не соизволила узаконить findText остаётся загадкой 8(o_0)8
в качестве примера - реализация динамической подсветки кода. одними только dom-функциями это реализовывать - страшный геморрой, а ещё и очень медленно. гораздо быстрее и проще пройтись парой регулярок по сериализованному документу.
но тут нас подстерегает одна гадость - после обработки хорошо было бы восстановить выделение или хотябы позицию курсора. очевидно, пока выделение ещё существует, нужно сохранить его позиции в dom-е, обработать и по оставленным меткам восстановить выделение.
очевидно, что метки начала и конца выделения должны быть неиспользуемой последовательностью символов юникода. также они должны иметь нулевую ширину, дабы при вводе текста не было скачков. я остановился на парах диактрических знаков: '\u0300\u0301' и '\u0302\u0303'. вроде как маловероятно, чтобы в тексте потребовалось их применить последовательно. ширины они точно не имеют. единственный недостаток: они имеют визуализацию, но с учётом того, что обработка должна быть "мгновенной" (ибо рилтаймовая подсветка) - кратковременное появление маленьких значков не должно быть заметно на глаз.
пришлось несколько погеморроиться с реализацией этого дела, но всё получилось. отдельный пример не выкладываю ибо его сложно выдрать из фреймворка - выпущу фреймворк - можно будет посмотреть в действии.
в ИЕ всё оказалось весьма шоколадно...
сохранение меток выглядит так:
var range= document.selection.createRange();
range.pasteHTML( '\u0300\u0301' + range.htmlText + '\u0300\u0301' );
восстановление несколько менее тривиально:
var ran= document.body.createRange();
var tr= document.body.createRange();
tr.findText( '\u0300\u0301' );
tr.text= '';
ran.setEndPoint( 'StartToStart', tr );
tr.findText( '\u0302\u0303' );
tr.text= '';
ran.setEndPoint( 'EndToEnd', tr );
ran.select( );
а вот реализуя то же самое для остальных браузеров пришлось несколько попотеть...
сохранение меток:
var ran= window.getSelection().getRangeAt(0);
var rane= ran.cloneRange( );
rane.collapse( false );
var node= document.createTextNode( '\u0302\u0303' );
rane.insertNode( node );
var node= document.createTextNode( '\u0300\u0301' );
ran.insertNode( node );
а для восстановления соответственно приходится бежать по всему дому в поисках открывающей и закрывающей пар node+offset, после чего наведение выделения с помощью функций setStart и setEnd. почему w3c не соизволила узаконить findText остаётся загадкой 8(o_0)8
воскресенье, сентября 02, 2007
Теория множеств свернула не туда
Читая различную литературу каждый раз подмечаю интересную особенность: если автор описывая что-то начинает вдруг использовать эпитеты типа "гениальное", "эпохальное" и тп, то это значит, что читателю пытаются скормить очередную чушь и упомянутые эпитеты призваны усилить аргументацию...
Приведу пример из "Что такое математика?" от Куранта, Роббинса под редакцией Колмогорова:
Для начала хотелось бы напомнить классическое доказательство бесконечности ряда натуральных чисел:
Предположим, что мы нашли конец, значит среди всех чисел можно найти максимальное, прибавить к нему 1 и получить новое натуральное число, которое находится за установленной нами границей. далее формулируем индукционный переход: для любого конечного множества натуральных чисел можно найти натуральное число, которое не будет входить в это множество.
и делаем вывод, что множество натуральных чисел не является конечным или, что то же самое, является бесконечным.
Теперь перейдём собственно к Кантору... суть его "доказательства" сводится к следующему: пусть мы пересчитали все вещественные числа, тогда, мы можем выписать их в ряд:
0: 0.abc...
1: 0.def...
2: 0.ghi...
...
, а потом используя диагональный метод составить новое число, где первая цифра не равна первой цифре первого числа, вторая - второй второго и так далее.
Далее мы делаем финт ушами - предельный переход - и получаем число, которого нет в нашем списке, из чего делаем вывад о том, что множество вещественных чисел мощнее множества натуральных. Подумать только - одна бесконечность больше другой бесконечности на целый 1 элемент! ^_^ (Всем, кто не согласен с моими рассуждениями, советую крепко задуматься над последним предложением.)
Что мешает нам полученное число тут же добавить, например, в начало списка? А ничего! (надеюсь все согласны, что "бесконечность+1=бесконечность"?) Да, после этого можно повторить процедуру и найти ещё одно число. Ничего не напоминает? Та же самая схема, что и в случае доказательства бесконечности множества натуральных чисел, но вот вывод из этого Кантором сделан неверный. Фактически он доказывает бесконечность множества вещественных чисел, ибо диагональный метод всего-лишь позволяет по конечному множеству вещественных чисел найти вещественное число, которое в это множество не входит (вспоминаем индукционный переход в доказательстве бесконечности ряда натуральных чисел). На бесконечном же множестве диагональный метод будет бесконечно искать, но так и не найдёт неучтённое число. Точно также мы можем прибавлять единицу бесконечное число раз в поиске последнего натурального числа, но так никогла его и не найти.
Приведу пример из "Что такое математика?" от Куранта, Роббинса под редакцией Колмогорова:
- Тому же Кантору принадлежит открытие исключительной важности: множество всех действительных (рациональных и иррациональных) чисел несчетно.
- Евклид, громкая слава которого объясняется той частью его «Начал», которая посвящена основам геометрии (изучаемым в школе), по-видимому, сделал оригинальные открытия в области теории чисел, тогда как его геометрия в значительной степени представляет собой компиляцию ранее полученных результатов.
Для начала хотелось бы напомнить классическое доказательство бесконечности ряда натуральных чисел:
Предположим, что мы нашли конец, значит среди всех чисел можно найти максимальное, прибавить к нему 1 и получить новое натуральное число, которое находится за установленной нами границей. далее формулируем индукционный переход: для любого конечного множества натуральных чисел можно найти натуральное число, которое не будет входить в это множество.
и делаем вывод, что множество натуральных чисел не является конечным или, что то же самое, является бесконечным.
Теперь перейдём собственно к Кантору... суть его "доказательства" сводится к следующему: пусть мы пересчитали все вещественные числа, тогда, мы можем выписать их в ряд:
0: 0.abc...
1: 0.def...
2: 0.ghi...
...
, а потом используя диагональный метод составить новое число, где первая цифра не равна первой цифре первого числа, вторая - второй второго и так далее.
Далее мы делаем финт ушами - предельный переход - и получаем число, которого нет в нашем списке, из чего делаем вывад о том, что множество вещественных чисел мощнее множества натуральных. Подумать только - одна бесконечность больше другой бесконечности на целый 1 элемент! ^_^ (Всем, кто не согласен с моими рассуждениями, советую крепко задуматься над последним предложением.)
Что мешает нам полученное число тут же добавить, например, в начало списка? А ничего! (надеюсь все согласны, что "бесконечность+1=бесконечность"?) Да, после этого можно повторить процедуру и найти ещё одно число. Ничего не напоминает? Та же самая схема, что и в случае доказательства бесконечности множества натуральных чисел, но вот вывод из этого Кантором сделан неверный. Фактически он доказывает бесконечность множества вещественных чисел, ибо диагональный метод всего-лишь позволяет по конечному множеству вещественных чисел найти вещественное число, которое в это множество не входит (вспоминаем индукционный переход в доказательстве бесконечности ряда натуральных чисел). На бесконечном же множестве диагональный метод будет бесконечно искать, но так и не найдёт неучтённое число. Точно также мы можем прибавлять единицу бесконечное число раз в поиске последнего натурального числа, но так никогла его и не найти.
воскресенье, августа 19, 2007
Кодестайл против собаки
- вы должны каждое слово начинать с большой буквы
- ну.. это ж тянуться к шифту без конца
- это хороший стить
- чем же он хорош?
- позволяет отделять слова друг от друга
- а пробелы разве не для этого?
- пробелы - это плохой стиль
- что за бред?
- это потенциальный источник ошибок: слова можно написать настолько близко друг к другу, что можно не заметить существование пробела, к тому же иногда межбуквенный интервал можно принять за пробел.
- а что мешает использовать интервалы нормальной длинны?
- мне лень такому дауну как ты что-либо доказывать - любой здравомыслящий человек поймёт, что пробелы нельзя использовать нигде и никогда, потому как получается говнокод - нужно использовать "синтаксический сахар" в виде заглавных букв.
- но это не удобно, ужасно смотрится и некоторые заглавные буквы можно спутать со строчными!
- бан бы тебе, с аргументом "непросветлённый"! тема закрыта.
навеяно этим: http://phpclub.ru/talk/showthread.php?s=&threadid=101915
- ну.. это ж тянуться к шифту без конца
- это хороший стить
- чем же он хорош?
- позволяет отделять слова друг от друга
- а пробелы разве не для этого?
- пробелы - это плохой стиль
- что за бред?
- это потенциальный источник ошибок: слова можно написать настолько близко друг к другу, что можно не заметить существование пробела, к тому же иногда межбуквенный интервал можно принять за пробел.
- а что мешает использовать интервалы нормальной длинны?
- мне лень такому дауну как ты что-либо доказывать - любой здравомыслящий человек поймёт, что пробелы нельзя использовать нигде и никогда, потому как получается говнокод - нужно использовать "синтаксический сахар" в виде заглавных букв.
- но это не удобно, ужасно смотрится и некоторые заглавные буквы можно спутать со строчными!
- бан бы тебе, с аргументом "непросветлённый"! тема закрыта.
навеяно этим: http://phpclub.ru/talk/showthread.php?s=&threadid=101915
суббота, августа 18, 2007
среда, августа 15, 2007
php и замыкания
как известно в пыхе нет замыканий. некоторые считают это недостатком, потому что замыкания - это черезвычайно мощные штуки, некоторые, наоборот, достоинством, ибо копаться в коде с замыканиями довольно напряжно.
в пыхе сделано тупо, но эффективно - у каждой функции своё пространство имён и если какая-то переменная в ней не определена - значит она не определена и не надо лезть родительский контекст, чтобы в этом убедиться.
однако, в пыхе есть и поруганное многими исключение - директива global позволяющая импортировать переменные из глобального контекста. как говорится: "мысля была хорошей, но родилась она в заднице" :) вместо директивы global лучше бы ввели директиву extern, позволяющую импортировать переменные из родительского контекста - получились бы эдакие "контролируемые замыкания".
интересно, существуют ли уже языки с "контролируемыми замыканиями"?
в пыхе сделано тупо, но эффективно - у каждой функции своё пространство имён и если какая-то переменная в ней не определена - значит она не определена и не надо лезть родительский контекст, чтобы в этом убедиться.
однако, в пыхе есть и поруганное многими исключение - директива global позволяющая импортировать переменные из глобального контекста. как говорится: "мысля была хорошей, но родилась она в заднице" :) вместо директивы global лучше бы ввели директиву extern, позволяющую импортировать переменные из родительского контекста - получились бы эдакие "контролируемые замыкания".
интересно, существуют ли уже языки с "контролируемыми замыканиями"?
вторник, августа 07, 2007
смерть ORM'у
реализовал сегодня идеальную систему прав для движка. есть пользователи, каждый может состоять в нескольких группах. как для группы так и для отдельного пользователя в определённом разделе каталога можно назначить свою роль, а у каждой роли есть свой набор прав.
в итоге запрос получения привелегий доступа к определённой статье для текущего пользователя выглядит следующим образом:
сижу, думаю, а не перемудрил ли я? (o_0)`
в итоге запрос получения привелегий доступа к определённой статье для текущего пользователя выглядит следующим образом:
$perms= $db->get1d('
select *
from
mo_cat_art as ca
,
mo_catalog as c1
,
mo_catalog as c2
,
mo_rules as ru
,
mo_roles as ro
where
ca.art_id = ',$art['art_id'],'
and
ca.cat_id = c1.cat_id
and
c1.cat_no >= c2.cat_no
and
c1.cat_sub <= c2.cat_sub
and
c2.cat_id = ru.cat_id
and
(
ru.user_id = ',$user['user_id'],'
or
ru.group_id in ',$user['grouplist'],'
)
and
ru.role_id = ro.role_id
group by
ru.rule_id
order by
c2.cat_no desc
');сижу, думаю, а не перемудрил ли я? (o_0)`
суббота, июля 28, 2007
Подписаться на:
Сообщения (Atom)




