11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour à tous,
J'ai coder une petite classe (sur le modèle prototype) qui permet de redimensionner un élément qu'on lui passe comme une fenêtre d'application.

Avec un seul élément tous ce passe très bien :

<div id="windows" style="top:35px; left:100px;">
	<div id="tete">
	Windows 
	</div>
</div>
<script type="text/javascript">
new Resizable("windows");
</script>


En revanche lorsque je veux instancier un second élément et donc le rendre lui aussi redimensionnable , et bien les deux élément sont lié.
Si je redimensionne le premier , la taille du second change et vice versa.

Je vous met ici le code de la classe au cas ou vous verriez une erreur :
/**
* Classe permettant le redimensionnement d'un élément
* @author Olivier ROGER
* @version 1.0.0
*
*/
Resizable = Class.create();
Resizable.prototype = 
{
	initialize:function(elem)
	{
		this.RsE  = 1;
		this.RsW  = 2;
		this.RsS  = 3;
		this.RsSE = 4;
		this.RsSW = 5;
		//Postion du curseur à l'appel de getCursorPos
		this.curPosX;
		this.curPosY;
		this.curPosXOld;
		this.curPosYOld;
		//A t'on cliqué ?
		this.clicked = false;
		//Element à déplacer
		this.objet = $(elem);
		//Zone dans laquelle on passe en mode resize (px)
		this.resizeZoneH = 8;
		this.resizeZoneV = 8;
		//Taille
		this.initWidth = this.objet.getWidth();
		this.initHeight = this.objet.getHeight();
		this.initLeft	= this.objet.style.left;
		this.minWidth   = 50;
		this.minHeight   = 25;
		//Event
		this.eventMouseDown = this.onDownAction.bindAsEventListener(this);
		this.eventMouseUp = this.onUpAction.bindAsEventListener(this);
		this.eventMouseMove = this.onMoveAction.bindAsEventListener(this);
		Event.observe(document, "mousedown", this.eventMouseDown);
		Event.observe(document, "mouseup", this.eventMouseUp);
		Event.observe(document, "mousemove", this.eventMouseMove);
		this.action;
	},
	
	/**
	* Récupère la position du curseur
	* @param event e
	*/
	getCursorPos:function(e)
	{
		this.curPosX = Event.pointerX(e);
		this.curPosY = Event.pointerY(e);
	},
	
	/**
	* Action lancée à la pression du bouton
	* @param event e
	*/
	onDownAction:function(e)
	{
		this.clicked = true;
		this.initWidth = this.objet.getWidth();
		this.initHeight = this.objet.getHeight();
		this.getCursorPos(e);
		this.curPosXOld = this.curPosX;
		this.curPosYOld = this.curPosY;
		this.action = this.changeCursor(e);	
	},
	
	/**
	* Action lancée au relachement du bouton
	* @param event e
	*/
	onUpAction:function(e)
	{
		this.clicked = false;
		this.initWidth = this.objet.getWidth();
		this.initHeight = this.objet.getHeight();
		this.initLeft	= this.objet.style.left;
	},
	
	/**
	* Action lors du déplacement de la souris
	* @param event e
	*/
	onMoveAction:function(e)
	{
		if(this.clicked)
		{
			this.getCursorPos(e);
			switch(this.action)
			{
				case this.RsE :
					this.resizeE();
				break;
				case this.RsW : 
					this.resizeW();
				break;
				case this.RsS :
					this.resizeS();
				break;
				case this.RsSE :
					this.resizeS();
					this.resizeE();
				break;
				case this.RsSW :
					this.resizeS();
					this.resizeW();
				break;
			}
		}
		else
		{
			this.changeCursor(e);
		}
	},
	
	/**
	* Change le curseur en fonction de sa position
	* @param event e
	* @return int Type du redimensionnement
	*/
	changeCursor:function(e)
	{
		var posX = Event.pointerX(e);
		var posY = Event.pointerY(e);
		
		//Bas droit
		if(posX>((parseInt(this.objet.style.left)+this.objet.getWidth())-this.resizeZoneH) && posX<(parseInt(this.objet.style.left)+this.objet.getWidth())
			&& posY>((parseInt(this.objet.style.top)+this.objet.getHeight())-this.resizeZoneV) && posY<(parseInt(this.objet.style.top)+this.objet.getHeight()))
		{
			this.objet.setStyle({cursor:'se-resize'});
			return this.RsSE;
		}
		//bas gauche
		if(posX>parseInt(this.objet.style.left) && posX<(parseInt(this.objet.style.left)+this.resizeZoneH)
			&& posY>((parseInt(this.objet.style.top)+this.objet.getHeight())-this.resizeZoneV) && posY<(parseInt(this.objet.style.top)+this.objet.getHeight()))
		{
			this.objet.setStyle({cursor:'sw-resize'});
			return this.RsSW;
		}
		
		//Coté droit
		if(posX>((parseInt(this.objet.style.left)+this.objet.getWidth())-this.resizeZoneH) && posX<(parseInt(this.objet.style.left)+this.objet.getWidth()))
		{
			this.objet.setStyle({cursor:'e-resize'});
			return 1;
		}
		
		//Coté gauche
		if(posX>parseInt(this.objet.style.left) && posX<(parseInt(this.objet.style.left)+this.resizeZoneH))
		{
			this.objet.setStyle({cursor:'w-resize'});
			return this.RsW;
		}
		
		//Bas
		if(posY>((parseInt(this.objet.style.top)+this.objet.getHeight())-this.resizeZoneV) && posY<(parseInt(this.objet.style.top)+this.objet.getHeight()))
		{
			this.objet.setStyle({cursor:'s-resize'});
			return this.RsS;
		}
		
		this.objet.setStyle({cursor:'auto'});
		return this.RsE;
		
	},
	
	/**
	* Redimensionne l'objet vers la droite
	*
	*/
	resizeE:function()
	{
		var ecart 		= (parseInt(this.objet.style.left) + this.initWidth)-this.curPosX;
		var newWidth 	= this.initWidth - ecart;
		if(newWidth > this.minWidth)
			this.objet.setStyle({width:newWidth});
	},
	
	/**
	* Redimensionne l'objet vers la gauche
	* 
	*/
	resizeW:function()
	{
		var ecart		= parseInt(this.initLeft) -this.curPosX;
		var newWidth 	= this.initWidth + ecart;
		var newLeft		= this.curPosX;
		if(newWidth > this.minWidth)
			this.objet.setStyle({left:newLeft,width:newWidth});
	},
	
	/**
	* Redimensionne l'objet vers le bas
	* 
	*/
	resizeS:function()
	{
		var ecart 		= (parseInt(this.objet.style.top)+this.initHeight) - this.curPosY;
		var newHeight 	= this.initHeight - ecart; 
		if(newHeight > this.minHeight)
			this.objet.setStyle({height:newHeight});
	}
	
}


Je précise que c'est ma première tentative de codage "poo" en JS.

Vous pouvez télécharger un exemple avec tous les fichiers qui vont bien (prototype, scriptaculous ...) ici : http://www.lanforums.com/dl/draggablewindows.zip

Merci pour votre aide Smiley cligne
Modifié par grunky (20 Oct 2008 - 08:37)
Bonjour, pas mal du tout, cette petite classe... si elle fonctionnait comme tu le veux Smiley cligne

Sufiyaka : s'il faut bien observer les mouvements de la souris sur tout le document, il faut observer le mouseover et le mouseup seulement sur l'élément de l'objet : remplace juste


		Event.observe(document, "mousedown", this.eventMouseDown);

		Event.observe(document, "mouseup", this.eventMouseUp);

		Event.observe(document, "mousemove", this.eventMouseMove);



par :

		Event.observe(this.objet, "mousedown", this.eventMouseDown);
		Event.observe(this.objet, "mouseup", this.eventMouseUp);
		Event.observe(document, "mousemove", this.eventMouseMove);


ou même, puisque tu utilises une version 1.6.x de prototype :

		this.objet.observe("mousedown", this.eventMouseDown);
		this.objet.observe("mouseup", this.eventMouseUp);
		document.observe("mousemove", this.eventMouseMove);



D'ailleurs, si je puis me permettre, une classe se définit désormais ainsi :


Resizable = Class.create({
	initialize:function(elem)
	{
		// code
	},
	autreFonction(param) {
		// code
	}
});


Et voilà, ça marche comme tu veux Smiley cligne

@+
Laruiss
Super merci Smiley smile

Petite précision cependant , dans mon cas j'ai laisser le mouseup sur le document entier , sinon il n'est plus possible d'avoir à la fois un draggable et un Resizable.

Je prend note de la nouvelle structure des classes en 1.6.x Smiley cligne