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
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;
}
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)
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...
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
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;
}
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
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 ?
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
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>
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.
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
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>
ahh and sorry for naming functions - just change them to what you want ;)
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?
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?
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>
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
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')});
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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?