85 posts tagged

по-русски

/core.php, line 2
Error 2: Use of undefined constant k - assumed 'k' (this will throw an Error in a future version of PHP)

/core.php, line 2
Error 2: Use of undefined constant k - assumed 'k' (this will throw an Error in a future version of PHP)

/core.php, line 2
Error 2: Use of undefined constant k - assumed 'k' (this will throw an Error in a future version of PHP)

/core.php, line 2
Error 2: Use of undefined constant k - assumed 'k' (this will throw an Error in a future version of PHP)

/core.php, line 2
Error 2: Use of undefined constant k - assumed 'k' (this will throw an Error in a future version of PHP)

/core.php, line 2
Error 2: Use of undefined constant k - assumed 'k' (this will throw an Error in a future version of PHP)

/core.php, line 2
Error 2: Use of undefined constant k - assumed 'k' (this will throw an Error in a future version of PHP)

Later Ctrl + ↑

Трюк с очисткой всех интервалов и таймаутов

Перечитывал JavaScript-Garden, в секции таймеров есть следующий код:
// удаляем "все" таймауты
for(var i = 1; i < 1000; i++) {
    clearTimeout(i);
}
Авторы утверждают, что не все таймауты могут быть завершены этим циклом, и это утверждение не вызывает сомнений. Но способ остановить все таймауты (и интервалы) все-же есть. Фишка в том, что функции setTimeout и setInterval возвращают id таймера, который при каждом вызове увеличивается на 1 (и для интервалоц и таймаутов). Таким образом, если создать интервал прямо перед очисткой всех интервалов, то его id будет наибольшим. Все, кто имеет меньший id будут очищены:
// удаляем все таймауты
var max_id;

max_id = setTimeout(function () {});
while (max_id--) {
    clearTimeout(max_id);
}
2012   по-русски   разработка

Замена всех вхождений подстроки

Ничего лучше, чем преобразование подстроки в регулярку с флагом g, не нашел (может вы подскажите). Идея заключается в том, чтобы экранировать все служебные символы регулярок перед проведением замены.
function replace_string_occurances (src_string, string_to_replace, replace_rule) {
	var escaped_string,
		reg;

	escaped_string = string_to_replace.replace(/[\(\)\[\]\\\.\^\$\|\?\+]/g, '\\$&');
	reg = new RegExp(escaped_string, 'g');
	return src_string.replace(reg, replace_rule);
}

Если же служебные символы не экранировать, то [.] превращается в корректное регулярное выражение. А так, код ниже отработает корректно:
replace_string_occurances('[.]_[.]', '[.]', '[*]'); // [*]_[*]
2012   по-русски   разработка

Запланированный вызов функций или «вызови меня не чаще, чем»

Если синхронность функции не имеет значения (в нашем случае она будет вызывана черз минимальный таймаут), то можно провести следующий трюк. Вместо вызова функции, мы планируем ее вызов в будущем через setTimeout и запоминаем наши намерения. При последующих вызовах этой функции в пределах одного блока, мы видим, что вызов запланирован, и спокойно ничего не делаем. В общем виде получается нижеследующее:
function planned (func, delay) {
	var was_planned,
		timer;

	was_planned = false;
	return function () {
		if (!was_planned) {
			timer = setTimeout(function () {
				func();
				was_planned = false;
			}, delay || 0);
		}
		was_planned = true;
		return timer;
	};
}


И да, чтобы можно было отменить вызов запланированной функции, всегда возвращаем id интервала.
Если использовать 0 интервал, то функцию можно использовать для разовой отправки данных при выходе из блока кода, а с 100мс — перерасчет размеров блоков при ресайзе окна.

function recalculate_box_sizes () {
	// stuff to make design fit window size
}
recalculate_box_sizes = planned(recalculate_box_sizes, 300);
window.onresize = recalculate_box_sizes;
2012   по-русски   разработка

Подсветка HTML на странице

Для подсветки примеров исходного кода на веб страницах использую подсветку highlight.js Ивана Сагалаева. Но HTML, который я в надежде увидеть в виде кода вставляю настраницу, интерпретируется браузером как разметка. Для корректной работы надо бы все html символы заэскейпить (превратить > в &gt; < в &lt; и т. д.). Лень, да и неудобно (особенно, когда код требует правки). Дословное решение задачи: поместить в виде текста html содержимое элемента.
$('pre code.html').each(function () {
	var self;

	self = $(this);
	self.text( self.html() );
});

Есть но: решение не работатет, если требуется подсветить строку с doctype.
2012   по-русски   разработка

Javascript decorator

Один из любимейших приемов. В двух словах: декоратор возвращает функцию, которая выполняет декорируемую исходную функцию и вместе с ней выполняет еще одну (или две). Практическая польза декорирования ощущается при отладке и логировании на высшем уровне, когда исследуется поведение всей системы, а не деталей реализации методов. Второй, немного грязный случай — использование декоратора для шлифования уже существующих методов налету. Третий — переписывание стандартных методов для исследование кода внешних источников (например рекламных блоков).

Основные проблемы:
  • нечитаемость функции после декорирования (toString выводит код декоратора);
  • эффект неожиданности, когда функция выполняет не только то, что было описано при ее объявлении;
  • некорректная работа в случае, когда декорируемая функция используется как объект для хранения свойств и методов, которые сама же и использует
function decorate (initial, decorate_before, decorate_after) {
	return function () {
		var initial_call_result;

		if (typeof decorate_before === 'function') {
			decorate_before.apply(this, arguments);
		}
		initial_call_result = initial.apply(this, arguments);
		if (typeof decorate_after === 'function') {
			decorate_after.apply(this, arguments);
		}
		return initial_call_result;
	}
}

gist

Реализации могут варьироваться. В конкретном случае исходную функцию можно декорировать как «до» так и «после». Например логирование использования document.write
document.write = decorate(document.write, null, function (str) {
	console.log( 'Document write call with "' + str + '" argument' );
});
2012   по-русски   разработка

Мимический спектакль

На сцене стоит занавес, в нем — прорези. В прорезях видны лица актеров. Каждое лицо принадлежит одному из действующих персонажей. Сценарий читает одним человеком нарочно беэмоциональным тоном. Каждое лицо выражает ту эмоцию, которую испытывает герой пьесы в момент, описываемый диктором. Дополнительные возможности: менять актерский состав, акцентировать внимание зрителя на актере с помощью освещения.  
2012   по-русски

Iterator на javascript

Изобрел велосипед: функцию для прохода по итерируемым объектам (массивы, объекты, arguments, nodeCollection). Функция пробегает по каждому элементу первого аргумента, в обработчик передает элемент и индекс. Обработчик вызывается в контексте итерируемого объекта. Результаты вызовов обработчиков складывает в массив или объект (в зависимости от типа входящих данных). По объекту arguments итерирует как по массиву gist.
function iterate(list, func) {
	var i, res, type;
	
	type = Object.prototype.toString.call(list);
	if ( list.hasOwnProperty('length') || type === '[object HTMLCollection]' ) {
		res = [];
		for (i = 0; i < list.length; i += 1) {
			res.push(func.call(list, list[i], i));
		}
	} else {
		res = {};
		for (i in list) {
			res[i] = func.call(list, list[i], i);
		}
	}
	return res;
}

Пример использования. Все ссылки с решеткой в урле помечаются классом anchor
iterate(document.links, function (link) {
	if (link.href && link.href.indexOf('#') !== -1) {
		link.className += ' anchor';
	}
})
2012   по-русски   разработка
Earlier Ctrl + ↓