Как и обещал хочу выложить видоизменненную систему функций по перетаскиванию мышью объекта.
Какие изменения были внесены?
1. Оптимизация
теперь у вас не будет тупить при перетаскивании флеши или других объектов
2. максимальные и минимальные координаты передвижения
Кроме как настройки вектора движущегося объекта (X Y или по плоскости) теперь появилась новая настройка
CODE
<html>
<head>
<title>Move Div</title>
<script>
bool_move = 0; // иницициализация глобальной переменной
// конено юзание глобалов плохой тон, но иногда никак без них (я про JS)
// переменная отвечает за старт перетаскивания
function addEvent(elm, evType, fn, useCapture) { // эта функция для добавления событий
// не моя, конечно написать такую непроблема, но зачем колесо изобретать ))
// http://www.javaportal.ru/javascript/articles/bestfunctions.html
// взята она от сюда
if (elm.addEventListener) {
elm.addEventListener(evType, fn, useCapture);
return true;
}
else if (elm.attachEvent) {
var r = elm.attachEvent('on' + evType, fn);
return r;
}
else {
elm['on' + evType] = fn;
}
}
function createDiv(clss) { // Функция часть вторичной оптимизации движения
// Оптимизация организуется за счет того что двигается не весь активный елемент,
// а только его "тень" - див (что значительно ускоряет обработку) , стиль которого вы можете задать сами
// после окончания движения тени, движущийся елемент заменяет ее
// Эта ф-я создает эту тень и принимает в качестве значения класс дива
// возвращает объект "тени"
var newDiv = document.createElement('DIV');
newDiv.style.zIndex = 1000000;
newDiv.style.position = 'absolute';
newDiv.id = 'temp_move';
document.body.appendChild(newDiv);
return document.getElementById('temp_move');
}
function initDiv(element, clss, express) { // Функция часть вторичной оптимизации движения
// Инициализирует "тень", если ее нет, то создает ее
// если уже есть, то просто присваевает ей соответствующие параметры
// clss - класс "тени"
// experss - событие которое инициализируется после mouseup
var newDiv = document.getElementById('temp_move');
if (newDiv == undefined) newDiv = createDiv(clss)
else newDiv.style.display = 'block';
document.onmouseup = null;
addEvent(document,'mouseup',express);
newDiv.className = clss;
// Тень имеет теже высоту, ширину, и координаты что и объект движения
newDiv.style.height = element.offsetHeight + 'px';
newDiv.style.width = element.offsetWidth + 'px';
newDiv.style.top = element.offsetTop + 'px';
newDiv.style.left = element.offsetLeft + 'px';
ID = element.id; // еще одна глобальная переменнаяя ))
// служит для сохранения айдишника двигающегося элемента
}
function initMove (e, id, set, clss, express) { // Функция инициализирующая движения общего назначения
// в качестве параметров принимает
// е - объект события
// id - id элемента движения
// set - настройки
// clss - класс тени
// express - функция вызывающаяся при mouseup
if(document.all)e = event;
if (set) settings = set;
else settings = false;
element = getObj(id);
initDiv(element, clss, express) // инициалицация тени
bool_move = 0; // обнуление движения
// еще одна кучка глобальных переменных запоминающие
// начальные координаты мыши и объекта движения
startMousePosX = e.clientX;
startMousePosY = e.clientY;
startPosElmX = element.offsetLeft;
startPosElmY = element.offsetTop;
moveTime(); // Функция первоначальной оптимицации
return false;
}
function positElement() { // Функция часть вторичной оптимизации
// Заменяет после окончания движения тень на движущийся объект
var temp = document.getElementById('temp_move');
// заменяем координаты
element = document.getElementById(ID);
element.style.left = temp.offsetLeft + 'px';
element.style.top = temp.offsetTop + 'px';
temp.style.display = 'none'; // скрывает тень
return element;
}
function moveStart(e){ // Функция движения учитывающая глобальные настройки
if(document.all)e = event;
element = getObj('temp_move');
if(bool_move >= 10){ // если счетчик движения разрешает
// Счетчик движения как раз таки и есть опимизация первичная
// за счет задержки исчезает баг с неуспеванием расчитывать координаты и забиванием на событие onmouseup
if (settings['vector']!=undefined) { // настройка движения по координате
var px;
// X //
if (settings['vector']!='X') { // Если координата Y..
px = startPosElmX + e.clientX - startMousePosX;
element.style.left = px + 'px';
// Тут же сравнение максимальных и минимально допустимых координат
if (settings['max'] != undefined)
if (px > settings['max'])
element.style.left = settings['max'] + 'px';
if (settings['min']!=undefined)
if (px < settings['min'])
element.style.left = settings['min'] + 'px';
}
// Y //
if (settings['vector']!='Y') { // Если координата X
px = startPosElmY + e.clientY - startMousePosY;
element.style.top = px + 'px';
// Тут же сравнение максимальных и минимально допустимых координат
if (settings['max'] != undefined)
if (px > settings['max'])
element.style.top = settings['max'] + 'px';
if (settings['min']!=undefined)
if (px < settings['min'])
element.style.top = settings['min'] + 'px';
}
return false; // Это нуно для того чтобы выделения небыло
// Но чето неочень оно то работает )) Нуно для мазилы и оперы(геко)
}
}
}
function moveTime(){ // оптимизация первого порядка
// (Счетчик)
if(bool_move >= 0 && bool_move<=10){
bool_move++;
setTimeout('moveTime()',5);
}
if (document.selection){
var range = document.selection.createRange();
range.select(); // Это нуно для того чтобы выделения небыло
// Нуно для IE
}
return false; // Нуно для Геко
}
function moveStop(){ //возвращает елемент первоначального клика
// объект движения получается ))
if (bool_move>=0) { // и обнуляем счетчеГ ))
bool_move = -1;
return positElement();
}
}
function getObj(id){ // Думаю в пояснениях ненунается
return document.getElementById(id);
}
function _initMove (e) { // Инициализация движения частного характера
// Сдесь в зависимости от принятого id происходит инициализация настроек - для выполнения общей инициализации
// Вооо! как умно сказал ш сам удивился ))
// Думаю если сам бы разбирал эти писанины чьито нехрена не понял бы, Вот! :)
// Так что удачи!
if(document.all)
{e = event; eObj = e.srcElement}
else {eObj = e.target;}
var move, id = eObj.getAttribute('id');
var express = moveStop;
if (id == 'wind') { // настройки в зависимости от айдишника
// если дивов разных тобиш двигающихся будет много
// тада лучше юзать не кучу if а switch
var clss = 'move'; // класс тени
var settings = []; // массив настроек
settings['vector'] = 'YX'; // координата движения
// X - движение только по иксу
// Y - движение только по игреку
// XY или любое другое кроме вышеуказанных - по всей плоскасти
settings['max'] = 200; // максимальная координата, после достижения которой тень не будет двигаться далее
settings['min'] = 0; // минимальная координата, после достижения которой тень не будет двигаться далее
// если юзать движение по всей плоскости и указать максимальную и минимальную координаты
// то тень будет двигаться по квадрату
initMove (e, id, settings, clss, express) // Общая инициализация движения
}
}
document.onmousemove = moveStart; // отлавливания движения мыши
document.onmousedown = _initMove; // отлавливания опускания кнопки мыши
</script>
</head>
<style>
.move { border:1px dotted #000;}
/* Класс тени */
</style>
<body>
<!-- Объект движения -->
<div id='wind' style='border:1px solid #000; text-align:center; position:absolute'>
J| E P E T A LL| |/| <br/>
M E H 9|
</div>
</body>
</html>