2012-03-30 37 views
1

我希望能夠在textarea中選擇一些文本,然後用SpanElement替換選定的文本。我不能使用TextLayoutFormat,因爲它沒有「id」屬性。如何在TextFlow中插入SpanElement?

如何在textarea的特定位置插入跨度?

+0

HTTP://www.coursesweb。 net/actionscript/add-text-actionscript – 2012-04-02 18:55:10

回答

4

有幾種方法可以做到這一點。根據開始文本的結構,您可以使用簡單的方法來替換文本,也可以使用更通用的方法來處理多種情況。

兩個想法,一個簡單,一個接近通用解決方案。 會好奇,想看看其他的方法,我一直在學習TLF新的東西:)

導出TLF文本字符串,做你的更換,重新導入字符串到一個新的TLF的TextFlow。

  1. 從星火 TextArea的textFlow財產獲得textFlow /的TextInput
  2. 使用TextFlow.getText(0,-1, 「< BR/>」)來獲得字符串表示
  3. 待辦事項替換重新導入流程:查看TextFlowUtil.importFromString
  4. 將上述步驟中的文本流程應用回TextInput或TextArea的 textFlow屬性。

這種方法可能不是最有效的。請注意,您也可能會丟失應用於文本的所有樣式。看看TextConverter類,您也可以使用它將文本導入到帶有文本格式的TLF中。特別是TextConvert.importToFlow()。

使用TextFlow API來獲取包含文本的FlowElement。

刪除包含要替換的原始文本的元素,追加替換文本,追加結尾文本。比上述效率更高。請注意,如果你知道你的文字的確切結構,你可以讓這個更簡單...

[編輯]

下面是兩者兼具的例子:

<?xml version="1.0" encoding="utf-8"?> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
       xmlns:s="library://ns.adobe.com/flex/spark" 
       xmlns:mx="library://ns.adobe.com/flex/mx" 
       width="800" height="600" xmlns:local="*"> 

    <fx:Script> 
     <![CDATA[ 
      import flashx.textLayout.edit.ISelectionManager; 
      import flashx.textLayout.elements.FlowElement; 
      import flashx.textLayout.elements.TextFlow; 

      import spark.utils.TextFlowUtil; 

      private var flow:TextFlow; 
      private var mgr:ISelectionManager; 
      private var startIndex:int; 
      private var endIndex:int; 

      private function init():void 
      { 
       flow = texty.textFlow; 
       mgr = flow.interactionManager; 
       if (mgr.hasSelection()) 
       { 
        // determine start/end indexes of the selection 
        if (mgr.anchorPosition < mgr.activePosition) 
        { 
         startIndex = mgr.anchorPosition; 
         endIndex = mgr.activePosition; 
        } 
        else 
        { 
         startIndex = mgr.activePosition; 
         endIndex = mgr.anchorPosition; 
        } 
       } 
       else 
       { 
        startIndex = 0; 
        endIndex = 0; 
       } 
      } 

      private function replaceByImportText():void 
      { 
       init(); 
       if (mgr.hasSelection()) 
       { 
        var copy:String = flow.getText(0,-1,"<br/>"); 
        // replace the text 
        copy = copy.substring(0,startIndex) + "*** You just replaced me ***" + copy.substring(endIndex); 
        // reimport - expensive (makes a new TextFlow) and probably looses some fidelity (styles, etc) 
        texty.textFlow = TextFlowUtil.importFromString(copy); 
       } 
      } 

      private function replaceBySplittingFlowElements():void 
      { 
       init(); 
       if (mgr.hasSelection()) 
       { 
        // each call to splitAtPosition leaves the text before startIndex in the original FlowElement 
        // and returns a new FlowElement (TextFlow's in this case) w/the remaining text 
        var textToBeReplaced:FlowElement = flow.splitAtPosition(startIndex); 
        // chops out whatever was between start/end indexes 
        var remainingTextToAddBack:TextFlow = textToBeReplaced.splitAtPosition(endIndex - startIndex) as TextFlow; 
        // insert replacment text 
        var span:SpanElement = new SpanElement(); 
        span.text = "Hi, I'm a replacement String."; 
        // assumes last element is a paragraph but it could be a div :) 
        var lastParagraph:ParagraphElement = flow.getChildAt(flow.numChildren -1) as ParagraphElement; 
        if (lastParagraph) 
        { 
         lastParagraph.addChild(span); 
         // merge the last paragraph w/the 1st paragraph of remaining text 
         var firstP:ParagraphElement = remainingTextToAddBack.getChildAt(0) as ParagraphElement; 
         if (firstP) 
         { 
          lastParagraph.replaceChildren(lastParagraph.numChildren, lastParagraph.numChildren, getParagraphChildren(firstP)); 
         } 

        } 

       } 
      } 

      private function getParagraphChildren(p:ParagraphElement):Array 
      { 
       var kids:Array =[]; 
       var numKids:int = p.numChildren; 
       for (var i:int = 0; i<numKids; i++) 
       { 
        kids.push(p.getChildAt(i)); 
       } 
       return kids; 
      } 

     ]]> 
    </fx:Script> 

    <fx:Declarations> 
     <!-- Place non-visual elements (e.g., services, value objects) here --> 
    </fx:Declarations> 

    <s:HGroup> 
     <s:Button label="Replace by importing text" click="replaceByImportText()" /> 
     <s:Button label="Replace by using FlowElements" click="replaceBySplittingFlowElements()"/> 
    </s:HGroup> 


    <s:TextArea id="texty" top="40" left="40" right="40" bottom="40"> 
     <s:p> 
      <s:span> 
       <s:text> 
        Bacon ipsum dolor sit amet turducken pancetta short ribs tail anim pig. 
        In pastrami in, ball tip flank shankle beef ribs spare ribs deserunt pancetta esse cupidatat aliquip venison pork chop. 
        Pork loin commodo corned beef ullamco culpa dolore occaecat, capicola adipisicing ribeye bresaola sunt est. 
        Commodo labore culpa ut, sausage ad meatloaf adipisicing. 
       </s:text> 
      </s:span> 
      <s:br/> 
     </s:p> 

     <s:p> 
      <s:span> 
       <s:text> 
        Quis qui aliqua enim, rump jerky aute bresaola aliquip pig speck short loin. 
        Non ea eiusmod shoulder, consequat enim ribeye sed. Meatloaf tenderloin pork loin reprehenderit. 
        Enim rump eiusmod, tri-tip capicola in do frankfurter dolore. 
        Culpa elit meatball pariatur turducken, leberkas excepteur irure in pork belly shank consequat. 
        Sint biltong t-bone veniam shankle. Consectetur irure et minim. 
       </s:text> 
      </s:span> 
      <s:br/> 
     </s:p> 

     <s:p> 
      <s:span> 
       <s:text> 
        Excepteur laborum non corned beef, est dolore pastrami jowl id. 
        Leberkas short ribs ham, tempor id sed esse. Officia eiusmod pork frankfurter leberkas cow, nisi qui filet mignon mollit swine bacon veniam. 
        Nostrud deserunt nulla ground round, shankle sausage aliqua ut frankfurter culpa. 
        Veniam hamburger spare ribs, ullamco dolor labore salami capicola short loin swine. 
       </s:text> 
      </s:span> 
     </s:p> 

    </s:TextArea> 
</s:Application> 
+0

謝謝你,這正是我所需要的。這麼簡單,但我不知道它 – William 2012-04-05 16:02:32

+0

@Sunil如果我的父母是div和孩子是paragrah和跨度如何實現這一點 – Librak 2012-04-22 09:26:02

3

我想貢獻一些代碼,因爲我從這裏創建了我的代碼,也因爲幾乎沒有關於「splitAtPosition」方法的示例或文檔。

這個代碼在插入一個文本流(文本流)的任何位置(指數)針對FlowElement(的FlowElement) - 記得運行函數後運行textflow.flowComposer.updateAllControllers();

private function insertFlowElementInTextFlowAt(textflow:TextFlow,index:int,flowElement:FlowElement):void{ 

    var part2:TextFlow = textflow.splitAtPosition(index) as TextFlow; 
    var part2_firstPara:ParagraphElement = part2.getChildAt(0) as ParagraphElement;  
    var textflow_lastPara:ParagraphElement = textflow.getChildAt(textflow.numChildren -1) as ParagraphElement; 



    if (textflow.textLength == index){ 

     part2_firstPara.addChildAt(0,flowElement); 
     textflow.replaceChildren(textflow.numChildren,textflow.numChildren,getFlowElementChildren(part2,0)) 

    }else if(index < textflow.textLength){ 

     textflow_lastPara.addChild(flowElement); 
     textflow_lastPara.replaceChildren(textflow_lastPara.numChildren, textflow_lastPara.numChildren, getFlowElementChildren(part2_firstPara)); 
     textflow.replaceChildren(textflow.numChildren,textflow.numChildren,getFlowElementChildren(part2,1)) 

    } 



} 

private function getFlowElementChildren(p:FlowGroupElement,start:int=0):Array 
{ 
    var kids:Array = new Array(); 
    for (var i:int = start; i<p.numChildren; i++){ 
     kids.push(p.getChildAt(i)); 
    } 
    return kids; 
} 
相關問題