Як зробити HTML-елемент змінним, використовуючи чистий Javascript?


83

Мені було цікаво, як ми можемо зробити елемент HTML подібним <div>або <p>елементом тегу змінним при натисканні, використовуючи чистий JavaScript, а не бібліотеку jQuery чи будь-яку іншу бібліотеку.


Що ви маєте на увазі "розмір"? Якщо ви хочете змінити розмір вікна, ви можете встановити ширину елемента в%.
Sagar Patil

Ось як я змінити розмір Div елемент: stackoverflow.com/questions/43411103 / ...
sfanjoy

Дуже пов’язане: stackoverflow.com/questions/12194469/…
Ендрю

Відповіді:


110

Я справді рекомендую використовувати якусь бібліотеку, але ви попросили її і отримаєте:

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

Демо

Пам'ятайте, що це може працювати не у всіх браузерах (протестовано лише у Firefox, однозначно не працює в IE <9).


одне питання, що робить це значення '10' у коді parseInt (document.defaultView.getComputedStyle (p) .width, 10);
чернець

1
я знайшов помилку в скрипті, якщо ви намагаєтесь змінити розмір кількох елементів елемента тегу, коли є більше одного елемента тегу p, тоді код не працює, чи є для цього рішення?
чернець

1
Ви насправді не будете використовувати це у виробництві, правда? Наведений вище код, очевидно, є швидким руйнуванням і має кілька інших проблем. Це просто, щоб показати, як все працює на низькому рівні.
user123444555621

4
+1 Я знаю, що це низький рівень, але це дуже корисно, коли ти не можеш користуватися сторонньою бібліотекою з будь-якої причини. Я тестував його на Chrome, Firefox, Opera та Safari.
Ян Ворчак

4
Я виправив jsfiddle. Це має працювати і досягати того ж ефекту. jsfiddle.net/MissoulaLorenzo/gfn6ob3j
Lorenzo Gangi

79

а як щодо чистого рішення css3?

div {
    resize: both;
    overflow: auto;
} 

Веб-документи MDN

Приклад W3Schools

Підтримка браузера


3
На жаль, зміна розміру CSS не підтримується в IE
pyanzin

9
Я вважаю важливим зазначити: використання resizeбраузерів css Webkit не дозволить вам змінити розмір елемента, щоб зробити його меншим, лише більшим (в обох вимірах).
Ротарети

5
Я спробував це в Chrome 53, і він працює як для зменшення, так і для розтягування.
DutchKevv

1
Це справді приємно знати. Але мені потрібен розмір нижнього колонтитула, розмір якого змінюється вгору. Здається, це неможливо за допомогою "змінити розмір".
Мартін Мізер,

Дякую, це мене врятувало! Мені потрібно було змінити розмір Iframe, і він працює. Ніщо у javascript не працює для iframes.
FourCinnamon0

25

Це просто:

Приклад: 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
Чудове рішення! Перевірено та працює для Firefox56, Chrome61, Opera48 та IE11.
JCO9,

Це чудово працює! Я шукав вихідну точку для вирішення цього питання, і це дало мені з чим працювати.

15

Перегляньте мій розмір змінних розмірів, сумісний із браузером .

    <!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>

Також див. Мій приклад зміни розміру


Примітно, що коли я спробую ваш приклад у Firefox (на Linux), горизонтальне та вертикальне змінення розміру змушує текст блимати вперед і назад між виділеним та невиділеним.
Ендрю

3

Я щойно створив CodePen, який показує, як це можна зробити досить легко за допомогою ES6.

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

В основному, ось клас, який це робить.

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

"досить легко": lol - Крім того, це для мене зламано; здається, у нього виникають проблеми з виділенням та скасуванням вибору тексту.
Ендрю

2

Я створив функцію, яка отримує ідентифікатор елемента html і додає межу до її правої сторони, функція є загальною і просто отримує ідентифікатор, щоб ви могли скопіювати його як є, і він буде працювати

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

просто використовуючи mousemoveподію у ванільному js

кроки

  1. додати mousemoveдо своєї цілі

  2. слухати цільову moveподію

  3. отримати позицію вказівника, змінити розмір цілі

коди

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

демо в реальному часі

https://codepen.io/xgqfrms/full/wvMQqZL введіть тут опис зображення

посилання

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

Тут є дуже хороші приклади, з яких слід почати спробу, але всі вони засновані на додаванні якогось додаткового або зовнішнього елемента, такого як "div", як еталонного елемента, щоб перетягнути його, і обчислити нові розміри або положення вихідного елемента.

Ось приклад, в якому не використовуються зайві елементи. Ми могли б додати межі, відступи або поля, не впливаючи на його роботу. У цьому прикладі ми не додали колір, ані жодне візуальне посилання на межі, а також на нижній правий кут як підказку, де можна збільшити або зменшити розміри, але за допомогою курсору навколо змінних елементів з’являються підказки!

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

Перегляньте це в дії з CodeSandbox:

У цьому прикладі ми використовуємо ES6 та модуль, який експортує клас під назвою Resizer. Приклад вартий тисячі слів:

Редагувати boring-snow-qz1sd

Або з фрагментом коду:


-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>

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.