История нечестной победы

Есть глазоломная игра: game.ioxapp.com/color/ в которой я могу набрать максимум 25 очков.

Однако имеющиеся у меня знания подталкивают на нечестный способ победы :)

var f = function () {
	var box = document.querySelector('#box');
	var cubes = box.querySelectorAll('span');
	var el = null;
 
	for(var i = 0, l = cubes.length; i < l; i += 1) {
		if (el === null) {
			el = cubes[i];
		} else if (convert(el.style.backgroundColor) < convert(cubes[i].style.backgroundColor)) {
			c(cubes[i]);
			return false;
		}
	}
 
	function convert (rgb) {
		return rgb.replace(/[^0-9,]/g, '').split(',').reduce(function (summ, item) {
			return ~~summ + ~~item;
		});
	}
 
	c(el);
};
 
var c = function (el) {
	el.click();
	setTimeout(f, 100);
};
 
f();

Живые шаблоны для PHPstorm

Некоторые кастомные шаблоны (Live Templates), которые я чаще всего использую на проекте.

cl

console.log('$TITLE$',$VAR$); // $TITLE$ set jsMethodName() expr

ct

console.time('$VAR$');

cte

console.timeEND('$VAR$');

ajax

var xhr = $ajax({
    url: '$VAR$',
    type: '$TYPE$', // set as 'post' string
    data: '$VAR$'
});

xhr.done(function (response) {
    $VAR$
});

xhr.fall(function (response) {
    $VAR$
});

xhr.then(function (response) {
    $VAR$
});

for

for (var i = 0, l = $VAR$.length; i < l; i += 1) {
    $VAR$
}

dgr

debugger;

fn

function $VAR$ ($VAR$) {
    $VAR$
}

meth

$VAR$: function ($VAR$) {
    $VAR$
}, 

Функция определения палиндрома

Однажды мне пришлось решать задачу определения палиндрома. Так как вопрос был задан в лоб и времени было мало, решение было простецким:

function pal (str) {
    str = str.toLowerCase().replace(/ /g, '');

    return str.split('').reverse().join('') == str;
}

Тут всё просто: приводим строку к нижнему регистру, убираем пробелы, разбиваем на массив, меняем порядок следования элементов, собираем новый массив в строку и сравниваем с исходной строкой.

Что бы убрать возможные знаки препинания из исходной строки, которые бы могли помешать работе, надо изменить регулярку:

// спасибо Тимур
str = str.toLowerCase().replace(/[^a-zA-Zа-яА-Я]/g, '');

Вот собственно и всё. Способ крайне прост и понятен, но мы пять раз проходим по всему набору символов. А если строка из миллиона символов?

В этом случае лучшим решением будет пожертвование простотой в угоду скорости:

function pal (str) {
    // нормализуем строку
    str = str.toLowerCase().replace(/[^a-zA-Zа-яА-Я]/g, ''); 
    
    var strLen = str.length; // сохраняем значение её длины
    
    // берём половину длины строки и округляем до большего
    for (var i = 0, l = Math.ceil(strLen / 2); i &lt; l; i += 1) { 
        // тут самое интересное: мы берём первый символ 
        // строки и сравниваем его с последним. 
        // Второй с предпоследним и так далее.
        // если крайние символы не совпадают, прерываем цикл. 
        // Ясно, что уже не палидром.
        if (str.charAt(i) !== str.charAt(strLen-(1+i))) { 
            console.log('Не палиндром!');
            return false;
        }
    }
    // если все символы из первой половины строки совпадают 
    // с аналогичными символами из второй, 
    // значит исходная строка - палиндром.
    console.log('Палиндром')
}

Видно, что во втором примере полный обход строки осуществляется лишь дважды. А при первом же несовпадении цикл прерывается, не расходуя ресурсы понапрасну.

На практике такого рода оптимизация не имеет смысла и даёт выигрыш всего в 10 мс. при длине строки в 1 000 000 символов :)

UPD: Мда, интернет пестрит вариантами определения палиндрома и мои изыскания отнюдь не пионерские.

Тег STYLE тоже считается

В современном мире подключить CSS к HTML можно следующими способами:

Встроенные стили
<div style="color: red;">...</div>

Внутренние стили
<style type="text/css">
    div {
        color: red;
    }
</style>

Внешние стили 
<link rel="stylesheet" type="text/css" href="style.css" /> 

или так
<link rel="stylesheet" href="style.css"> 

Через @import @import url(style.css);

В ИЕ максимальное количество подключаемых CSS файлов равно 31. Каким бы способом это не было реализовано это подключение.

Важно помнить, что учитывается также количество тегов style. Т.е. общее количество link, style и @import не должно превышать 31. Обход идёт с верха DOM дерева и все последующие способы подключения стилей будут игнорироваться.

Кроссбраузерное присваивание значения для атрибута style

Всем конечно известно, что в ИЕ до восьмой версии не работает присваивание значения атрибуту style через element.setAttribute();.

Однако присваивание атрибутов по отдельности через запись вида: element.style.name = "value" совершенно отлично работает в любом браузере. Стоит только учитывать, что имена свойств, которые пишутся через дефис, надо конвертировать в «верблюжий стиль» с малой буквы. Так свойство margin-left следует записывать как marginLeft. Однако правило работает не всегда. Так свойство float, хоть и не содержит дефиса и состоит из одного слова, следует писать как cssFloat или styleFloat.

В общем виде, функцию для присваивания значения атрибуту style можно написать следующим образом:

// создаём елемент
var wrap = document.createElement('div');

// вызываем функцию присваивания значения
setStyle(wrap, "position:fixed;top:50%;left:50%;display:block;");

// собственно функция
function setStyle(el, style) {
	style = style.split(';'); // разбиваем на массив значений
	
	for (var i in style) {
		if (style[i] !== "") { // если значение нет (конец строки)
			var attr = style[i].split(':'); // конкретное значение

			// если есть дефис в значении свойства, преобразуем значение
			if (attr[0].indexOf('-') != -1) { 						
				attr[0] = attr[0].replace(/-\D/g, attr[0].charAt(attr[0].indexOf('-') + 1).toUpperCase());
			}
			
			// задаём значение
			el.style[attr[0]] = attr[1];
		}
	}
}

С присваиванием float пока не знаю что делать. Стараюсь его избегать.

Дополнение: конструкция element.setAttribute(); очень замечательно заменяется конструкцией element.style.cssText = 'css prop';.