понедельник, 24 марта 2008 г.

Drag and Drop

Drag and Drop, при реализации D&D возникает кроссброузерная проблема с событиями, наша задача оптимизировать код, значит использовать как можно меньше условий.
В javascrpit к методам и свойствам обьекта можно обращаться как к ассоциативным массивам, тоесть запись window['alert']('Hello'); будет корректна, значит мы можем сделать предварительную проверку и установку нужных переменных в какойто обьект, затем использовать уже установленные корректные методы и свойства, избегая проверки на совместимость с браузерами.

Следуя всему этому написал такой код:

<script>

(function(){
// Браузер
var browser = {ie:false,opera:false,mozilla:false,safari:false};
browser[/ie/.test(navigator.userAgent.toLowerCase())?'ie':
/mozilla/.test(navigator.userAgent.toLowerCase())?'mozilla':
/opera/.test(navigator.userAgent.toLowerCase())?'opera':''
] = true;

// Назначение имён для свойств обьектов.
var ev = {}
ev.target = browser.ie?'srcElement':'target';
ev.pageY = browser.ie?'clientY':'pageY';
ev.pageX = browser.ie?'clientX':'pageX';
window.ev = ev;
})()
var obj = {};

function startDrag(e){
obj = document.getElementById('wnd');
obj.xoffset = e[ev.pageX] - parseInt(obj.style.left);
obj.yoffset = e[ev.pageY] - parseInt(obj.style.top);
document.onmousemove = draging;
document.onmouseup = endDrag;
}

function draging(e){
e = e||window.event
obj.style.top = e[ev.pageY] - obj.yoffset + "px";
obj.style.left = e[ev.pageX] - obj.xoffset + "px";
}

function endDrag(e){
document.onmousemove = null;
document.onmouseup = null;
}

</script>

четверг, 20 марта 2008 г.

Функция trim

Продолжая тему оптимизации работы со строками, можно вспомнить функцию trim и ее решение.

function trim (str){
return str.replace(/(^\s+)|(\s+$)/g, "");
}

Все чисто и понятно, но не так быстро как могло бы быть.
Результаты удаления пробелов из строки в 25000 символов.
IE6-IE7: 16ms;
FF: 16ms;
Opera: 15ms;
Как бы и немного, но можно гораздо быстрее

Как бы и немного, но можно гораздо быстрее.
function trim (str){
str = str.replace(/^\s\s*/, '');
var length = str.length;
while(/\s/.test(str.charAt(--length)));
return str.substring(0, length+1);
}

IE6-IE7: 0ms;
FF: 0ms;
Opera: 0ms;
Такой результат вполне понятен, скрипт не перебирает всю строку, а сперва добирается до порвого символа не пробел, затем с конца идёт цикл пока пробел.

понедельник, 17 марта 2008 г.

Оптимизация JavaScript (String IE)

В этот раз оптимизация касается «любимого» всеми браузера IE. По какой-то причине конкатенация строк в ослике тотально медленная, поэтому приходится мудрить.
Кто сталкивался с динамическим обновлением контента (ajax), эта функция в той или иной конфигурации очень знакома.



function createList(){
var el = document.getElementById('list');
var html = '<ul>';
for (var i = 1; i <= 1000; i++) {
html += '<li>Element';
html += i;
html += '</li>';
}
html += '</ul>';
el.innerHTML = html;

}

Итак посмотрим на время выполнения скрипта.

Mozilla: 31ms;
Opera: 16ms (как всегда радует);
IE6: 230ms (никуда не годится…);
IE7: 67ms (немного лучше);

Выход из этой ситуации есть, он довольно прост и неожидан.

function createList(){
var html = [];
html.push('<ul>');
for (var i = 1; i <= 1000; i++) {
html.push('<li>Element');
html.push(i);
html.push('</li>');
}
html.push('<ul>');
var el = document.getElementById('list');
el.innerHTML = html.join('');
}


Mozilla: 47ms (тут пришлось немного пожертвовать скоростью);
Opera: 16ms ;
IE6: 31ms (другое дело);
IE7: 32ms (и тут получше);

Как, я уже писал никогда не пишите … el.innerHTML += '<li>' … даже если операций совсем немного, присваивайте к innerHTML уже готовый результат.