Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Drag - как-то вот так решил (https://javascript.ru/forum/project/31729-drag-kak-vot-tak-reshil.html)

shkoder 18.09.2012 23:50

Drag - как-то вот так решил
 
/js/drag.js
var dragable = function(node){
	var _this = this,
		_onmousemove = window.onmousemove,
		_onblur = window.onblur,
		_onmouseup = window.onmouseup;
	if (typeof node === 'object' && node.onmousedown) {
		node.onmousedown = function(e){
			var e = e || window.event;
			var target = e.target || e.srcElement;
			target.parentNode.style.position = 'absolute';
			var elementTop = target.parentNode.offsetTop,
				elementLeft = target.parentNode.offsetLeft;
			target.parentNode.style.top = elementTop + 'px';
			target.parentNode.style.left = elementLeft + 'px';
			var drag = true;
			_this.addClass(target.parentNode, 'dragable');
			window.onblur = window.onmouseup = function(){
				drag = false;
				_this.removeClass(target.parentNode, 'dragable');
				window.onmousemove = _onmousemove;
				window.onblur = _onblur;
				window.onmouseup = _onmouseup;
			};
			window.onmousemove = function(_e){
				if (drag){
					var _e = _e || window.event;
					target.parentNode.style.top = _e.clientY - e.clientY + elementTop + 'px';
					target.parentNode.style.left = _e.clientX - e.clientX + elementLeft + 'px';
				}
			}
		}
	}
}
dragable.prototype = {
	addClass : function(node, name){
		if (typeof node === 'object' && typeof node.setAttribute === 'function' && name){
			var stack = node.getAttribute('class') ? node.getAttribute('class').split(' ') : [];
			for (var i in stack)
				if (stack[i] === name)
					return true;
			stack.push(name);
			node.setAttribute('class', stack.join(' '));
			return true;
		}
		return false;
	},
	removeClass : function(node, name){
		if (typeof node === 'object' && typeof node.setAttribute === 'function' && name){
			var stack = node.getAttribute('class') ? node.getAttribute('class').split(' ') : [];
			for (var i in stack)
				if (stack[i] === name)
					delete stack[i];
			node.setAttribute('class', stack.join(' '));
			return true;
		}
		return false;		
	}
};

window.onload = function(){
	new dragable(document.getElementById('drag'));
}

html
<!DOCTYPE html>
<html>
	<head>
		<title>Drag</title>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<script type="text/javascript" src="/js/drag.js"></script>
		<style>
			html, body { height: 100%; margin: 0; padding: 0; }
			#drag { padding: 30px 0; width: 300px; text-align: center; display: block; border: 1px solid #CCCCCC; background: #EEEEEE; }
		</style>
	</head>
	<body>
		<div>
			<div id="drag">Возьми и перетащи меня!!!</div>
		</div>
	</body>
</html>


Покритикуйте

Ps: теперь с учетом замечаний Dim@
(не проверял)

Dim@ 19.09.2012 00:24

shkoder,
как минимум не кроссбраузерно, куда ни глянь - сплошные таргеты -
if (typeof node === 'object' && typeof node.onmousedown === 'object') {
        node.onmousedown = function(e){
            e.target.parentNode.style.position = 'absolute';
            var elementTop = e.target.parentNode.offsetTop,
                elementLeft = e.target.parentNode.offsetLeft;
они поддерживаются основными браузерами, для ИЕ же надо надо писать
var e = e || window.event;
var target = e.target || e.srcElement;

;) ну а с практической точки зрения пока не рассматривал - опиши, что нужно делать?:)

Dim@ 19.09.2012 00:27

shkoder,
плюс
Цитата:

typeof node.onmousedown === 'object'

не совсем правильно:
var obj = {};
var fun = function () {};
alert(["obj " + typeof obj, "fun " + typeof fun].join("\n"));

shkoder 19.09.2012 07:34

Цитата:

Сообщение от Dim@ (Сообщение 205370)
shkoder,
плюс
typeof node.onmousedown === 'object'

не совсем правильно:

Dim@,
вы правы, спасибо.
По поводу ie - его у меня нету, проверить не на чем, а под wine его запускать как-то не очень. Но учту учту.

Gozar 19.09.2012 14:00

shkoder,
Создай тестовую страницу, чтобы можно было перейти и посмотреть работу по клику. Либо [HTML RUN], а то лень копирастией заниматься.

Gozar 19.09.2012 14:10

Ещё, сразу вопрос. Почему это всё вешается на элемент вставленный в страницу?

Лично мне идея делать уже вставленный в страницу элемент Dragable видится абсолютно бесполезной. Гораздо удобней создавать элемент динамически и вставлять в страницу, а так же делать его удаляемым, по крестику справа.

В остальном задача двигать элемент на странице - задача довольно простая. Так что критиковать код я пожалуй не буду, т.к. для меня он не применим к жизни.

Gozar 19.09.2012 14:16

И ещё мне не нравиться, что идет привязка элемента по id, вернее то, что я сам должен назначать ему этот самый id, а не так:

new dragable({title:"Новое окошко", content: "<h1>Опа</h1> Ну и так далее текст"});


или так:

new dragable({title:"Новое окошко", content: "<h1>Опа</h1> Ну и так далее текст", parent: document.body});


Как будут вести себя элементы, когда их будет несколько? Как будет визуально отражаться вид элемента в зависимости от того, какой элемент сейчас сверху?

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

melky 20.09.2012 00:20

shkoder, критиковать очередной фабричный велосипед?


0. толку от сохранения обработчиков в текущий экзампляр, если в конструкторе образуется замыкание?

1. элемент должен appendChild'иться к body, не изменяя своего положения.

2. вместо изменения top\left лучше было бы изменять transform:translate(X,Y)

3. нужно ограничить частоту отрисовки до 24-х раз в секунду.

Gozar 20.09.2012 10:59

Цитата:

Сообщение от melky
вместо изменения top\left нужно изменять transform:translate(X,Y)

Почему именно нужно, а не можно?

melky 20.09.2012 18:21

Цитата:

Сообщение от Gozar (Сообщение 205533)
Почему именно нужно, а не можно?

поправил. это как способ улучшения.


Часовой пояс GMT +3, время: 20:16.