TinyMCE限制文字在ScrollerActived上 [英] TinyMCE limit text on scrollerActived

查看:182
本文介绍了TinyMCE限制文字在ScrollerActived上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在rails应用程序中有一个textarea来从数据库中的用户收集内容。 Rails应用程序进一步将该文本提供给一个XML驱动的Flex应用程序。

Flex应用程序具有一定数量的固定大小的容器,其中包含文本通过Rails的应用程序),但截断文本,如果它超过了容器的高度。问题在于;没有办法在XML中显示大文本,所以在编译后的flex应用程序中会自动进行调整。事实是,基于Web的Rails应用程序和前端Flex应用程序在了解其内部事件方面完全断开连接。 (就像在这种情况下一样; rails应用程序没有关于flex内部容器的溢出事件的知识,并且在这种情况下依赖字体大小和字符/行数不起作用)。
$ b $因此,我写了一个JS函数来观察和救援textarea的溢出情况,同时设置它的属性(即line-height,font-size,font-family,width,height ... yada yada)的柔性控制。在rails中的复杂形式做了一个动作,让JS函数可以观察到这样的textarea控件的动态数量。

这里是Prototype代码来处理溢出事件清理相应的救援码:

  var timeout; 
document.observe('dom:loaded',attach_obr);

函数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);
});
});


函数check_limits(eyeD){
if($(eyeD).scrollHeight> $(eyeD).offsetHeight){

/ /溢出发生,现在这里的救援代码
timeout = window.setTimeout(function(){
$(error_notice)。hide();
},4000);
$(error_notice)。show()。update('这里没有空格,请用新的方框继续添加内容'); ($(eyeD).scrollHeight> $(eyeD).offsetHeight){
$(eyeD).value = $(

//截取文字直到滚动条消失
) (eyeD).value.slice(0,-1); ($(error_notice)。innerHTML!=){
$(error_notice)。hide(){
}
}
else {
.update( );
clearTime(超时);


$ b code
$ b

[注意: 在最后一行中有一个小于预期的截断字符的小缺陷。用户可以重新键入这些字母,直到该行结束。我想这是因为不知怎的,由于滚动条的外观,textarea的宽度变化影响了处理过程中的scrollHeight或offsetHeight。 ($(eyeD).scrollHeight> $(eyeD).offsetHeight)]



while循环使得事情有点慢,但至少它是为了达到目的。所见即所得。 (我很乐意听到观众提出的改善那些不雅的代码的建议:O)

所见即所得在丰富/格式化文本方面没有实现。

p>

合并富文本:



与用户不同的是,在下一个阶段,我打算在我的应用程序中部署tinyMCE。现在,为了使上述函数与tinyMCE一起工作,我有以下代码:

  tinyMCE.init({
theme_advanced_buttons1:粗体,斜体,下划线,删除线,分隔符,justifyleft,justifycenter,jus jusright,justifyfull,separator,forecolor,backcolor,
主题:advanced,
模式:textareas,
plugins:safari,
width:'360px',
height:'198px',
setup:function(ed){
ed.onChange.add (ed,i){
check_limits(ed.id);
});
}

});

事件的绑定和解除工作正常。不幸的是,控制文本溢出的目的不起作用。原因在于;

ed.id 是我的textarea的id,而不是由tinyMCE创建的交互式面板。所以,像scrollHeight的属性是offsetHeight不会被更改为隐藏的textarea控件。 b)在这种情况下,textarea的值也包含HTML代码,而不是实际的文本。因此,告诉什么是没有标记的实际文本是非常隐含的(在我们的情况下,在截断溢出文本时,这是必需的)。

我的问题:有没有办法让tinyMCE创建的控件的scrollHeight和offsetHeight?

有没有一种方法可以获得tinyMCE控件内部内容的唯一文本版本(无标记)?
(所以,当我截断check_limits函数中的文本时,它不影响/破坏由tinyMCE为格式化文本创建的标记/ DOM。换句话说,我将模拟用户按下退格键在while循环中使用tinyMCE控件。)
  • 使用& amp;没有tinyMCE?



  • 任何建议都非常感谢!



    这里有一些建议:

    相关代码

      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循环的唯一更有效的方法无tinymce的情况下将切掉更多的字符,并遵循对数的方法。你切下一大部分的字符串,然后以半部分的步伐达到最终值。示例:您可以切分20个字符,但它很合适。然后切下原始字符串的10个字符。如果它不适合你尝试15个字符等等...这是更有效的,然后是方法,但更复杂的发展。



    编辑:



    从插入位置获取行号似乎几乎是不可能的。这里的问题是,你不知道文本行在哪里打破。虽然很容易找出光标位于哪个段落(tinymce使用段落来包装文本节点)。

    有一种方法可以限制基于tinymce的插入在字符(即限制可以设置为100个字符),但我猜这不适用于你的用例,除非你使用等宽字体。



    另一种方法可能是设置tinymce CSS来设置编辑器窗口,以确切的宽度作为您的柔性框(设置的widht的iframes正文元素应该是足够的)。在这种情况下,使用scrollHeigth方法会更容易 - 只需要在插入文本之后查明heigth是否发生了变化,然后就可以用lineheigth分隔heigth,例如行号。我建议你写一个自己的插件来实现这一点。这并不困难。这是指向这个教程的链接


    I have a textarea in my rails application to collect content from user in a database. The rails application is further feeding that text to an XML-driven flex application.

    The flex application has number of fixed sized containers which wraps the text inside (from the XML created by Rails app on-the-fly), but truncates the text if it exceeds the container's height. Problem is; there is no way to present the large text in XML, so it gets adjusted automatically in the compiled flex application. And the fact is; the web-based rails app and front-tier flex app are entirely disconnected in terms of having awareness of their internal events. (like in this case; rails app has no knowledge of the overflow event for flex internal containers and relying on font-size and character/line count doesn't work in this scenario!)

    Therefore, I wrote a JS function to watch and rescue the textarea's overflow situation and while setting its attributes (viz; line-height, font-size, font-family, width, height... yada yada) matching that of the flex control. The complex form in rails did the trick to have dynamic number of such textarea's control being observed by the JS function.

    Here is the Prototype code to handle the overflow event with the corresponding rescue code for cleanup:

    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);
            }
        }
    }
    

    [Note: It works with a minor flaw of truncating few more characters than expected in the last line. User can retype these letters till the end of that line. I guess this is because somehow the change in width of textarea due to the appearance of scroll-bar is effecting either the scrollHeight or offsetHeight during the process & there should be something more to the loop's condition ($(eyeD).scrollHeight > $(eyeD).offsetHeight)]

    The while loop makes things bit slower, but at least it is serving the purpose. WYSIWYG is achieved. (I would love to hear any suggestion from the viewers to improve that inelegant code :O )

    WYSIWYG is not achieved, in terms of rich/formatted text..

    Incorporating Rich Text:

    Rather than expecting from user to place tags inside the area , in the next phase, I am planning to deploy tinyMCE in my app. Now, to make the above function work with tinyMCE, I have the following code:

    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);
            });
        }
    
    });
    

    The binding and firing of events is working alright. Unfortunately, the aim to control the text overflow is not working. Reason being;

    a) ed.id is the id of my textarea not the interactive panel created by tinyMCE. So, the attributes like scrollHeight are offsetHeight are not getting changed for the hidden textarea control.

    b) The value of textarea in this case also contains HTML code rather than the actual text. So, it is very implicit to tell what is the actual text without markup (which in our case is required when truncating the overflowed text).

    My questions:

    1. Is there a way to get the scrollHeight and offsetHeight of the control created by tinyMCE?

    2. Is there a way to get the only-text version (without markup) of inner content of tinyMCE control? (So, when I truncate the text in check_limits function, it doesn't effect/breaks the markup/DOM created by tinyMCE for the formatted text. In other words, I would be simulating the user action of pressing backspace on tinyMCE control in the while loop.)

    3. Elegant way to do this whole exercise with & without tinyMCE?

    Any suggestions are greatly appreciated!

    解决方案

    First you need to know that tinymce creates a contenteditable iframe to let users edit html contents; contents from that iframe get written back to the textarea onSave. The textarea gets hidden in the rtinymce intiatilization process. The editor id is equal to the textarea id.

    Here some suggestions:

    1. Relevant code

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

    2. code for this (using jQuery)

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

    3. The only more efficient way to handle the while loop in the "without tinymce" case will be to slice off some more characters and follow a logarithmic approach. You slice off a bigger part of the string and then get to the final value in half-part paces. Example: You slice of 20 characters, but it fits. Then you slice off 10 characters of the original string. If it does not fit you try 15 characters and so on... this is more effectife then the while approach, but more complicated to develop.

    EDIT:

    It seems almost impossible to get the line number from the caret position. Problem here is that you do not know where the a text line breaks. Though it is easy to find out in which paragraph the cursor is located at (tinymce uses paragraphs to wrap text nodes).

    There is a way to limit insertion in tinymce based on characters (i.e. limit can be set to 100 characters), but i guess this won't work for your use case unless you use a monospace font.

    Another approach could be to set the tinymce css to set the editor window to the exact same width as your flex boxes (set the widht to the iframes body element should be sufficient). In this case it sould be easier to use the scrollHeigth approach - you would only need to find out if the heigth did change after insertion of text and then you could divied the heigth with the lineheigth to egt the line number. I suggest you write an own plugin to implement this. This is not that difficult. Here is a link to a tutorial for this.

    这篇关于TinyMCE限制文字在ScrollerActived上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆