Для моего небольшого вики-приложения мне в основном нужно, чтобы текстовое поле использовалось для редактирования содержимого, чтобы использовать мягкое (или виртуальное) обертывание. Однако в некоторых случаях предпочтительнее не оборачивать контент. Я думал, что сделаю это, просто нажав кнопку, чтобы отключить упаковку. Вот упрощенный код:
<form name = "wikiedit" action = "[[script_name]]" method = "post">
<textarea name = "content" rows = "25" cols = "90" wrap = "virtual">[[content]]</textarea>
<input type = "button" onclick = "document.wikiedit.content.wrap='off';" value = "No Wrap">
<input type = "submit" value = "Save">
</form>
Он работает с IE, но не с Firefox или Opera. Как мне это сделать?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Согласно спецификация HTML 4.01, wrap не является допустимым атрибутом для <textarea>, что объясняет, почему это так сложно и странно. Похоже, что Firefox действительно использует атрибут wrap, но не позволяет вам его изменить.
Но у меня есть решение! Это довольно ужасно, но вот оно. Полностью замените текстовое поле новым.
// this is the onclick handler for your button
document.getElementById("nowrapButton").onclick = function() {
var oldOne = this.form.content; // the old textarea
var newOne = document.createElement('textarea'); // the new textarea
var attrs = ['name', 'rows', 'cols']; // these are the attributes to keep
for (var i = 0; i < attrs.length; ++i) {
// copy the attributes to the new one
newOne.setAttribute(attrs[i], oldOne.getAttribute(attrs[i]));
}
// toggle the wrapping on and off
if (oldOne.getAttribute('wrap') != 'off') {
newOne.setAttribute('wrap', 'off');
}
// copy the text over
newOne.value = oldOne.value;
// add the new one
oldOne.parentNode.insertBefore(newOne, oldOne);
// get rid of the old one
oldOne.parentNode.removeChild(oldOne);
return false;
};
Вот рабочая версия, с которой вы можете поиграть: http://jsbin.com/ugepa
Как обычно, в jQuery было бы намного лучше. :)
См. Ошибку 41464: https://bugzilla.mozilla.org/show_bug.cgi?id=41464
Неприятный обходной путь на данный момент - заменить текстовое поле его клоном:
function setWrap(area, wrap) {
if (area.wrap) {
area.wrap= wrap;
} else { // wrap attribute not supported - try Mozilla workaround
area.setAttribute('wrap', wrap);
var newarea= area.cloneNode(true);
newarea.value= area.value;
area.parentNode.replaceChild(newarea, area);
}
}
Несвязанный: старайтесь избегать доступа к элементам прямо из объекта документа, это ненадежно в некоторых браузерах и вызывает проблемы с конфликтом имен. «Document.forms.wikiedit» лучше, а переход к «id» в форме вместо «name», а затем использование «document.getElementById ('wikiedit')» еще лучше.
form.elements.content также более надежен, чем form.content по тем же причинам ... или, действительно, вы можете дать текстовой области идентификатор и перейти прямо к текстовой области с помощью getElementById, не беспокоясь о просмотре формы.
Вот пример обертывания текстового поля, включая решение CSS:
http://www.web-wise-wizard.com/html-tutorials/html-form-forms-textarea-wrap.html
Они цитируют следующее решение CSS:
white-space: pre; overflow: auto;
Что было бы:
<script type = "text/javascript">
function setNoWrap(textarea) {
textarea.style.whiteSpace = 'pre';
textarea.style.overflow = 'auto';
}
</script>
<form name = "wikiedit" action = "[[script_name]]" method = "post">
<textarea name = "content" rows = "25" cols = "90" wrap = "virtual">[[content]]</textarea>
<input type = "button" onclick = "setNoWrap(this);" value = "No Wrap">
<input type = "submit" value = "Save">
</form>
Хотя это старый пост, но, поскольку я получаю от этого помощь, я также хочу показать более простой метод, который я нашел только что. И я считаю, что это правильнее.
Чтобы заменить .cloneNode (), я думаю, что лучший способ:
child.setAttribute ('обертка', обертка); parent.removeChild (ребенок); parent.appendChild (ребенок);
используя этот способ, вы можете сохранить не только атрибуты самого себя, но и добавленные вами атрибуты, например, дескриптор скрипта или что-то еще.
Попробуйте это расширение jQuery: Textarea Wrap Changer.
Вот вариант Ответ Бобинса, который не требует клонирования текстового поля:
function setWrap(area, wrap) {
if (area.wrap) {
area.wrap = wrap;
} else { // wrap attribute not supported - try Mozilla workaround
area.setAttribute("wrap", wrap);
area.style.overflow = "hidden";
area.style.overflow = "auto";
}
}
Это похоже на комментарий ВК в ошибке, на которую ссылается bobince, но установка отображения вместо переполнения не сработала для меня, если я не поместил второй набор в setTimeout.
Что такое textarea.wrap?