Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #31 (permalink)  
Старый 03.11.2011, 13:43
Аватар для trikadin
Модератор
Отправить личное сообщение для trikadin Посмотреть профиль Найти все сообщения от trikadin
 
Регистрация: 27.04.2010
Сообщений: 3,417

Сообщение от tenshi
трудно забить на тех с кем приходится работать.. особенно на начальника..
А, ну если так, то это, конечно, да... Но я говорил про людей на форуме)
__________________
Читайте:
Ты любопытный) Всё-таки, ничему в этом мире не помешает хорошая доля юмора)
Как спросить, чтобы вам ответили
Часто Задаваемые Вопросы (FAQ)
Ответить с цитированием
  #32 (permalink)  
Старый 07.07.2017, 15:52
Интересующийся
Отправить личное сообщение для boor1 Посмотреть профиль Найти все сообщения от boor1
 
Регистрация: 08.09.2012
Сообщений: 10

******* по сабжу ******

Правильное (логичное) решение - через CSS:
нужно (как-то) заставить <INPUT> вести себя как <SPAN>

Свойство display=inline у обоих.
Нужно что-то ещё.

Или это невозможно задать параметрически для <INPUT>?
Ответить с цитированием
  #33 (permalink)  
Старый 08.07.2017, 23:55
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Текстовое поле является замещаемым элементом, размеры которого определяются внутри элемента. Следовательно размер элемента представляющего содержимое замещаемых элементов может иметь определённые ширину, высоту или соотношение сторон, если только не заданы конкретные размеры.

Давайте попробуем создать текстовое поле, которое занимало бы ширину равную ширине введённого текста...

<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] {
	user-modify: read-write;
}
Именно так оно и работает в некоторых браузерах, например в webkit используется свойство -webkit-user-modify. В webkit используется дополнительное значение read-write-plaintext-only, которое позволяет вставлять текст без оформления.

<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)
Ответить с цитированием
  #34 (permalink)  
Старый 24.07.2017, 18:17
Профессор
Отправить личное сообщение для Маэстро Посмотреть профиль Найти все сообщения от Маэстро
 
Регистрация: 02.07.2010
Сообщений: 642

Сообщение от Malleys Посмотреть сообщение
Кто знает, как ещё проще?
Старая тема (6 лет назад подняли). Но если кому-то нужно поделюсь своим вариантом. Фишка в создании "теневого спана" - копии инпута. Браузер сам вычисляет ширину элемента в зависимости от названия шрифта, его размера и длины текстовой строки. Нам надо её просто взять.
Свойства стиля в <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>
Ответить с цитированием
  #35 (permalink)  
Старый 24.07.2017, 19:01
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от Маэстро
/\s/i
А пробел может иметь верхний и нижний регистры?
Ответить с цитированием
  #36 (permalink)  
Старый 24.07.2017, 19:06
Профессор
Отправить личное сообщение для Маэстро Посмотреть профиль Найти все сообщения от Маэстро
 
Регистрация: 02.07.2010
Сообщений: 642

Сообщение от laimas Посмотреть сообщение
А пробел может иметь верхний и нижний регистры?
ну погорячился.. писал по памяти из проекта двухлетней давности..
собственно, для понимания идеи это не важно. хотя Ваше замечание об аккуратности оформления кода учту
Ответить с цитированием
  #37 (permalink)  
Старый 24.07.2017, 19:23
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Сообщение от Маэстро
замечание об аккуратности
Тут более правильно говорить о нагрузке, так не "учитывать регистр" означает дополнительное действие над символом. Или например, если говорить о более мощном REGEXP, чего нет в JS, но так, к слову, то для нахождения английских символов в юникод строке также не обязательно указывать модификатор u, так как этот набор в строке будет все равно однобайтовым.

Последний раз редактировалось laimas, 24.07.2017 в 20:07.
Ответить с цитированием
  #38 (permalink)  
Старый 24.07.2017, 19:28
Профессор
Отправить личное сообщение для Маэстро Посмотреть профиль Найти все сообщения от Маэстро
 
Регистрация: 02.07.2010
Сообщений: 642

Сообщение от laimas Посмотреть сообщение
Тут более правильно говорить о нагрузке
К нагрузке я тоже всегда отношусь очень щепетильно. Но это не тот случай. После нажатия на клавишу (даже в режиме автоповтора) даже самый слабый процессор успеет сделать замену символа. Речь не идет о 100000 операциях в цикле. 100 ms между нажатиями клавиш ему хватит с головой. Это просто "опечатка", не ведущая ни к каким печальным последствиям, тем более в учебном примере.
Ответить с цитированием
  #39 (permalink)  
Старый 24.07.2017, 19:38
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

Я не о ядрах процессора говорю, а о том, что разбор будет производится с лишними операциями, а зачем? Можно ссылаться на то, что выросли возможности процессоров, но зачем же лишнее делать. Все лишнее зря кушает энергию, которая для моб. устройств является чувствительной.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Динамическое изменение содержимого фрейма VetalStar Элементы интерфейса 3 21.12.2010 23:14
Частичное изменение содержимого элемента kuhok Events/DOM/Window 28 07.09.2009 22:44
Изменение размера блока реклама в зависимости от разрешения экрана. toxiz77 Общие вопросы Javascript 3 11.02.2009 14:12
Динамическое изменение <input text> baal1988 Events/DOM/Window 4 24.08.2008 17:17
Динамическое изменение размеров изображения Макс Элементы интерфейса 7 21.07.2008 16:55