Цитата:
|
******* по сабжу ******
Правильное (логичное) решение - через CSS: нужно (как-то) заставить <INPUT> вести себя как <SPAN> Свойство display=inline у обоих. Нужно что-то ещё. Или это невозможно задать параметрически для <INPUT>? |
Текстовое поле является замещаемым элементом, размеры которого определяются внутри элемента. Следовательно размер элемента представляющего содержимое замещаемых элементов может иметь определённые ширину, высоту или соотношение сторон, если только не заданы конкретные размеры.
Давайте попробуем создать текстовое поле, которое занимало бы ширину равную ширине введённого текста... <input value="London" placeholder="City"> <style> input { /* Для начала сбросим все стили */ all: unset; /* Затем применим стили, чтобы увидеть какого размера теперь поле */ border-bottom: 0.125em dashed deeppink; background-color: lightpink; padding: 0.5em; font: 2em Georgia, serif; display: inline-block; min-width: 1em; /* Обратите внимание, как применилось */ max-width: 10em; } </style> Каким бы не был текст, ширина упорно не меняется, по причине указанной выше. Из-за этого min-width и max-width остаются по сути не применёнными. Но давайте попробуем эмулировать текстовое поле, используя атрибут contenteditable. <span contenteditable placeholder="City">London</span> <style> span[contenteditable] { /* Затем применим стили, чтобы увидеть какого размера теперь поле */ border-bottom: 0.125em dashed deeppink; background-color: lightpink; padding: 0.5em; font: 2em Georgia, serif; display: inline-block; min-width: 1em; /* Обратите внимание, как применилось */ max-width: 10em; /* стили специально для contenteditable */ white-space: nowrap; overflow: hidden; cursor: text; } /* Браузеры для имитаций перевода строки используют div, p или br */ /* Также могут применять инлайн-стили, для вставленных элементов */ span[contenteditable] * { white-space: nowrap !important; font: unset !important; display: inline; } span[contenteditable] br { display: none; } /* Имитируем placeholder */ span[contenteditable]:empty::before { content: attr(placeholder); opacity: 0.5; } </style> Теперь наше текстовое поле меняет размеры, как оно должно быть на самом деле Правда здесь проблемы: - Браузер вставляет элементы - В поле можно перетащить изображения и другие элементы - Это не элемент формы (нужно будет получить значение через textContent) Плюсы: + Если предположить, что пользователь будет вводить или вставлять только текст, то ОК + Применяются min-width и max-width, т. е. ведёт себя не странно + textContent возвращает только текст + работает placeholder, доступен через клавиатуру В черновике спецификаций работа над которой была прекращена, определялось свойство user-modify, которое позволяет редактировать содержимое элемента, если указано значение read-write. (https://www.w3.org/TR/2000/WD-css3-u...16#user-modify) В принципе редактирование элемента может быть задано через стили. По сути... Код:
[contenteditable] { <span contenteditable placeholder="City">London</span> <style> span[contenteditable] { /* Затем применим стили, чтобы увидеть какого размера теперь поле */ border-bottom: 0.125em dashed deeppink; background-color: lightpink; padding: 0.5em; font: 2em Georgia, serif; display: inline-grid; display: inline-flex; min-width: 1em; /* Обратите внимание, как применилось */ max-width: 10em; /* стили специально для contenteditable */ -webkit-user-modify: read-write-plaintext-only; cursor: text; } /* Имитируем placeholder */ span[contenteditable]:empty::before { content: attr(placeholder); opacity: 0.5; } </style> Это всё не работает как элемент формы, но можно взять элемент формы и сделать программно вокруг него обёртку, которая позволяла бы отслеживать его размеры (при помощи стилей, обёртка скриптом). <input value="London" placeholder="City"> <style> input, x-input { /* Затем применим стили, чтобы увидеть какого размера теперь поле */ border-bottom: 0.125em dashed deeppink; background-color: lightpink; padding: 0.5em; font: 2em Georgia, serif; display: inline-block; min-width: 1em; /* Обратите внимание, как применилось */ max-width: 10em; } </style> <script> for(let element of document.querySelectorAll("input")) { let host = document.createElement("x-input") let parent = host.attachShadow({ mode: "open" }); let style = document.createElement("style"); let input = element.cloneNode(true); input.placeholder = element.getAttribute("placeholder"); let field = document.createElement("span"); style.textContent = ` :host { position: relative; overflow: hidden; } input { all: inherit; margin: 0; border: 0; top: 0; left: 0; right: 0; bottom: 0; width: 100%; height: 100%; opacity: 1; position: absolute; box-sizing: border-box; max-width: initial; max-height: initial; min-width: initial; min-height: initial; } span { visibility: hidden; } `; element.parentNode.insertBefore(host, element.nextSibling); parent.appendChild(style); parent.appendChild(input); parent.appendChild(field); let inputHandler = () => { field.textContent = (input.value || input.placeholder).replace(/\s/g, "\xa0"); element.value = input.value; }; input.addEventListener("input", inputHandler); inputHandler(); element.type = "hidden"; } </script> И ещё один способ, от Ли Веру. Тоже отслеживает размеры (при помощи скрипта). <input value="London" placeholder="City"> <style> input { all: unset; /* Затем применим стили, чтобы увидеть какого размера теперь поле */ border-bottom: 0.125em dashed deeppink; background-color: lightpink; padding: 0.5em; display: inline-block; font: 2em Georgia, serif; min-width: 1em; /* Обратите внимание, как применилось */ max-width: 10em; } </style> <script src="https://leaverou.github.io/stretchy/stretchy.js"></script> Кто знает, как ещё проще? Определение замещаемого элемента(https://www.w3.org/TR/CSS21/conform.html, https://www.w3.org/TR/2014/REC-html5...laced-elements) |
Цитата:
Свойства стиля в <span> и <input> должны полностью совпадать (некоторые браузеры не наследуют в input font-family по inherit). <html> <style> .inp {font-family:calibri,arial,sans-serif; font-size:1em; padding:.2px; background-color:#DDDDFF; border:1px solid #F00; min-width:1em} </style> <body> <script> function rsz() { setTimeout(function(){ var inp = document.getElementById('inp1'); var spa = document.getElementById('inp1copy'); ///spa.innerText = inp.value; // так не учитывает пробелы spa.innerText = inp.value.replace(/\s/ig, String.fromCharCode(160)); inp.style.width=spa.offsetWidth + 20; // 20px чтобы инпут не дергался при вводе нового символа },0); }; </script> <input id="inp1" class="inp" style="width:10px" type="input" value="" onkeydown="rsz()" onpaste="rsz()" oncut="rsz()"> <span id="inp1copy" class="inp" style="position:absolute; left:-30000px; top:0px"> </span> </body> </html> |
Цитата:
|
Цитата:
собственно, для понимания идеи это не важно. хотя Ваше замечание об аккуратности оформления кода учту |
Цитата:
|
Цитата:
|
Я не о ядрах процессора говорю, а о том, что разбор будет производится с лишними операциями, а зачем? Можно ссылаться на то, что выросли возможности процессоров, но зачем же лишнее делать. Все лишнее зря кушает энергию, которая для моб. устройств является чувствительной. :)
|
Часовой пояс GMT +3, время: 10:07. |