TinyMCE ограничить текст на scrollerActived - PullRequest
1 голос
/ 08 июля 2011

В моем приложении 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-код, а не фактический текст. Таким образом, очень неявно сказать, что представляет собой фактический текст без разметки (что в нашем случае требуется при обрезании переполненного текста).

Мои вопросы:

  1. Есть ли способ получить scrollHeight и offsetHeight элемента управления, созданного tinyMCE?

  2. Есть ли способ получить единственную текстовую версию (без разметки) внутреннего содержимого элемента управления tinyMCE? (Таким образом, когда я обрезаю текст в функции check_limits, это не влияет на / не нарушает разметку / DOM, созданную tinyMCE для форматированного текста. Другими словами, я бы имитировал действие пользователя, нажимая клавишу backspace на элементе управления tinyMCE цикл while.)

  3. Элегантный способ выполнить все это упражнение с и без tinyMCE?

Любые предложения приветствуются!

1 Ответ

0 голосов
/ 08 июля 2011

Во-первых, вы должны знать, что tinymce создает приемлемый iframe, чтобы позволить пользователям редактировать html-содержимое;содержимое этого iframe записывается обратно в текстовое поле onSave.Текстовая область скрывается в процессе инициализации rtinymce.Идентификатор редактора равен идентификатору текстовой области.

Вот некоторые предложения:

1.Соответствующий код

var frameid = editor.id+'_ifr';
var currentiframe = document.getElementById(frameid);
var offsetHeight = currentiframe .contentDocument.body.offsetHeight;
var scrollHeight = currentfr.Document.body.scrollHeight

2.код для этого (с использованием jQuery)

var plain_text = $(editor.getBody()).text();

3. Единственный, более эффективный способ обработки цикла while в случае "без крошечных" - это отрезать некоторыебольше символов и следуйте логарифмическому подходу.Вы отсекаете большую часть строки и затем добираетесь до окончательного значения в полусегментах.Пример: у вас есть 20 символов, но это подходит.Затем вы отсекаете 10 символов исходной строки.Если он вам не подходит, попробуйте 15 символов и так далее ... это более эффективно, чем подход "время", но сложнее в разработке.

РЕДАКТИРОВАТЬ:

Кажется, почти невозможно получитьномер строки из позиции каретки.Проблема здесь в том, что вы не знаете, где разрывается текстовая строка.Хотя легко определить, в каком абзаце находится курсор (tinymce использует абзацы для переноса текстовых узлов).

Существует способ ограничить вставку в tinymce на основе символов (т. Е. Limit можно установить100 символов), но я думаю, это не сработает для вашего случая использования, если вы не используете моноширинный шрифт.

Другой подход может состоять в том, чтобы установить для tinymce css значение окна редактора, равное ширине вашего окнаflex box (достаточно установить элемент widht для элемента тела iframes).В этом случае было бы проще использовать подход scrollHeigth - вам нужно будет только выяснить, изменилась ли высота после вставки текста, а затем вы могли бы разделить высоту на lineheigth, чтобы вывести номер строки.Я предлагаю вам написать собственный плагин для реализации этого.Это не так сложно.Вот ссылка на учебник для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...