[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.javascript

Move a div with mouse

danca

7/21/2015 11:27:00 AM

I needed to solve an old stupid issue regarding an <iframe> (aka a <div>
containing an <iframe>) that sometimes is misplaced in a page [served by
a CGI] containing a form (depending by the size of the browser's
window), and didn't want to go through calculations involving the size
of the viewport or adaptive design (for now, in the future maybe...),
moreover such a functionality seems handy, so I decided to implement a
"drag 'n drop" function, and began to search around and to try to figure
out how to do the damn thing.

After many hours searching, studying, testing and tinkering with Firefox
and IE I ended up with this function:

// usage: makeMovable(<id of the div to drag>,<optional id of a
"handler" (f.e. a small image inside the div) to drag the div>)

var makeMovable = function(target, handle) {
target = document.getElementById(target);
if (!handle) handle = target; else handle=document.getElementById(handle);
if (document.addEventListener){

handle.addEventListener("mousedown",function(event){e=event||window.event;if
(e.preventDefault) e.preventDefault(); else e.returnValue = false;})
}else{

handle.attachEvent("onmousedown",function(event){e=event||window.event;if (e.preventDefault)
e.preventDefault(); else e.returnValue = false; })
}
handle.onmousedown = function(event) {
var e=event||window.event
if (window.event){ //IE
var initialXOffset = target.offsetLeft - e.clientX
var initialYOffset = target.offsetTop - e.clientY
document.onmousemove = function() {
target.style.left = e.clientX + initialXOffset+"px";
target.style.top = e.clientY + initialYOffset+"px";
return false;
}
}else if (event){ //moz
var initialXOffset = target.offsetLeft - event.pageX;
var initialYOffset = target.offsetTop - event.pageY;
document.onmousemove = function(event) {
target.style.left = event.pageX + initialXOffset;
target.style.top = event.pageY + initialYOffset;
}
}else{ alert("no event")// just in case}
document.onmouseup = function() {
document.onmousemove = null;
document.onmouseup = null;
}
return false;
}
}

The first part tries to prevent the default action for the drag action
on the div. I think to remember that HTML5 provides a way to natively
support drag and drop, but since I still am lost with HTML5, hmmm, I
disabled this little icon appearing in Firefox on dragging the div, and
to be sure tried to make the same for IE.

Next comes the real thing, the onmousedown event activates the
onmousemove event and applies to the style.top and style.left properties
of the div the coordinates obtained from the mouse position.

I was very proud of the result and spent some time moving a <div> all
around alternatively with IE and FF, while drinking a deserved gin and
tonic (very hot here - 36 c°).

Then I tried on Chrome and Safari and none of them reacted. :-(
A subsequent session of work with the Chrome's debugger was inconclusive.

At the end of the tale, I implemented a very dumb "dock 'n release"
function instead, compatible with all the "Fantastic 4" and 15 lines of
code wide, and I am quite satisfied with it. First click on the handler
docks the div to the mouse and second one releases it to the new
position. :-)

So, JFC, why this does not work with those 2 browsers?

JFTR
The dock function:

function dock(el){
if (document.onmousemove!=null) {
el.innerHTML="Dock"
document.onmousemove=null;
}else {
el.innerHTML="Release"
document.onmousemove=function(eve){
e=eve||window.event
propx=e.clientX?"clientX":"pageX"
propy=e.clientY?"clientY":"pageY"
el.parentNode.style.top=(e[propy])-5+"px"
el.parentNode.style.left=(e[propx])-5+"px"
}
}
}

<html>
<body>
<div
style="position:absolute;top:150px;left:600px;width:340px;height:155px;background-color:#c0c0c0;">
<div
style="width:40px;height:15px;background-color:#48D7FF;font-size:8px;position:absolute;top:0px;float:left;"
onclick="dock(this)">Dock</div>
<iframe src="Crono.html" id="ifra"
style="position:relative;left:41px;"></iframe>
</div>
</body>
</html>

Dan
--
"Everybody should pay taxes with a smile"
I tried, but they want money.
7 Answers

Thomas 'PointedEars' Lahn

7/24/2015 6:37:00 PM

0

danca (Daniele Campagna) wrote:

> I needed to solve an old stupid issue regarding an <iframe> (aka a <div>
> containing an <iframe>) that sometimes is misplaced in a page [served by
> a CGI] containing a form (depending by the size of the browser's
> window), and didn't want to go through calculations involving the size
> of the viewport or adaptive design (for now, in the future maybe...),
> moreover such a functionality seems handy, so I decided to implement a
> "drag 'n drop" function, and began to search around and to try to figure
> out how to do the damn thing.
>
> After many hours searching, studying, testing and tinkering with Firefox
> and IE I ended up with this function:

First of all, your code (style) is barely readable. If you want others to
review your code, you should employ a code style that is easily readable.
A decent code editor can help with that.

Particularly for Usenet, you should post code that still works when word-
wrapped at about the 72th text column. See the FAQ.

> // usage: makeMovable(<id of the div to drag>,<optional id of a
> "handler" (f.e. a small image inside the div) to drag the div>)

This code was word-wrapped by your newsreader and does not work anymore
because of that. It would not have happened had you used /*â?¦ */ instead,
which I recommend for documentation comments.

> var makeMovable = function(target, handle) {
> target = document.getElementById(target);
> if (!handle) handle = target; else
> handle=document.getElementById(handle); if (document.addEventListener){
>
> handle.addEventListener("mousedown",function(event){e=event||
window.event;if
> (e.preventDefault) e.preventDefault(); else e.returnValue = false;})

Wrong. You are testing â??document.addEventListenerâ?, but you are calling
â??handle.addEventListenerâ? â?? a different method. Test exactly that which you
will be using, and test for callable objects to be callable, not merely
existing. In particular, do not subject methods of host objects to simple
type-converting tests; this is error-prone (search for â??isHostMethodâ?).

> }else{
>
> handle.attachEvent("onmousedown",function(event){e=event||window.event;if
> (e.preventDefault) e.preventDefault(); else e.returnValue = false; })
> }
> handle.onmousedown = function(event) {

It makes no sense to use one of EventTarget::addEVentListener() from the W3C
DOM and eventTarget.attachEvent() from the MSHTML DOM, *and* subsequently
EventTarget::onmousedown from the Netscape/HTML5 DOM. See my tests about
the side effects of using both from earlier this year, and
jsx.dom.addEventListener() for the correct approach.

> [â?¦]
> }else{ alert("no event")// just in case}

This may be a syntax error. Your code is so unreadable that it is difficult
to tell without copying and reformatting it.

> document.onmouseup = function() {
> document.onmousemove = null;
> document.onmouseup = null;
> }

Nonsense.

> [â?¦]
> So, JFC,

You want to refrain from cursing when asking a question.

See also <http://www.catb.org/~esr/faqs/smart-question....

> why this does not work with those 2 browsers?

You are still under the misconception that it would be prudent to think in
terms of browsers instead of DOM implementations.

--
PointedEars
FAQ: <http://PointedEars.... | SVN: <http://PointedEars.de...
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-...
Please do not cc me. / Bitte keine Kopien per E-Mail.

danca

7/24/2015 7:58:00 PM

0

Il 07/24/2015 08:36 PM, Thomas 'PointedEars' Lahn ha scritto:
> danca (Daniele Campagna) wrote:
>
>> I needed to solve an old stupid issue regarding an <iframe> (aka a <div>
>> containing an <iframe>) that sometimes is misplaced in a page [served by
....
>>
>> After many hours searching, studying, testing and tinkering with Firefox
>> and IE I ended up with this function:
>
> First of all, your code (style) is barely readable. If you want others to
> review your code, you should employ a code style that is easily readable.
> A decent code editor can help with that.

:-(

>
> Particularly for Usenet, you should post code that still works when word-
> wrapped at about the 72th text column. See the FAQ.

I TRIED to copy-and-paste and then to adjust the [horrible] result.

>
>> // usage: makeMovable(<id of the div to drag>,<optional id of a
>> "handler" (f.e. a small image inside the div) to drag the div>)
>
> This code was word-wrapped by your newsreader and does not work anymore
> because of that. It would not have happened had you used /*â?¦ */ instead,
> which I recommend for documentation comments.
>

OK.

>> var makeMovable = function(target, handle) {
>> target = document.getElementById(target);
>> if (!handle) handle = target; else
>> handle=document.getElementById(handle); if (document.addEventListener){
>>
>> handle.addEventListener("mousedown",function(event){e=event||
> window.event;if
>> (e.preventDefault) e.preventDefault(); else e.returnValue = false;})
>
> Wrong. You are testing â??document.addEventListenerâ?, but you are calling
> â??handle.addEventListenerâ? â?? a different method. Test exactly that which you
> will be using, and test for callable objects to be callable, not merely
> existing. In particular, do not subject methods of host objects to simple
> type-converting tests; this is error-prone (search for â??isHostMethodâ?).

So it is not correct to infer[It exists? I mean make a deduction] that
if document.addEventListener does not exist <something>.addEventListener
couldn't instead exist? Hummmmm...
(Ubi major minus cessat).

>
>> }else{
>>
>> handle.attachEvent("onmousedown",function(event){e=event||window.event;if
>> (e.preventDefault) e.preventDefault(); else e.returnValue = false; })
>> }
>> handle.onmousedown = function(event) {
>
> It makes no sense to use one of EventTarget::addEVentListener() from the W3C
> DOM and eventTarget.attachEvent() from the MSHTML DOM, *and* subsequently
> EventTarget::onmousedown from the Netscape/HTML5 DOM. See my tests about
> the side effects of using both from earlier this year, and
> jsx.dom.addEventListener() for the correct approach.

OMG. Ok, I'll take a look.

>
>> [â?¦]
>> }else{ alert("no event")// just in case}
>
> This may be a syntax error. Your code is so unreadable that it is difficult
> to tell without copying and reformatting it.
>
>> document.onmouseup = function() {
>> document.onmousemove = null;
>> document.onmouseup = null;
>> }
>
> Nonsense.

Ehm... it should cancel the event listeners - and it seems to work in IE
and FF. What's wrong with canceling eventListeners that simple way?

>
>> [â?¦]
>> So, JFC,
>
> You want to refrain from cursing when asking a question.
>
> See also <http://www.catb.org/~esr/faqs/smart-question....
>
>> why this does not work with those 2 browsers?
>
> You are still under the misconception that it would be prudent to think in
> terms of browsers instead of DOM implementations.
>

NoNo, I am not thinking at all. I just reported the thing. What the
hell, I didn't tried browser sniffing at all, and I simply can't imagine
what feature detection I should put on to distinguish between the
[working] IE and FF and the [aliens] Chrome and Safari.

I exhausted all my thinking capabilities in the hours I tried to make it
work. Now I am void of ideas - and this is the reason I bother people in
this NG.

Anyway thanks for your time - but, an idea about the fact that Chrome
and Safari seem to dislike my code is still to come, while an idea about
why you dislike it has been clearly expressed. :-)

Dan
--
"Everybody should pay taxes with a smile"
I tried, but they want money.

Thomas 'PointedEars' Lahn

7/25/2015 12:07:00 PM

0

danca (Daniele Campagna) wrote:

> Il 07/24/2015 08:36 PM, Thomas 'PointedEars' Lahn ha scritto:
>> danca (Daniele Campagna) wrote:
>
> [â?¦]
> I TRIED to copy-and-paste and then to adjust the [horrible] result.

I think you know what to do now.

> So it is not correct to infer[It exists? I mean make a deduction] that
> if document.addEventListener does not exist <something>.addEventListener
> couldn't instead exist?

Yes.

> Hummmmm...
> (Ubi major minus cessat).

_maior_

>>> [â?¦]
>>> }else{ alert("no event")// just in case}
>>
>> This may be a syntax error. Your code is so unreadable that it is
>> difficult to tell without copying and reformatting it.
>>
>>> document.onmouseup = function() {
>>> document.onmousemove = null;
>>> document.onmouseup = null;
>>> }
>>
>> Nonsense.
>
> Ehm... it should cancel the event listeners - and it seems to work in IE
> and FF. What's wrong with canceling eventListeners that simple way?

*Events* are canceled, not event listeners.

You are defining and _undefining_ event listeners here. It makes no sense
to define/*overwrite* an event listener for an event, that may not have been
defined in the first place, just to undefine it when the event is fired.

--
PointedEars
FAQ: <http://PointedEars.... | SVN: <http://PointedEars.de...
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-...
Please do not cc me. / Bitte keine Kopien per E-Mail.

danca

7/25/2015 5:48:00 PM

0

Il 07/25/2015 02:07 PM, Thomas 'PointedEars' Lahn ha scritto:
> danca (Daniele Campagna) wrote:
>
>> Il 07/24/2015 08:36 PM, Thomas 'PointedEars' Lahn ha scritto:
>>> danca (Daniele Campagna) wrote:
>>
>> [â?¦]
>> I TRIED to copy-and-paste and then to adjust the [horrible] result.
>
> I think you know what to do now.
>

Apart from putting comments between /*..*/ I am not sure about the 72
columns limit - I often read messages not wrapped at all, and I must
explicitly word wrap them (CTRL-R in Thunderbird). But no clues about
the messages I write.

>> So it is not correct to infer[It exists? I mean make a deduction] that
>> if document.addEventListener does not exist <something>.addEventListener
>> couldn't instead exist?
>
> Yes.
>
>> Hummmmm...
>> (Ubi major minus cessat).
>
> _maior_

And minor, not minus. I need vacations.

>
>>>> [â?¦]
>>>> }else{ alert("no event")// just in case}
>>>
>>> This may be a syntax error. Your code is so unreadable that it is
>>> difficult to tell without copying and reformatting it.
>>>
>>>> document.onmouseup = function() {
>>>> document.onmousemove = null;
>>>> document.onmouseup = null;
>>>> }
>>>
>>> Nonsense.
>>
>> Ehm... it should cancel the event listeners - and it seems to work in IE
>> and FF. What's wrong with canceling eventListeners that simple way?
>
> *Events* are canceled, not event listeners.

OK

>
> You are defining and _undefining_ event listeners here. It makes no sense
> to define/*overwrite* an event listener for an event, that may not have been
> defined in the first place, just to undefine it when the event is fired.
>

The onmousedown activates the onmousemove and the onmouseup. The latter
in turn when fired cancels the onmousemove and itself - so it is fired
only one time and only if it has been defined by onmousedown.

Dan
--
"Everybody should pay taxes with a smile"
I tried, but they want money.

Thomas 'PointedEars' Lahn

7/25/2015 6:55:00 PM

0

danca (Daniele Campagna) wrote:

> Il 07/25/2015 02:07 PM, Thomas 'PointedEars' Lahn ha scritto:
>> danca (Daniele Campagna) wrote:
>>> Il 07/24/2015 08:36 PM, Thomas 'PointedEars' Lahn ha scritto:
>>>> danca (Daniele Campagna) wrote:
>>> [â?¦]
>>> I TRIED to copy-and-paste and then to adjust the [horrible] result.
>> I think you know what to do now.
>
> Apart from putting comments between /*..*/ I am not sure about the 72
> columns limit - I often read messages not wrapped at all, and I must
> explicitly word wrap them (CTRL-R in Thunderbird). But no clues about
> the messages I write.

The feature is called â??format=flowedâ?. Messages appear as if they were not
word-wrapped properly by the sender because the text is reformatted at the
receiverâ??s for display so as to be wrapped within the viewport (in
Thunderbird: the Message Pane). You can disable this feature, both for
sending (that is, for other newsreaders that support this feature for
display) and reading, if it causes you problems.

Word-wrapping at column 72 is the default setting in Thunderbird, so I do
not see why you did not see that your code would break if posted as is.

That said, I thought it would be obvious to you by now that you need to
format your code properly in the first place â?? not just for posting.
Employing an easily readable code style, including shorter lines, not only
helps with code reviews by others, but helps to avoid bugs in the first
place. (I am having a /déjà vu/ here.)

>> You are defining and _undefining_ event listeners here. It makes no
>> sense to define/*overwrite* an event listener for an event, that may not
>> have been defined in the first place, just to undefine it when the event
>> is fired.
>
> The onmousedown activates the onmousemove and the onmouseup. The latter
> in turn when fired cancels the onmousemove and itself - so it is fired
> only one time and only if it has been defined by onmousedown.

Yes; your code was hard to read, so easy to misread.

You should use flags instead of creating Function instances repeatedly.

That aside:

Your code most certainly does not work in Chrome because you are assigning
to .onmousemove after you called .addEventListener() for the same target,
which adds *two* event listeners for the same event and target: the listener
added with .addEventListener() is added after the one assigned to
..onmousemove. (As I showed earlier this year.)

And it probably does not work in Chrome because your feature test is wrong
again, a faulty inference: you are testing â??window.eventâ? but access
â??e.clientXâ?, and you are testing â??eventâ?, but you are accessing
â??event.pageXâ?. Debugging should show the underlying assumptions to be wrong
in the offending runtime environments.

I am not willing to dig deeper before you have posted a readable version of
your code along with reports from further debugging.

BTW, there are drag-and-drop event types now.

--
PointedEars
FAQ: <http://PointedEars.... | SVN: <http://PointedEars.de...
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-...
Please do not cc me. / Bitte keine Kopien per E-Mail.

danca

7/26/2015 10:55:00 AM

0

Il 07/25/2015 08:54 PM, Thomas 'PointedEars' Lahn ha scritto:
>
> The feature is called â??format=flowedâ?...

....[instructions about the use of the newsreader]
OK Thanks.

>
> You should use flags instead of creating Function instances repeatedly.
>
> That aside:
>
> Your code most certainly does not work in Chrome because you are assigning
> to .onmousemove after you called .addEventListener() for the same target,
> which adds *two* event listeners for the same event and target: the listener
> added with .addEventListener() is added after the one assigned to
> .onmousemove. (As I showed earlier this year.)
>
> And it probably does not work in Chrome because your feature test is wrong
> again, a faulty inference: you are testing â??window.eventâ? but access
> â??e.clientXâ?, and you are testing â??eventâ?, but you are accessing
> â??event.pageXâ?. Debugging should show the underlying assumptions to be wrong
> in the offending runtime environments.
>

Hummmmm... Interesting [guess: in the second sentence I should read
"Safari"?]. Thank You, I would also note that the answer came on a
Saturday - thanks for your time.
I'll retest and give a follow-up, but I need some more time to go deeper
in the matter.

>
> BTW, there are drag-and-drop event types now.
>

Eh... yes. I am [vaguely] aware of that. Let me understand this, and
then to move forward.

Dan
--
"Everybody should pay taxes with a smile"
I tried, but they want money.

Thomas 'PointedEars' Lahn

7/26/2015 11:36:00 AM

0

danca (Daniele Campagna) wrote:

> Il 07/25/2015 08:54 PM, Thomas 'PointedEars' Lahn ha scritto:
>> Your code most certainly does not work in Chrome because you are
>> assigning to .onmousemove after you called .addEventListener() for the
>> same target, which adds *two* event listeners for the same event and
>> target: the listener added with .addEventListener() is added after the
>> one assigned to .onmousemove. (As I showed earlier this year.)
>>
>> And it probably does not work in Chrome because your feature test is
>> wrong again, a faulty inference: you are testing â??window.eventâ? but
>> access â??e.clientXâ?, and you are testing â??eventâ?, but you are accessing
>> â??event.pageXâ?. Debugging should show the underlying assumptions to be
>> wrong in the offending runtime environments.
>
> Hummmmm... Interesting [guess: in the second sentence I should read
> "Safari"?].

I have not tested in Safari, but it is probable that the same logic applies
there because Safari is based on WebKit, too. The main difference between
the first and second _paragraph_ is the certainty of the former and the mere
probability of the latter (IMO).

--
PointedEars
FAQ: <http://PointedEars.... | SVN: <http://PointedEars.de...
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-...
Please do not cc me. / Bitte keine Kopien per E-Mail.