GibboK
GibboK

Reputation: 73908

Saving position for div after dragging

I have the following script, when dragging the gray handler (top left) div re-sizes but at release of the mouse div is being place in the wrong place (at left margin).

I need to fix it as would be the bottom right handler.

What could be the problem? It seems related with event.clientX which is set to 0.

NOTES: click on the div to activate the handlers.

http://jsfiddle.net/cx41otxp/

  <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <style>
            #target {
                background-color: lightgreen;
            }

            .selected {
                border: 1px dashed red;
            }

            .handler {
                position: absolute;
                width: 10px;
                height: 10px;
                background-color: gray;
            }
        </style>
        <script>
            window.App = {
                config: {
                    elm: 'target',
                    elmInnerContent: 'inner-content',
                    x: null,
                    y: null,
                    w: null,
                    h: null,
                    handlerSize: 10
                },
                start: function () {
                    this.addEventListeners();
                },
                addEventListeners: function () {
                    var elm = document.getElementById(this.config.elm);
                    elm.addEventListener('click', function () {
                        if (!elm.classList.contains('selected')) {
                            elm.classList.add('selected');
                            this.getDimensions();
                            this.createHandlers();
                            this.setPositionHandlers();
                            this.addEventListenersHandlers();
                        } else {
                            elm.classList.remove('selected');
                            this.removeHandlers();
                        }
                    }.bind(this));
                },
                removeHandlers: function () {
                    var elm = document.getElementById('handler-wrapper');
                    elm.parentElement.removeChild(elm);
                },
                getDimensions: function () {
                    var elm = document.getElementById(this.config.elm);
                    this.config.x = elm.offsetLeft;
                    this.config.y = elm.offsetTop;
                    this.config.w = elm.clientWidth;
                    this.config.h = elm.clientHeight;
                },
                createHandlers: function () {
                    var wrpHandlers = document.createElement('div'),
                        htmlHandlers = '<div id="tl" class="tl handler" draggable="true">&nbsp;</div>';
                    htmlHandlers += '<div id="tr" class="tr handler" draggable="true">&nbsp;</div>';
                    htmlHandlers += '<div id="bl" class="bl handler" draggable="true">&nbsp;</div>';
                    htmlHandlers += '<div id="br" class="br handler" draggable="true">&nbsp;</div>';
                    wrpHandlers.id = "handler-wrapper";
                    wrpHandlers.innerHTML = htmlHandlers;
                    var elm = document.getElementById(this.config.elm);
                    elm.appendChild(wrpHandlers);
                },
                setPositionHandlers: function () {
                    this.getDimensions();
                    var elmTl = document.getElementById('tl'),
                        elmTr = document.getElementById('tr'),
                        elmBl = document.getElementById('bl'),
                        elmBr = document.getElementById('br');
                    elmTl.style.top = this.config.handlerSize * -1 + 'px';
                    elmTl.style.left = this.config.handlerSize * -1 + 'px';
                    elmTr.style.top = this.config.handlerSize * -1 + 'px';
                    elmTr.style.left = this.config.w + 'px';
                    elmBl.style.top = this.config.h + 'px';
                    elmBl.style.left = this.config.handlerSize * -1 + 'px';
                    elmBr.style.top = this.config.h + 'px';
                    elmBr.style.left = this.config.w + 'px';
                },
                addEventListenersHandlers: function () {
                    var elmTl = document.getElementById('tl'),
                    elmTr = document.getElementById('tr'),
                    elmBl = document.getElementById('bl'),
                    elmBr = document.getElementById('br');

                    elmTl.addEventListener('drag', function (event) {
                        this.resize('tl', event);
                    }.bind(this));
                    elmTr.addEventListener('drag', function (event) {
                        this.resize('tr', event);
                    }.bind(this));
                    elmBl.addEventListener('drag', function (event) {
                        this.resize('bl', event);
                    }.bind(this));
                    elmBr.addEventListener('drag', function (event) {
                        this.resize('br', event);
                    }.bind(this));
                },
                resize: function (handler, event) {
                    var elm = document.getElementById(this.config.elm);
                    switch (handler) {
                        case 'tl':
                            var marginR = elm.offsetLeft + elm.clientWidth,
                                newW = marginR - event.clientX,
                                xPos = event.clientX;

                            elm.style.left = xPos + 'px';
                            elm.style.width = newW + 'px';
                            this.setPositionHandlers();
                            break;
                        case 'tr':
                            break;
                        case 'bl':
                            break;
                        case 'br':
                            var newW = event.clientX - this.config.x,
                                newH = event.clientY - this.config.y;
                            elm.style.width = newW + 'px';
                            elm.style.height = newH + 'px';
                            this.setPositionHandlers();
                            break;
                    }
                },
            };


        </script>
        <title></title>
    </head>
    <body onload="window.App.start();">
        <div id="target" style="position: absolute; top: 100px; left: 100px; width: 100px; height: 100px;">
            <div id="inner-content">
                Some text here
            </div>
        </div>
    </body>
    </html>

Upvotes: 0

Views: 72

Answers (1)

zord
zord

Reputation: 4783

In the resize function, case 'tl': you have to do the same thing for top & height, what you do for left & width.

marginT = elm.offsetTop + elm.clientHeight,
newH = marginT - event.clientY,
yPos = event.clientY;

and

elm.style.top = yPos + 'px';
elm.style.height = newH + 'px';

Edit: Sorry, I think misread something the first time. FYI: your code is working fine in Safari, but in Chrome, I see your problem.

Edit2: I don't know what causes this. But if you just check xPos >= 0, you can work around it. I know it's an ugly hack, but this is the best I have. Fiddle updated.

Upvotes: 1

Related Questions