Link to home
Start Free TrialLog in
Avatar of cevoman
cevoman

asked on

Javascript Resizing

Hi all,

I'm trying to build a resize script so when a user hovers over the bottom line of a div they can click down and resize(like a window)

It is working however if the mouse moves too quickly the resize function stops running

There is no "mouseout" event only a mousedown and mouse up

for reference elementObj.newTop is set to the objects offsetTop (based on it's owners) once the user clicks down so that it isn't processed every time the mouse is moved - the code below is used while the mouse is down and the mouse is moved

Any ideas?
thanks for your help
elementResize : function(e)
		{
			
			var newMouseY = e.clientY-elementObj.newTop;
			elementObj.style.height = newMouseY + "px";
			elementObj.bottom = getTopPos(elementObj) + newMouseY;
			return false;
		}

Open in new window

Avatar of Pawel Witkowski
Pawel Witkowski
Flag of Poland image

To do any dragables you need 3 events.

mousedown - event on bottom line of div - function that will be fired on start draging window, it need to set variable that holds information what element is dragged,

mousemove - event on whole document - function that need to check if dragging is on (check is variable is set with proper element) and extends its size - it have to be on document level, otherwise if you move your mouse fast there will be diffrent event called for other elements instead of bar element,

mouseup - event also on document level - just to be sure that it will be cleared properly



any questions?
Avatar of cevoman
cevoman

ASKER

The function is part of a bigger class which i have created
Mousedown does exist but as part of the bigger function so if mouse down happens anywhere but the bottom line it will move the box and not resize it.

The problem isn't that the resize isn't functioning (as above it works well) the problem is that if the mouse moves to quickly javascript doesn't resize any more until you mouse down on the bottom line again (ie it just switches off any current "onmousemove" event handler)

Yes I know what is the problem and I gave you sollution for that... Problem is that events that you want to relay on are not fired because if you get your mouse outside of element - there is no longer event for it. So you need to listen on whole document...
Avatar of cevoman

ASKER

Hi there,

with respect - where did you give me a solution for my problem?
all you have provided is 3 events which need to happen (which are happening) for an element to be draggable.

Once the 'element.onmousedown' has fired, the 'document.onmousemove' is set and fires when the mouse moves fired - under normal conditions this will only return to null if the mouse is up,
however I have removed that part of the class so even if the mouse is up the event 'onmousemove' still runs - which it does except if I move the mouse too quickly

Kind regards
James

is that more clear ? You have to do this otherwise you lose event context for element.

 
 
var dragged;
element.onmousedown = function()
{
   dragged = this;
}
 
document.onmousemove = function()
{
 
if (dragged){
   // animate dragged
}
}
 
document.onmouseup = function()
{
dragged = null;
}

Open in new window

Avatar of cevoman

ASKER

Hi there,

as I have explained in each of the previous messages - these functions already exist and are already doing what they should be doing, I have briefly disabled 'document.onmouseup' so that the event handler for document.onmousemove is always running but the event still ends if the mouse is moved too quickly.

Kind regards
James
can you show me page with some example for this so I can look at this with mine tools ?
Avatar of cevoman

ASKER

Hi there,

I have attached the full code including a Div which is re-sizeable
you have to move the mouse very slowly for it to resize - I have also made it so the mouse can hover between the  bottom and -10 pixels to resize the bottom (makes it easier to locate the edge)

Kind regards
James
<script language=javascript>
	 function getTopPos(inputObj)
	{
	
		var returnValue = inputObj.offsetTop;
		while((inputObj = inputObj.offsetParent) != null){
			returnValue += inputObj.offsetTop;
		}
		return returnValue;
	}
 
 	var ElementRMove = 
	{
		elementObj : null,
		
		initResize : function(obj,e)
		{
			
			document.onmousemove = ElementRMove.elementCheckResize;
			obj.onmouseout = ElementRMove.checkResizeEnd;
			obj.bottom = getTopPos(obj) + obj.offsetHeight;
			elementObj = obj;
			return false;
			
		},
		
		elementCheckResize : function(e)
		{
			
			if(e.clientY > (elementObj.bottom-10) && e.clientY < elementObj.bottom)
			{
				document.body.style.cursor = "s-resize";
				elementObj.onmousedown = ElementRMove.initElementResize;
			}
			else{document.body.style.cursor = "default";}
			return false;
		
		},
		
		checkResizeEnd : function()
		{
			document.onmousemove = null;
			elementObj = null;
		},
		
		initElementResize : function (e)
		{
			
			document.onmousemove = ElementRMove.elementResize;
			document.onmouseup = ElementRMove.resizeEnd;
			elementObj.newTop = getTopPos(elementObj);
			return false;
			
		},
		
		elementResize : function(e)
		{
			var oldHeight = elementObj.offsetHeight;
			var newMouseY = e.clientY-elementObj.newTop;
			
			elementObj.style.height = newMouseY + "px";
			return false;
		},
		
		resizeEnd : function()
		{
			document.onmouseup = null;
			document.onmousemove = null;
			document.body.style.cursor = "default";
			elementObj = null;
			return false;
		}
	
	}
</script>
 
<div style="border: 1px solid #000000;" onmouseover="ElementRMove.initResize(this,event);">hello</div>

Open in new window

Sorry to tell that.. dont get me wrong... but I never saw so strange solution. I tried to patch it somehow but there are so many errors and bad design concept that I will create for you from scratch - analyse it then please! I will  give it to you in 5 min.
Avatar of cevoman

ASKER

The code was just banged together to see how it could work for a specific site admin panel, i would have refined it later but that part of the code was driving me nuts it seems as if to much is being processed for the event handler to keep up with the mouse moving but I have no idea thats why i wanted a fresh pair of eyes
Avatar of cevoman

ASKER

just to mention, there shouldn't be any errors in this code unless you run it from IE (which it's not been designed to run from)
Generally based on your code, but changed almost everything. Notice that you need to initEngine first to use it - in initalisation we attach those events to document. Rest is just to analyse for you.
<script language=javascript>
         function getTopPos(inputObj)
        {
        
                var returnValue = inputObj.offsetTop;
                while((inputObj = inputObj.offsetParent) != null){
                        returnValue += inputObj.offsetTop;
                }
                return returnValue;
        }
 
        var ElementRMove = 
        {
                elementObj : null,
                initEngine : function()
				{
					document.onmousemove = ElementRMove.mouseMove;
					document.onmouseup = ElementRMove.mouseUp;				
				},
				mouseMove : function (e)
				{
				    if (ElementRMove.elementObj)
					{
						var newMouseY = e.clientY-getTopPos(ElementRMove.elementObj);                        
                        ElementRMove.elementObj.style.height = newMouseY + "px";
					}
				},
				mouseUp : function()
				{
					ElementRMove.elementObj=null;
				},
				mouseOut : function()
				{
				
					if (ElementRMove.elementObj===null)
					{
						document.body.style.cursor = "default";
					}
				
				},
                initResize : function(obj)
                {
					if (ElementRMove.elementObj === null)
					{
						document.body.style.cursor = "s-resize";
					}
					obj.onmousedown = function()
					{
						ElementRMove.startResize(obj);
					}
					obj.onmouseout = ElementRMove.mouseOut;
 
                },
				
                startResize: function(obj)
				{
					ElementRMove.elementObj = obj;			
				}      
        }
		ElementRMove.initEngine();
</script>
 
<div style="border: 1px solid #000000;" onmouseover="ElementRMove.initResize(this);">hello</div>

Open in new window

ahh and sorry for naming functions - just change them to what you want ;)
Avatar of cevoman

ASKER

Hi there,

It works - which is great

But the reason my code was designed the way it was, was to allow there to be multiple objects on one screen (all resizeable) and also so the mouse is tracked when inside an object (so it knows when it is on the bottom line) as the design is to allow for an object to be resized by width and dragged finally to ensure the "class" doesn't hog the mousemove / mouseup events and allows other objects in a form to take focus for the same function or different

Adding the relevant code to yours brings it almost identically back to mine and causes the same issue.
Any suggestions?
???

There should be no issues with mine solution - it creates one global dragging element that can drag one item at any given time. If you mouseover on another element it should work... have you test it  already?
Try this i think that I know what you mean
<script language=javascript>
         function getTopPos(inputObj)
        {
        
                var returnValue = inputObj.offsetTop;
                while((inputObj = inputObj.offsetParent) != null){
                        returnValue += inputObj.offsetTop;
                }
                return returnValue;
        }
 
        var ElementRMove = 
        {
                elementObj : null,
                initEngine : function()
				{
					document.onmousemove = ElementRMove.mouseMove;
					document.onmouseup = ElementRMove.mouseUp;				
				},
				mouseMove : function (e)
				{
				    if (ElementRMove.elementObj)
					{
						var newMouseY = e.clientY-getTopPos(ElementRMove.elementObj);                        
                        ElementRMove.elementObj.style.height = newMouseY + "px";
					}
				},
				mouseUp : function()
				{
					if (ElementRMove.elementObj!==null)
					{
						ElementRMove.elementObj=null;
						ElementRMove.elementObj.onmousedown = null;
						ElementRMove.elementObj.onmouseout = null;
					}
				},
				mouseOut : function()
				{
				
					if (ElementRMove.elementObj===null)
					{
						document.body.style.cursor = "default";
					}
				
				},
                initResize : function(obj)
                {
					if (ElementRMove.elementObj === null)
					{
						document.body.style.cursor = "s-resize";
						obj.onmousedown = function()
						{
							ElementRMove.startResize(obj);
						}
						obj.onmouseout = ElementRMove.mouseOut;						
					}
 
 
                },
				
                startResize: function(obj)
				{
					ElementRMove.elementObj = obj;			
				}      
        }
		ElementRMove.initEngine();
</script>
 
<div style="border: 1px solid #000000;" onmouseover="ElementRMove.initResize(this);">hello</div>
<div style="border: 1px solid #000000;" onmouseover="ElementRMove.initResize(this);">world</div>

Open in new window

Avatar of cevoman

ASKER

Hi there,

It definitely works but it is dependant on only those objects can utilize onmousemove and onmouseup so if there is another class / object on a page which takes control of onmousemove or onmouseup the script needs to be reinitialized.

Kind regards
James
google ->  addEventListener  MDC   ;)
what I basicaly create is just an example - if you worried about what you saying just use addEventListener instead of simply .onmouseover

function registerEvent(el,eventName, func)
{
 
if (el.addEventListener){
  el.addEventListener(eventName, func, false); 
} else if (el.attachEvent){
  el.attachEvent('on'+eventName, func);
}
 
}
 
 
registerEvent(document,"mousemove",function(){ console.log('a')});

Open in new window

Avatar of Michel Plungjan
I believe console does not work out of the box...
I believe that autor understand idea of how it should work like
Only if he has firebug installed
Code I provide is just an example - it will not work with anything else if is not well understanded / correctly called
ASKER CERTIFIED SOLUTION
Avatar of GoofyDawg
GoofyDawg
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial