Me preguntaba cómo podemos hacer que un elemento HTML <div>
o <p>
un elemento de etiqueta cambie de tamaño cuando se hace clic en JavaScript puro, no en la biblioteca jQuery ni en ninguna otra biblioteca.
javascript
html
css
dom-events
monje
fuente
fuente
Respuestas:
Realmente recomiendo usar algún tipo de biblioteca, pero lo solicitaste, lo obtienes:
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); }
Manifestación
Recuerde que es posible que esto no se ejecute en todos los navegadores (probado solo en Firefox, definitivamente no funciona en IE <9).
fuente
¿qué pasa con una solución css3 pura?
div { resize: both; overflow: auto; }
Documentos web de MDN
Ejemplo de W3Schools
Soporte de navegador
fuente
resize
navegadores CSS Webkit no le permitirá cambiar el tamaño de un elemento para hacerlo más pequeño, solo más grande (en ambas dimensiones).Es simple:
Ejemplo: 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); }
fuente
Vea mi cambio de tamaño compatible con varios navegadores .
<!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>
También vea mi ejemplo de resizer
fuente
Acabo de crear un CodePen que muestra cómo se puede hacer esto con bastante facilidad usando ES6.
http://codepen.io/travist/pen/GWRBQV
Básicamente, aquí está la clase que hace esto.
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; });
fuente
He creado una función que recibe una identificación de un elemento html y agrega un borde en el lado derecho, la función es general y solo recibe una identificación para que pueda copiarla tal como está y funcionará
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
fuente
solo usando el
mousemove
evento en vainilla jspasos
agrega el
mousemove
a tu objetivoescuchar el
move
evento objetivoobtener la posición del puntero, cambiar el tamaño de su objetivo
codigos
const div = document.querySelector(`div.before`); const box = document.querySelector(`div.container`); box.addEventListener(`mousemove`, (e) => { const { offsetX, offsetY, } = e; div.style.width = offsetX + `px`; });
demo en vivo
https://codepen.io/xgqfrms/full/wvMQqZL
refs
https://developer.mozilla.org/en-US/docs/Web/API/Element/mousemove_event
https://medium.com/the-z/making-a-resizable-div-in-js-is-not-easy-as-you-think-bda19a1bc53d
fuente
Aquí hay muy buenos ejemplos para empezar a probar, pero todos se basan en añadir algún elemento extra o externo como un "div" como elemento de referencia para arrastrarlo, y calcular las nuevas dimensiones o posición del elemento original.
Aquí tienes un ejemplo que no usa elementos adicionales. Podríamos agregar bordes, relleno o margen sin afectar su funcionamiento. En este ejemplo no hemos agregado color, ni ninguna referencia visual a los bordes ni a la esquina inferior derecha como una pista donde se puede ampliar o reducir las dimensiones, pero usando el cursor alrededor de los elementos redimensionables aparecen las pistas.
let resizerForCenter = new Resizer('center') resizerForCenter.initResizer()
Véalo en acción con CodeSandbox:
En este ejemplo usamos ES6 y un módulo que exporta una clase llamada Resizer. Un ejemplo vale más que mil palabras:
O con el fragmento de código:
Mostrar fragmento de código
const html = document.querySelector('html') class Resizer { constructor(elemId) { this._elem = document.getElementById(elemId) /** * Stored binded context handlers for method passed to eventListeners! * * See: /programming/9720927/removing-event-listeners-as-class-prototype-functions */ this._checkBorderHandler = this._checkBorder.bind(this) this._doResizeHandler = this._doResize.bind(this) this._initResizerHandler = this.initResizer.bind(this) this._onResizeHandler = this._onResize.bind(this) } initResizer() { this.stopResizer() this._beginResizer() } _beginResizer() { this._elem.addEventListener('mousemove', this._checkBorderHandler, false) } stopResizer() { html.style.cursor = 'default' this._elem.style.cursor = 'default' window.removeEventListener('mousemove', this._doResizeHandler, false) window.removeEventListener('mouseup', this._initResizerHandler, false) this._elem.removeEventListener('mousedown', this._onResizeHandler, false) this._elem.removeEventListener('mousemove', this._checkBorderHandler, false) } _doResize(e) { let elem = this._elem let boxSizing = getComputedStyle(elem).boxSizing let borderRight = 0 let borderLeft = 0 let borderTop = 0 let borderBottom = 0 let paddingRight = 0 let paddingLeft = 0 let paddingTop = 0 let paddingBottom = 0 switch (boxSizing) { case 'content-box': paddingRight = parseInt(getComputedStyle(elem).paddingRight) paddingLeft = parseInt(getComputedStyle(elem).paddingLeft) paddingTop = parseInt(getComputedStyle(elem).paddingTop) paddingBottom = parseInt(getComputedStyle(elem).paddingBottom) break case 'border-box': borderRight = parseInt(getComputedStyle(elem).borderRight) borderLeft = parseInt(getComputedStyle(elem).borderLeft) borderTop = parseInt(getComputedStyle(elem).borderTop) borderBottom = parseInt(getComputedStyle(elem).borderBottom) break default: break } let horizontalAdjustment = (paddingRight + paddingLeft) - (borderRight + borderLeft) let verticalAdjustment = (paddingTop + paddingBottom) - (borderTop + borderBottom) let newWidth = elem.clientWidth + e.movementX - horizontalAdjustment + 'px' let newHeight = elem.clientHeight + e.movementY - verticalAdjustment + 'px' let cursorType = getComputedStyle(elem).cursor switch (cursorType) { case 'all-scroll': elem.style.width = newWidth elem.style.height = newHeight break case 'col-resize': elem.style.width = newWidth break case 'row-resize': elem.style.height = newHeight break default: break } } _onResize(e) { // On resizing state! let elem = e.target let newCursorType = undefined let cursorType = getComputedStyle(elem).cursor switch (cursorType) { case 'nwse-resize': newCursorType = 'all-scroll' break case 'ew-resize': newCursorType = 'col-resize' break case 'ns-resize': newCursorType = 'row-resize' break default: break } html.style.cursor = newCursorType // Avoid cursor's flickering elem.style.cursor = newCursorType // Remove what is not necessary, and could have side effects! elem.removeEventListener('mousemove', this._checkBorderHandler, false); // Events on resizing state /** * We do not apply the mousemove event on the elem to resize it, but to the window to prevent the mousemove from slippe out of the elem to resize. This work bc we calculate things based on the mouse position */ window.addEventListener('mousemove', this._doResizeHandler, false); window.addEventListener('mouseup', this._initResizerHandler, false); } _checkBorder(e) { const elem = e.target const borderSensitivity = 5 const coor = getCoordenatesCursor(e) const onRightBorder = ((coor.x + borderSensitivity) > elem.scrollWidth) const onBottomBorder = ((coor.y + borderSensitivity) > elem.scrollHeight) const onBottomRightCorner = (onRightBorder && onBottomBorder) if (onBottomRightCorner) { elem.style.cursor = 'nwse-resize' } else if (onRightBorder) { elem.style.cursor = 'ew-resize' } else if (onBottomBorder) { elem.style.cursor = 'ns-resize' } else { elem.style.cursor = 'auto' } if (onRightBorder || onBottomBorder) { elem.addEventListener('mousedown', this._onResizeHandler, false) } else { elem.removeEventListener('mousedown', this._onResizeHandler, false) } } } function getCoordenatesCursor(e) { let elem = e.target; // Get the Viewport-relative coordinates of cursor. let viewportX = e.clientX let viewportY = e.clientY // Viewport-relative position of the target element. let elemRectangle = elem.getBoundingClientRect() // The function returns the largest integer less than or equal to a given number. let x = Math.floor(viewportX - elemRectangle.left) // - elem.scrollWidth let y = Math.floor(viewportY - elemRectangle.top) // - elem.scrollHeight return {x, y} } let resizerForCenter = new Resizer('center') resizerForCenter.initResizer() let resizerForLeft = new Resizer('left') resizerForLeft.initResizer() setTimeout(handler, 10000, true); // 10s function handler() { resizerForCenter.stopResizer() }
body { background-color: white; } #wrapper div { /* box-sizing: border-box; */ position: relative; float:left; overflow: hidden; height: 50px; width: 50px; padding: 3px; } #left { background-color: blueviolet; } #center { background-color:lawngreen ; } #right { background: blueviolet; } #wrapper { border: 5px solid hotpink; display: inline-block; }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Resizer v0.0.1</title> </head> <body> <div id="wrapper"> <div id="left">Left</div> <div id="center">Center</div> <div id="right">Right</div> </div> </body> </html>
fuente
var resizeHandle = document.getElementById('resizable'); var box = document.getElementById('resize'); resizeHandle.addEventListener('mousedown', initialiseResize, false); function initialiseResize(e) { window.addEventListener('mousemove', startResizing, false); window.addEventListener('mouseup', stopResizing, false); } function stopResizing(e) { window.removeEventListener('mousemove', startResizing, false); window.removeEventListener('mouseup', stopResizing, false); } function startResizing(e) { box.style.width = (e.clientX) + 'px'; box.style.height = (e.clientY) + 'px'; } function startResizing(e) { box.style.width = (e.clientX - box.offsetLeft) + 'px'; box.style.height = (e.clientY - box.offsetTop) + 'px'; }
#resize { position: relative; width: 130px; height: 130px; border: 2px solid blue; color: white; } #resizable { background-color: white; width: 10px; height: 10px; cursor: se-resize; position: absolute; right: 0; bottom: 0; }
<div id="resize"> <div id="resizable"> </div>
fuente