misc/class
lib/jquery_pnotify, lib/moment, lib/lodash, misc/notification, site/engine, misc/social
if( $.browser.msie && $.browser.version <= 8 ) include('lib/respond'); $._social.__cfg = {"init":[{"service":"basic"},{"fb_app_id":"1997094873850041","service":"fb"},{"vk_app_id":"2978320","service":"vk"},{"service":"twi"}],"like":[{"service":"fb"},{"service":"vk"},{"via":"","channel":"","hash_tag":"","service":"twi"}]}; window._SiteEngine = new classes.SiteEngine( { user_id: 0, controller: 'content_tape', action: 'tag', content_css_version: '1459538664', social_enabled: 0} );

Faiwer

Блог web-программиста

Поиск по метке: JavaScript

node-forever

1 сентября 2015

Внезапно оказался перед фактом ― закончилось место на VPS. Оказалось, что node-forever съел своими логами 21 GiB места на винте. Приложение упрямо не хотело подниматься, падало, forever это писал в логи и снова пытался его поднять. Забавно…

Как найти ближайший видимый domElement в скролируемом viewPort-е

26 июня 2015

Возникла задача ― в скролируемом контейнере найти первый видимый domElement. Я подумал, что, наверняка, это довольно частая задача, и должно быть множество разных готовых решений. Порыскав по сети я нашёл лишь множество вариаций одного и того же: рекурсивный обход всего древа domElement-ов, с рассчётом их границ. В голову полезли варианты с бинарным поиском по тому же принципу, но уж больно не хотелось с этим всем связываться. Как то уж слишком сурово, для такой мелочной задачи. Должен быть "нативный" инструмент.

Увы, совсем уж нативного инструмента я не нашёл. Но нашёл, гхм, альтернативный путь. Возможно, кому-нибудь ещё пригодится. 

  • У контейнера, который содержит искомые domElement-ы вызываем getBoundingClientRect. Получаем его расположение на экране
  • Вычисляем координаты какого-либо участка из viewPort-а, где должен находится искомый domElement
  • Вызываем document.elementFromPoint, указав нужные координаты экрана
  • profit…

Решение сгодится не для любого случая. Но мне вполне подошло.

Простой proxy-сервер на iojs

9 апреля 2015

Для нужд разработки возникла необходимость в proxy-овании некоторых запросов, в обход CORS-а. Погуглив и слегка причесав код, получилось следующее:

"use strict";

/**
 * run: iojs --harmony_arrow_functions proxy.js
 *
 * nginx:
 * location ~ ^/api.*$ {
 * 	proxy_pass http://127.0.0.1:3001;
 * 	proxy_set_header X-Real-IP $remote_addr;
 * 	proxy_set_header Host $host;
 * 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 * }
 */

let hostname = '%hostname%';
let port = 3001;
let auth = '%user%:%pass%';
let http = require('http');

http.createServer((clientReq, clientRes) =>
{
	let opts =
	{
		hostname: hostname,
		port: 80,
		path: clientReq.url,
		auth: auth,
		headers: clientReq.headers,
		method: clientReq.method
	};
	opts.headers.host = hostname;

	console.info('serve: %s %s', clientReq.method, clientReq.url);

	let proxy = http.request(opts, (proxyRes) =>
	{
		proxyRes.addListener('data', (chunk) => clientRes.write(chunk, 'binary'));
		proxyRes.addListener('end', () => clientRes.end());
		clientRes.writeHead(proxyRes.statusCode, proxyRes.headers);
	});

	clientReq.addListener('data', (chunk) => proxy.write(chunk, 'binary'));
	clientReq.addListener('end', () => proxy.end());
}).listen(port);

Запускается путём выполнения iojs --harmony_arrow_functions proxy.js, логирует все запросы в консоль. Точно умеет POST, GET, отдавать статику… Для простых нужд вполне сгодится. Жаль браузеры пока толком не умеют arrow functions :(

Knockout и this

3 июля 2014

Knockout, безусловно, весьма мощная библиотека, которая позволяет сэкономить море времени, но некоторые моменты в её работе, мне показались неудобными. Про один из них эта заметка. Binding «click» просит указать метод, но особенности JavaScript-а, не позволяют удобным способом указать метод и объект this, для его вызова. В итоге мы имеем вот такие вот уродливые конструкции

<span data-bind="click: $root.save.bind($root)"></span>
<span data-bind="click: $root.edit.bind($root, 'someParameter')"></span>

У меня возникло желание как это дело упростить. Я решил остановиться на таком варианте:

<span data-bind="click: @save"></span>
<span data-bind="click: [@edit, 'someParameter']"></span>

Возможно, не очень очевидный синтаксис, но никто не мешает придумать свой :) Итак, задача состоит в том, чтобы заставить knockout эти конструкции принимать за нужный метод. Для этого воспользуемся хаком preprocess для bindingclick. У меня получилось примерно так:

    ko.bindingHandlers.click.preprocess = function( val )
    {
        val = $.trim( val );

        if( val[ 0 ] === '@' )
        {
            var method = val.substr( 1 );
            return 'function(){ return $root["' + method + '"].apply( $root, arguments ); }';
        }

        if( val[ 0 ] === '[' && val[ val.length - 1 ] === ']' )
        {
            val = $.trim( val.substr( 1, val.length - 2 ) );
            var params = val.split( /\s*,\s*/ );
            if( params[ 0 ] && params[ 0 ][ 0 ] === '@' )
            {
                var method = params.shift().substr( 1 );
                var args = params.join(', ');
                var js = 'function()\n' +
                    '{\n' +
                        '\tvar args = [ ' + params + ' ].concat( _.toArray( arguments ) );\n' +
                        '\treturn $root["' + method + '"].apply( $root, args );\n' +
                    '}';
                return js;
            }
        }

        return val;
    }

Решение пока черновое и не обкатанное. К тому же на click-е мир клином не сошёлся и нужно что-то более универсальное.

Пишем плагин для CKEditor 4

30 ноября 2013

CKEditor - это WYSIWYG редактор HTML-кода для браузеров. Всякий раз, сталкиваясь с его документацией или же с его исходным кодом, с исходным кодом его плагинов я терялся. И это не мудрено, ведь CKEditor это очень большой продукт, имеющий довольно сложную инфраструктуру. Но, зачастую, стандартных возможностей не хватает и требуется добавить свою. В этой статье я хотел бы остановиться на плагине, который позволяет встраивать и оперировать в редакторе Yandex-картами. Вот так это будет выглядеть по окончанию редактирования:

534e37778bc3f.png

подробности…