Làm thế nào để làm cho phần tử HTML có thể thay đổi kích thước bằng cách sử dụng Javascript thuần?


83

Tôi đã tự hỏi làm cách nào chúng ta có thể làm cho một phần tử HTML như <div>hoặc <p>phần tử thẻ có thể thay đổi kích thước khi được nhấp bằng JavaScript thuần túy, không phải thư viện jQuery hoặc bất kỳ thư viện nào khác.


Ý bạn là gì 'có thể thay đổi kích thước'? Nếu bạn muốn cửa sổ có thể thay đổi kích thước, bạn có thể đặt chiều rộng của phần tử theo%.
Sagar Patil

Sau đây là cách thay đổi kích thước một phần tử div: stackoverflow.com/questions/43411103/...
sfanjoy

Câu trả lời:


110

Tôi thực sự khuyên bạn nên sử dụng một số loại thư viện, nhưng bạn đã yêu cầu nó, bạn nhận được nó:

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);
}

Bản giới thiệu

Hãy nhớ rằng điều này có thể không chạy trong tất cả các trình duyệt (chỉ được thử nghiệm trong Firefox, chắc chắn không hoạt động trong IE <9).


một câu hỏi, giá trị '10' này làm gì trong mã parseInt (document.defaultView.getComputedStyle (p) .width, 10);
nhà sư

1
Tôi đã tìm thấy một lỗi trong tập lệnh, nếu bạn cố gắng làm cho nhiều phần tử thẻ p có thể thay đổi kích thước khi có nhiều hơn một phần tử thẻ p thì mã không hoạt động, có giải pháp nào cho điều đó không?
nhà sư

1
Bạn sẽ không thực sự sử dụng nó trong sản xuất, phải không? Đoạn mã trên rõ ràng là một bản hack nhanh và có một số vấn đề khác. Nó chỉ để hiển thị cách mọi thứ hoạt động ở cấp độ thấp.
user123444555621

4
+1 Tôi biết đó là cấp thấp, nhưng nó rất hữu ích khi bạn không thể sử dụng thư viện của bên thứ ba vì bất kỳ lý do gì. Tôi đã thử nghiệm nó trên Chrome, Firefox, Opera và Safari.
Jan Vorcak

4
Tôi đã sửa lỗi jsfiddle. Điều này sẽ hoạt động và đạt được hiệu quả tương tự. jsfiddle.net/MissoulaLorenzo/gfn6ob3j
Lorenzo Gangi

79

những gì về một giải pháp css3 tinh khiết?

div {
    resize: both;
    overflow: auto;
} 

Tài liệu Web MDN

Ví dụ về W3Schools

Hỗ trợ trình duyệt


3
Thật không may, CSS thay đổi kích thước không được hỗ trợ trong IE
pyanzin

9
Tôi nghĩ điều quan trọng cần đề cập là: Sử dụng resizetrình duyệt Webkit css sẽ không cho phép bạn thay đổi kích thước một phần tử để làm cho nó nhỏ hơn, chỉ lớn hơn (theo cả hai chiều).
Rotareti

5
Tôi đã thử nó trong Chrome 53 và nó hoạt động cho cả thu nhỏ và kéo dài.
DutchKevv

1
Đó là thực sự tốt để biết. Nhưng tôi cần một footer khá lớn có thể thay đổi kích thước về phía trên cùng. Có vẻ như không thể với "thay đổi kích thước".
Martin Meeser

Cảm ơn bạn điều này đã cứu tôi! Tôi cần tạo Iframe có thể thay đổi kích thước và nó hoạt động. Không có gì trong javascript hoạt động cho iframe.
FourCinnamon:

25

Thì đơn giản:

Ví dụ: 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);
}

2
Giải pháp tuyệt vời! Đã thử nghiệm và hoạt động cho Firefox56, Chrome61, Opera48 và IE11.
JCO9

Điều này hoạt động tuyệt vời! Tôi đã tìm kiếm một điểm khởi đầu để giải quyết vấn đề này và điều này đã cho tôi một cái gì đó để làm việc.

15

Xem chéo trình duyệt tương thích của tôi resizer .

    <!doctype html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>resizer</title>
        <meta name="author" content="Andrej Hristoliubov anhr@mail.ru">
        <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>

Cũng xem ví dụ của tôi về resizer


Đáng chú ý là khi tôi thử ví dụ của bạn trong Firefox (trên Linux), việc thay đổi kích thước theo chiều ngang và chiều dọc khiến văn bản nhấp nháy qua lại giữa được chọn và không được chọn.
Andrew

3

Tôi vừa tạo một CodePen cho thấy cách này có thể được thực hiện khá dễ dàng bằng ES6.

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

Về cơ bản, đây là lớp thực hiện điều này.

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;
});

"khá dễ dàng": lol - Ngoài ra, điều này gây ra cho tôi; Có vẻ như nó đang gặp sự cố với việc lựa chọn và bỏ chọn văn bản.
Andrew

2

Tôi đã tạo một hàm nhận id của một phần tử html và thêm đường viền vào phía bên phải của nó, hàm nói chung và chỉ nhận một id để bạn có thể sao chép nó như cũ và nó sẽ hoạt động

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

2

chỉ sử dụng mousemovesự kiện trong vani js

các bước

  1. thêm mousemovemục tiêu của bạn

  2. lắng nghe movesự kiện mục tiêu

  3. lấy vị trí con trỏ, thay đổi kích thước mục tiêu của bạn

mã số

    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`;
    });

bản thử trực tiếp

https://codepen.io/xgqfrms/full/wvMQqZL nhập mô tả hình ảnh ở đây

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


1

Có những ví dụ rất hay ở đây để bắt đầu thử, nhưng tất cả chúng đều dựa trên việc thêm một số phần tử phụ hoặc phần tử bên ngoài như "div" làm phần tử tham chiếu để kéo nó và tính toán kích thước hoặc vị trí mới của phần tử ban đầu.

Đây là một ví dụ không sử dụng bất kỳ phần tử phụ nào. Chúng tôi có thể thêm đường viền, đệm hoặc lề mà không ảnh hưởng đến hoạt động của nó. Trong ví dụ này, chúng tôi đã không thêm màu, cũng không có bất kỳ tham chiếu trực quan nào đến đường viền cũng như góc dưới bên phải như một manh mối nơi bạn có thể phóng to hoặc thu nhỏ kích thước, nhưng bằng cách sử dụng con trỏ xung quanh các phần tử có thể thay đổi kích thước, manh mối sẽ xuất hiện!

let resizerForCenter = new Resizer('center')  
resizerForCenter.initResizer()

Xem nó hoạt động với CodeSandbox:

Trong ví dụ này, chúng tôi sử dụng ES6 và một mô-đun xuất một lớp có tên là Resizer. Một ví dụ đáng giá một nghìn từ:

Chỉnh sửa nhàm chán-snow-qz1sd

Hoặc với đoạn mã:


-2

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>

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.