web-dev-qa-db-fra.com

Comment rendre un élément HTML redimensionnable à l'aide de javascript pur?

Je me demandais comment nous pouvons redimensionner un élément HTML tel que l'élément de balise <div> ou <p> lorsque vous cliquez dessus avec du JavaScript pur, pas avec la bibliothèque jQuery ou toute autre bibliothèque.

50
monk

Je recommande vraiment d'utiliser une sorte de bibliothèque, mais vous l'avez demandée, vous l'avez:

var p = document.querySelector('p'); // element to make resizable

p.addEventListener('click', function init() {
    p.removeEventListener('click', init, false);
    p.className = p.className + ' resizable';
    var resizer = document.createElement('div');
    resizer.className = 'resizer';
    p.appendChild(resizer);
    resizer.addEventListener('mousedown', initDrag, false);
}, false);

var startX, startY, startWidth, startHeight;

function initDrag(e) {
   startX = e.clientX;
   startY = e.clientY;
   startWidth = parseInt(document.defaultView.getComputedStyle(p).width, 10);
   startHeight = parseInt(document.defaultView.getComputedStyle(p).height, 10);
   document.documentElement.addEventListener('mousemove', doDrag, false);
   document.documentElement.addEventListener('mouseup', stopDrag, false);
}

function doDrag(e) {
   p.style.width = (startWidth + e.clientX - startX) + 'px';
   p.style.height = (startHeight + e.clientY - startY) + 'px';
}

function stopDrag(e) {
    document.documentElement.removeEventListener('mousemove', doDrag, false);
    document.documentElement.removeEventListener('mouseup', stopDrag, false);
}

Démo

Rappelez-vous que cela peut ne pas fonctionner dans tous les navigateurs (testé uniquement dans Firefox, ne fonctionnant certainement pas dans IE <9).

86
user123444555621

qu'en est-il d'une solution pure CSS3?

div {
    resize: both;
    overflow: auto;
} 

Documents Web MDN

Exemple W3Schools

Support du navigateur

48
Alex

Est simple:

Exemple: https://jsfiddle.net/RainStudios/mw786v1w/

var element = document.getElementById('element');
//create box in bottom-left
var resizer = document.createElement('div');
resizer.style.width = '10px';
resizer.style.height = '10px';
resizer.style.background = 'red';
resizer.style.position = 'absolute';
resizer.style.right = 0;
resizer.style.bottom = 0;
resizer.style.cursor = 'se-resize';
//Append Child to Element
element.appendChild(resizer);
//box function onmousemove
resizer.addEventListener('mousedown', initResize, false);

//Window funtion mousemove & mouseup
function initResize(e) {
   window.addEventListener('mousemove', Resize, false);
   window.addEventListener('mouseup', stopResize, false);
}
//resize the element
function Resize(e) {
   element.style.width = (e.clientX - element.offsetLeft) + 'px';
   element.style.height = (e.clientY - element.offsetTop) + 'px';
}
//on mouseup remove windows functions mousemove & mouseup
function stopResize(e) {
    window.removeEventListener('mousemove', Resize, false);
    window.removeEventListener('mouseup', stopResize, false);
}
18
Lazaro

Voir mon navigateur compatible cross resizer .

    <!doctype html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>resizer</title>
        <meta name="author" content="Andrej Hristoliubov [email protected]">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <script type="text/javascript" src="https://rawgit.com/anhr/resizer/master/Common.js"></script>
        <script type="text/javascript" src="https://rawgit.com/anhr/resizer/master/resizer.js"></script>
        <style>
            .element {
                border: 1px solid #999999;
                border-radius: 4px;
                margin: 5px;
                padding: 5px;
            }
        </style>
        <script type="text/javascript">
            function onresize() {
                var element1 = document.getElementById("element1");
                var element2 = document.getElementById("element2");
                var element3 = document.getElementById("element3");
                var ResizerY = document.getElementById("resizerY");
                ResizerY.style.top = element3.offsetTop - 15 + "px";
                var topElements = document.getElementById("topElements");
                topElements.style.height = ResizerY.offsetTop - 20 + "px";
                var height = topElements.clientHeight - 32;
                if (height < 0)
                    height = 0;
                height += 'px';
                element1.style.height = height;
                element2.style.height = height;
            }
            function resizeX(x) {
                //consoleLog("mousemove(X = " + e.pageX + ")");
                var element2 = document.getElementById("element2");
                element2.style.width =
                    element2.parentElement.clientWidth
                    + document.getElementById('rezizeArea').offsetLeft
                    - x
                    + 'px';
            }
            function resizeY(y) {
                //consoleLog("mousemove(Y = " + e.pageY + ")");
                var element3 = document.getElementById("element3");
                var height =
                    element3.parentElement.clientHeight
                    + document.getElementById('rezizeArea').offsetTop
                    - y
                ;
                //consoleLog("mousemove(Y = " + e.pageY + ") height = " + height + " element3.parentElement.clientHeight = " + element3.parentElement.clientHeight);
                if ((height + 100) > element3.parentElement.clientHeight)
                    return;//Limit of the height of the elemtnt 3
                element3.style.height = height + 'px';
                onresize();
            }
            var emailSubject = "Resizer example error";
        </script>
    </head>
    <body>
        <div id='Message'></div>
        <h1>Resizer</h1>
        <p>Please see example of resizing of the HTML element by mouse dragging.</p>
        <ul>
            <li>Drag the red rectangle if you want to change the width of the Element 1 and Element 2</li>
            <li>Drag the green rectangle if you want to change the height of the Element 1 Element 2 and Element 3</li>
            <li>Drag the small blue square at the left bottom of the Element 2, if you want to resize of the Element 1 Element 2 and Element 3</li>
        </ul>
        <div id="rezizeArea" style="width:1000px; height:250px; overflow:auto; position: relative;" class="element">
            <div id="topElements" class="element" style="overflow:auto; position:absolute; left: 0; top: 0; right:0;">
                <div id="element2" class="element" style="width: 30%; height:10px; float: right; position: relative;">
                    Element 2
                    <div id="resizerXY" style="width: 10px; height: 10px; background: blue; position:absolute; left: 0; bottom: 0;"></div>
                    <script type="text/javascript">
                        resizerXY("resizerXY", function (e) {
                                resizeX(e.pageX + 10);
                                resizeY(e.pageY + 50);
                            });
                    </script>
                </div>
                <div id="resizerX" style="width: 10px; height:100%; background: red; float: right;"></div>
                <script type="text/javascript">
                    resizerX("resizerX", function (e) {
                        resizeX(e.pageX + 25);
                    });
                </script>
                <div id="element1" class="element" style="height:10px; overflow:auto;">Element 1</div>
            </div>
            <div id="resizerY" style="height:10px; position:absolute; left: 0; right:0; background: green;"></div>
            <script type="text/javascript">
                resizerY("resizerY", function (e) {
                    resizeY(e.pageY + 25);
                });
            </script>
            <div id="element3" class="element" style="height:100px; position:absolute; left: 0; bottom: 0; right:0;">Element 3</div>
        </div>
        <script type="text/javascript">
            onresize();
        </script>
    </body>
    </html>

Voir aussi mon exemple de resizer

10
Andrej

J'ai créé une fonction qui reçoit l'identifiant d'un élément html et ajoute une bordure à son côté droit La fonction est générale et ne reçoit qu'un identifiant afin que vous puissiez le copier tel quel et cela fonctionnera

var myoffset;
function resizeE(elem){
    var borderDiv = document.createElement("div");
    borderDiv.className = "border";
    borderDiv.addEventListener("mousedown",myresize = function myrsize(e) {
	    myoffset = e.clientX - (document.getElementById(elem).offsetLeft + parseInt(window.getComputedStyle(document.getElementById(elem)).getPropertyValue("width")));
	    window.addEventListener("mouseup",mouseUp);
	    document.addEventListener("mousemove",mouseMove = function mousMove(e) {
	   	 document.getElementById(elem).style.width = `${e.clientX -  myoffset - document.getElementById(elem).offsetLeft}px`;
		});
	});
    document.getElementById(elem).appendChild(borderDiv);
}

function mouseUp() {
    document.removeEventListener("mousemove", mouseMove);
    window.removeEventListener("mouseup",mouseUp);
}

function load() 
{
	resizeE("resizeableDiv");
	resizeE("anotherresizeableDiv");
  resizeE("anotherresizeableDiv1");
}
.border {

  position: absolute;
  cursor: e-resize;
  width: 9px;
  right: -5px;
  top: 0;
  height: 100%;
}

#resizeableDiv {
  width: 30vw;
  height: 30vh;
  background-color: #84f4c6;
  position: relative;
}
#anotherresizeableDiv {
  width: 30vw;
  height: 30vh;
  background-color: #9394f4;
  position: relative;
}
#anotherresizeableDiv1 {
  width: 30vw;
  height: 30vh;
  background-color: #43f4f4;
  position: relative;
}
#anotherresizeableDiv1 .border{
  background-color: black;
}
#anotherresizeableDiv .border{
  width: 30px;
  right: -200px;
  background-color: green;
}
<body onload="load()">

  <div id="resizeableDiv">change my size with the east border</div>
  <div id="anotherresizeableDiv1">with visible border</div>
</body>
  <div id="anotherresizeableDiv">with editted outside border</div>
</body>

resizeE("resizeableDiv"); //this calls a function that does the magic to the id inserted
1
coder

Je viens de créer un CodePen qui montre comment cela peut être fait assez facilement avec ES6.

http://codepen.io/travist/pen/GWRBQV

En gros, voici la classe qui fait cela.

let getPropertyValue = function(style, prop) {
  let value = style.getPropertyValue(prop);
  value = value ? value.replace(/[^0-9.]/g, '') : '0';
  return parseFloat(value);
}

let getElementRect = function(element) {
  let style = window.getComputedStyle(element, null);
  return {
    x: getPropertyValue(style, 'left'),
    y: getPropertyValue(style, 'top'),
    width: getPropertyValue(style, 'width'),
    height: getPropertyValue(style, 'height')
  }
}

class Resizer {
    constructor(wrapper, element, options) {
        this.wrapper = wrapper;
        this.element = element;
        this.options = options;
        this.offsetX = 0;
        this.offsetY = 0;
        this.handle = document.createElement('div');
        this.handle.setAttribute('class', 'drag-resize-handlers');
        this.handle.setAttribute('data-direction', 'br');
        this.wrapper.appendChild(this.handle);
        this.wrapper.style.top = this.element.style.top;
        this.wrapper.style.left = this.element.style.left;
        this.wrapper.style.width = this.element.style.width;
        this.wrapper.style.height = this.element.style.height;
        this.element.style.position = 'relative';
        this.element.style.top = 0;
        this.element.style.left = 0;
        this.onResize = this.resizeHandler.bind(this);
        this.onStop = this.stopResize.bind(this);
        this.handle.addEventListener('mousedown', this.initResize.bind(this));
    }

    initResize(event) {
        this.stopResize(event, true);
        this.handle.addEventListener('mousemove', this.onResize);
        this.handle.addEventListener('mouseup', this.onStop);
    }

    resizeHandler(event) {
        this.offsetX = event.clientX - (this.wrapper.offsetLeft + this.handle.offsetLeft);
        this.offsetY = event.clientY - (this.wrapper.offsetTop + this.handle.offsetTop);
        let wrapperRect = getElementRect(this.wrapper);
        let elementRect = getElementRect(this.element);
        this.wrapper.style.width = (wrapperRect.width + this.offsetX) + 'px';
        this.wrapper.style.height = (wrapperRect.height + this.offsetY) + 'px';
        this.element.style.width = (elementRect.width + this.offsetX) + 'px';
        this.element.style.height = (elementRect.height + this.offsetY) + 'px';
    }

    stopResize(event, nocb) {
        this.handle.removeEventListener('mousemove', this.onResize); 
        this.handle.removeEventListener('mouseup', this.onStop);
    }
}

class Dragger {
    constructor(wrapper, element, options) {
        this.wrapper = wrapper;
        this.options = options;
        this.element = element;
        this.element.draggable = true;
        this.element.setAttribute('draggable', true);
        this.element.addEventListener('dragstart', this.dragStart.bind(this));
    }

    dragStart(event) {
        let wrapperRect = getElementRect(this.wrapper);
        var x = wrapperRect.x - parseFloat(event.clientX);
        var y = wrapperRect.y - parseFloat(event.clientY);
        event.dataTransfer.setData("text/plain", this.element.id + ',' + x + ',' + y);
    }

    dragStop(event, prevX, prevY) {
        var posX = parseFloat(event.clientX) + prevX;
        var posY = parseFloat(event.clientY) + prevY;
        this.wrapper.style.left = posX + 'px';
        this.wrapper.style.top = posY + 'px';
    }
}

class DragResize {
    constructor(element, options) {
        options = options || {};
        this.wrapper = document.createElement('div');
        this.wrapper.setAttribute('class', 'tooltip drag-resize');
        if (element.parentNode) {
          element.parentNode.insertBefore(this.wrapper, element);
        }
        this.wrapper.appendChild(element);
        element.resizer = new Resizer(this.wrapper, element, options);
        element.dragger = new Dragger(this.wrapper, element, options);
    }
}

document.body.addEventListener('dragover', function (event) {
    event.preventDefault();
    return false;
});

document.body.addEventListener('drop', function (event) {
    event.preventDefault();
    var dropData = event.dataTransfer.getData("text/plain").split(',');
    var element = document.getElementById(dropData[0]);
    element.dragger.dragStop(event, parseFloat(dropData[1]), parseFloat(dropData[2]));
    return false;
});
1
Travis Tidwell