В моем приложении rails есть текстовая область для сбора контента от пользователя в базе данных. Приложение rails далее передает этот текст в гибкое приложение на основе XML.
Приложение flex имеет количество контейнеров фиксированного размера, которое оборачивает текст внутри (из XML, созданного приложением Rails на лету), но усекает текст, если он превышает высоту контейнера. Проблема есть; Невозможно представить большой текст в XML, поэтому он автоматически настраивается в скомпилированном приложении Flex. И факт в том, веб-приложение rails и приложение первого уровня полностью отключены с точки зрения осведомленности о своих внутренних событиях. (как и в этом случае; приложение rails не знает о событии переполнения для внутренних контейнеров flex, и полагаться на размер шрифта и количество символов / строк в этом сценарии не работает!)
Поэтому я написал JS-функцию для наблюдения и спасения ситуации переполнения текстовой области и при настройке ее атрибутов (а именно: line-height, font-size, font-family, width, height ... yada yada), совпадающих с гибкий контроль. Сложная форма в рельсах позволила получить динамическое число такого контроля текстовой области, наблюдаемого функцией JS.
Вот код прототипа для обработки события переполнения с соответствующим кодом восстановления для очистки:
var timeout;
document.observe('dom:loaded', attach_obr);
function attach_obr() {
$$('.active_text').each (function(text_element){
text_element.observe('keyup', function(e){
check_limits(text_element.id);
});
text_element.observe('change', function(e){
check_limits(text_element.id);
});
});
}
function check_limits(eyeD) {
if($(eyeD).scrollHeight > $(eyeD).offsetHeight){
// overflow occured, now the rescue code here
timeout = window.setTimeout(function() {
$("error_notice").hide();
}, 4000);
$("error_notice").show().update('There is no space left in this box, please use a new box to continue adding content');
// truncate text till the scrollbar disappears
while($(eyeD).scrollHeight > $(eyeD).offsetHeight){
$(eyeD).value = $(eyeD).value.slice(0, -1);
}
}
else {
if($("error_notice").innerHTML!=""){
$("error_notice").hide().update("");
clearTime(timeout);
}
}
}
[ Примечание: Работает с небольшим недостатком - усечение на несколько символов больше, чем ожидалось в последней строке. Пользователь может перепечатать эти буквы до конца этой строки. Я думаю, это потому, что каким-то образом изменение ширины текстовой области из-за появления 1011 * полосы прокрутки влияет на scrollHeight или offsetHeight во время процесса, и должно быть что-то большее состояние цикла ($(eyeD).scrollHeight > $(eyeD).offsetHeight)
]
Цикл while делает вещи немного медленнее, но, по крайней мере, служит цели. WYSIWYG достигается. (Я хотел бы услышать любое предложение от зрителей, чтобы улучшить этот не элегантный код: O)
WYSIWYG не достигается с точки зрения форматированного / форматированного текста.
Включение Rich Text:
Вместо того, чтобы ожидать от пользователя размещения тегов внутри области, на следующем этапе я планирую развернуть tinyMCE в своем приложении. Теперь, чтобы заставить вышеуказанную функцию работать с tinyMCE, у меня есть следующий код:
tinyMCE.init({
theme_advanced_buttons1 : "bold, italic, underline, strikethrough, separator, justifyleft, justifycenter, justifyright, justifyfull, separator, forecolor, backcolor",
theme:"advanced",
mode:"textareas",
plugins : "safari",
width: '360px',
height: '198px',
setup : function(ed) {
ed.onChange.add(function(ed, i) {
check_limits(ed.id);
});
}
});
Связывание и запуск событий работает нормально. К сожалению, цель контролировать переполнение текста не работает. Причина бытия;
a) ed.id
- это идентификатор моей текстовой области, а не интерактивная панель, созданная tinyMCE. Таким образом, такие атрибуты, как scrollHeight являются offsetHeight, не изменяются для скрытого элемента управления textarea.
b) Значение textarea в этом случае также содержит HTML-код, а не фактический текст. Таким образом, очень неявно сказать, что представляет собой фактический текст без разметки (что в нашем случае требуется при обрезании переполненного текста).
Мои вопросы:
Есть ли способ получить scrollHeight и offsetHeight элемента управления, созданного tinyMCE?
Есть ли способ получить единственную текстовую версию (без разметки) внутреннего содержимого элемента управления tinyMCE?
(Таким образом, когда я обрезаю текст в функции check_limits, это не влияет на / не нарушает разметку / DOM, созданную tinyMCE для форматированного текста. Другими словами, я бы имитировал действие пользователя, нажимая клавишу backspace на элементе управления tinyMCE цикл while.)
Элегантный способ выполнить все это упражнение с и без tinyMCE?
Любые предложения приветствуются!