2012-07-19 83 views
2

所以我使用的是使用setData預填充CKEDITOR內容與區域的一些信息是要在一起什麼用戶輸入發送:在「mesageTemplate1」的內容設置爲我申請了一些CKEDITOR內容區域之前如何在事件或手動啓動CKeditor插件?

CKEDITOR.on('instanceReady', function(ev) { 

      CKEDITOR.instances.ckeditor99.setData(messageTemplate1, function() { 

      this.checkDirty(); // true 

      }); 
}); 

JavaScript來清除它。在此之後,我再次使用JS刪除包含我剛剛插入CKeditor內容區域的信息的div。刪除後,我想laucn一個自定義的CKeditor插件來處理CKeditor中的內容。這個插件在使用div移除後很重要,因爲插件的目標是ID,並且如果兩個div都存在(頁面和ckeditor中的某處),插件將針對不在CKeditor內容區域的插件,在CK區域不變。

這是插件(它阻止編輯某些內容的地區)我從堆棧中的一員了,我以前question

/* 
    Plugin that prevents editing of elements with the "non-editable" class as well as elements outside of blocks with "editable" class. 
*/ 

//* ************************** NOTES *************************** NOTES **************************** 
/* 
    The "lastSelectedElement" variable is used to store the last element selected. 

    This plugin uses the "elementspath" plugin which shows all elements in the DOM 
    parent tree relative to the current selection in the editing area. 

    When the selection changes, "elementsPathUpdate" is fired, 
    we key on this and loop through the elements in the tree checking the classes assigned to each element. 

    Three outcomes are possible. 

    1) The non-editable class is found: 
    Looping stops, the current action is cancelled and the cursor is moved to the previous selection. 
    The "selectionChange" hook is fired to set the reverted selection throughout the instance. 

    2) The editable class is found during looping, the "in_editable_area" flag is set to true. 

    3) Neither the editable or the non-editable classes are found (user clicked outside your main container). 
    The "in_editable_area" flag remains set to false. 

    If the "in_editable_area" flag is false, the current action is cancelled and the cursor is moved to the previous location. 
    The "selectionChange" hook is fired to set the reverted selection throughout the instance. 

    If the "in_editable_area" flag is true, 
    the "lastSelectedElement" is updated to the currently selected element and the plugin returns true. 

--------------- 
    If you don't want the elements path to be displayed at the bottom of the editor window, 
    you can hide it with CSS rather than disabling the "elementspath" plugin. 

    The elementspath plugin creates and is left active because we are keying on changes to the path in our plugin. 
    #cke_path_content 
    { 
    visibility: hidden !important; 
    } 

--------------- 
    CSS Classes and ID that the plugin keys on. Use defaults or update variables to use your preferred classes and ID: 

    var starting_element_id = ID of known editable element that always occurs in the instance. 
    Don't use elements like <table>, <tr>, <br /> that don't contain HTML text. 
    Default value = cwjdsjcs_editable_id 

    var editable_class = class of editable containers. 
    Should be applied to all top level elements that contain editable elements. 
    Default = cwjdsjcs_editable 

    var non_editable_class = class of non-editable elements within editable containers 
    Apply to elements where all child elements are non-editable. 
    Default = cwjdsjcs_not_editable 

*/ 

//* ************************** END NOTES *************************** END NOTES **************************** 


// Register the plugin with the editor. 
// http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.plugins.html 




CKEDITOR.plugins.add('cwjdsjcsconfineselection', 
{ 

    requires : [ 'elementspath' ], 

    // The plugin initialization logic goes inside this method. 
    // http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.pluginDefinition.html#init 
    init: function(editor) 
    { 
    editor.on('instanceReady', function(instance_ready_data) 
    { 

     // Create variable that will hold the last allowed selection (for use when a non-editable selection is made) 
     var lastSelectedElement; 
     editor.cwjdsjcs_just_updated = false; 

     // This section starts things off right by selecting a known editable element. 
     // *** Enter the ID of the element that should have initial focus *** IMPORTANT *** IMPORTANT *** 
     var starting_element_id = "cwjdsjcs_editable_id"; 

     var resInitialRange = new CKEDITOR.dom.range(editor.document); 

     resInitialRange.selectNodeContents(editor.document.getById(starting_element_id)); 
     resInitialRange.collapse(); 

     var selectionObject = new CKEDITOR.dom.selection(editor.document); 

     editor.document.focus(); 
     selectionObject.selectRanges([ resInitialRange ]); 

     var sel = editor.getSelection(); 
     var firstElement = sel.getStartElement(); 
     var currentPath = new CKEDITOR.dom.elementPath(firstElement); 

     // Set path for known editable element, fire "selectionChange" hook to update selection throughout instance. 
     editor._.selectionPreviousPath = currentPath; 
     editor.fire('selectionChange', { selection : sel, path : currentPath, element : firstElement }); 
    }); // *** END - editor.on('instanceReady', function(e) 


    // When a new element is selected by the user, check if it's ok for them to edit it, 
    // if not move cursor back to last know editable selection 
    editor.on('elementsPathUpdate', function(resPath) 
    { 
     // When we fire the "selectionChange" hook at the end of this code block, the "elementsPathUpdate" hook fires. 
     // No need to check because we just updated the selection, so bypass processing. 
     if(editor.cwjdsjcs_just_updated == true) 
     { 
     editor.cwjdsjcs_just_updated = false; 
     return true; 
     } 

     var elementsList = editor._.elementsPath.list; 
     var in_editable_area = false; 
     var non_editable_class = "cwjdsjcs_not_editable"; 
     var editable_class = "cwjdsjcs_editable"; 

     for(var w=0;w<elementsList.length;w++){ 
     var currentElement = elementsList[w]; 

     // Sometimes a non content element is selected, catch them and return selection to editable area. 
     if(w == 0) 
     { 
      // Could change to switch. 
      if(currentElement.getName() == "tbody") 
      { 
      in_editable_area = false; 
      break; 
      } 

      if(currentElement.getName() == "tr") 
      { 
      in_editable_area = false; 
      break; 
      } 
     } 

     // If selection is inside a non-editable element, break from loop and reset selection. 
     if(currentElement.hasClass(non_editable_class)) 
     { 
      in_editable_area = false; 
      break; 
     } 

     if(currentElement.hasClass(editable_class)) { 
      in_editable_area = true; 
     } 
     console.log(currentElement); 
     console.log(currentElement.getName()); 
     } 

     // if selection is within an editable element, exit the plugin, otherwise reset selection. 
     if(in_editable_area) { 
     lastSelectedElement = elementsList[0]; 
     return true; 
     } 

     var resRange = new CKEDITOR.dom.range(editor.document); 

     resRange.selectNodeContents(lastSelectedElement); 
     resRange.collapse(); 
     editor.getSelection().selectRanges([ resRange ]); 
     //resRange.endContainer.$.scrollIntoView(); 

     // Open dialog window: 
     // It tells user they selected a non-editable area and cursor has been returned to previous selection 
    currentEditorName = editor.name; 
     openResDefaultDialog(currentEditorName); 

     try 
     { 
     var sel = editor.getSelection(); 
     var firstElement = sel.getStartElement(); 
     var currentPath = new CKEDITOR.dom.elementPath(firstElement); 
     editor.cwjdsjcs_just_updated = true; 

     editor._.selectionPreviousPath = currentPath; 
     editor.fire('selectionChange', { selection : sel, path : currentPath, element : firstElement }); 

     } 
     catch (e) 
     {} 
    }); 
    } // *** END - init: function(editor) 
}); // ************************************************************************************* END - CKEDITOR.plugins.add 

這是一個被設置爲CKEDITOR內容區域的DIV :

<table id="messageTemplate1" class="message cwjdsjcs_editable"> 
    <tbody> 
     <tr> 
      <td class="cwjdsjcs_not_editable" contenteditable="false"> 
      </td> 
      <td id="cwjdsjcs_editable_id"> 

      </td> 
     </tr> 

     <tr class="cwjdsjcs_not_editable" contenteditable="false"> 
      <td colspan="2"> 
       &nbsp; 

       <!-- Begin Original Content --> 
       <table class="hide" style="font-size: 12px; display:none;"> 
        <tbody> 
         <tr class="hide"> 
          <td> 
          Application sent by <strong><a href="http://www.globalcastingcenter.com/talent/jack-bolton">Matt Faro</a></strong> for Audition: <a href="http://www.globalcastingcenter.com:80/CustomContentRetrieve.aspx?ID=4185493">Actors Needed</a> 
          </td> 
         </tr> 
         <tr class="hide"> 
          <td> 
          Reply to applicant directly: [email protected] or visit full profile: http://www.globalcastingcenter.com/talent/jack-bolton 
          </td> 
         </tr> 
        </tbody> 
       </table> 
       <table class="hide" style="font-size: 12px; display:none;"> 
        <tbody> 
         <tr class="hide"> 
          <td><strong>Short Profile Summary:</strong></td> 
         </tr> 
        </tbody> 
       </table> 
       <table class="hide" style="font-size: 12px; display:none;"> 
        <tbody> 
         <tr class="hide"> 
          <td> 
          <a href="http://www.globalcastingcenter.com/talent/jack-bolton"><img alt="" src="http://globalcastingcenter.com/talent_images/4164035_258551_foto.png?Action=thumbnail&amp;Width=144&amp;Height=215" /></a> 
          </td> 
         </tr> 
        </tbody> 
       </table> 
       <table style="font-size: 12px; display:none;" class="hide"> 
        <tbody> 
         <tr class="hide"> 
          <td><strong>Areas:</strong></td> 
          <td>Actor,Extra</td> 
         </tr> 
         <tr class="hide"> 
          <td><strong>Country:</strong></td> 
          <td>WORLDWIDE,Any</td> 
         </tr> 
         <tr class="hide"> 
          <td><strong>Age:</strong></td> 
          <td>26</td> 
         </tr> 
        </tbody> 
       </table> 


      </td> 
     </tr> 
    </tbody> 
</table> 

我在這裏貼了很多東西,但是這一切都歸結到我是否以及如何能啓動的CKEditor是完成了拆卸事件之後手動或最佳插件的問題。我也會問是否有更合理的解決方案來解決我的問題。也許插件啓動時機並非如此。

感謝

編輯:

插件腳本,以使用setData後推出cwjdsjcsconfineselection:

// JavaScript的文檔

CKEDITOR.plugins.add('cwjdsjcsconfineselection', 
{ 

    requires : [ 'elementspath' ], 

    init: function(editor) 
    { 

/*  editor.on('confineselection', function(confineselection_data) 
    { 

      alert ("Blocker is on!"); 




     }); // editor on END 

*/  

     editor.on('confineselection', function(confineselection_data) 
    { 
     alert ("Plugin fired!"); 

     // Create variable that will hold the last allowed selection (for use when a non-editable selection is made) 
     var lastSelectedElement; 
     editor.cwjdsjcs_just_updated = false; 

     // This section starts things off right by selecting a known editable element. 
     // *** Enter the ID of the element that should have initial focus *** IMPORTANT *** IMPORTANT *** 
     var starting_element_id = "cwjdsjcs_editable_id"; 

     var resInitialRange = new CKEDITOR.dom.range(editor.document); 

     resInitialRange.selectNodeContents(editor.document.getById(starting_element_id)); 
     resInitialRange.collapse(); 

     var selectionObject = new CKEDITOR.dom.selection(editor.document); 

     editor.document.focus(); 
     selectionObject.selectRanges([ resInitialRange ]); 

     var sel = editor.getSelection(); 
     var firstElement = sel.getStartElement(); 
     var currentPath = new CKEDITOR.dom.elementPath(firstElement); 

     // Set path for known editable element, fire "selectionChange" hook to update selection throughout instance. 
     editor._.selectionPreviousPath = currentPath; 
     editor.fire('selectionChange', { selection : sel, path : currentPath, element : firstElement }); 
    }); // *** END - editor.on('instanceReady', function(e) 


    // When a new element is selected by the user, check if it's ok for them to edit it, 
    // if not move cursor back to last know editable selection 
    editor.on('elementsPathUpdate', function(resPath) 
    { 
     // When we fire the "selectionChange" hook at the end of this code block, the "elementsPathUpdate" hook fires. 
     // No need to check because we just updated the selection, so bypass processing. 
     if(editor.cwjdsjcs_just_updated == true) 
     { 
     editor.cwjdsjcs_just_updated = false; 
     return true; 
     } 

     var elementsList = editor._.elementsPath.list; 
     var in_editable_area = false; 
     var non_editable_class = "cwjdsjcs_not_editable"; 
     var editable_class = "cwjdsjcs_editable"; 

     for(var w=0;w<elementsList.length;w++){ 
     var currentElement = elementsList[w]; 

     // Sometimes a non content element is selected, catch them and return selection to editable area. 
     if(w == 0) 
     { 
      // Could change to switch. 
      if(currentElement.getName() == "tbody") 
      { 
      in_editable_area = false; 
      break; 
      } 

      if(currentElement.getName() == "tr") 
      { 
      in_editable_area = false; 
      break; 
      } 
     } 

     // If selection is inside a non-editable element, break from loop and reset selection. 
     if(currentElement.hasClass(non_editable_class)) 
     { 
      in_editable_area = false; 
      break; 
     } 

     if(currentElement.hasClass(editable_class)) { 
      in_editable_area = true; 
     } 
     console.log(currentElement); 
     console.log(currentElement.getName()); 
     } 

     // if selection is within an editable element, exit the plugin, otherwise reset selection. 
     if(in_editable_area) { 
     lastSelectedElement = elementsList[0]; 
     return true; 
     } 

     var resRange = new CKEDITOR.dom.range(editor.document); 

     resRange.selectNodeContents(lastSelectedElement); 
     resRange.collapse(); 
     editor.getSelection().selectRanges([ resRange ]); 
     //resRange.endContainer.$.scrollIntoView(); 

     // Open dialog window: 
     // It tells user they selected a non-editable area and cursor has been returned to previous selection 
    currentEditorName = editor.name; 
     openResDefaultDialog(currentEditorName); 

     try 
     { 
     var sel = editor.getSelection(); 
     var firstElement = sel.getStartElement(); 
     var currentPath = new CKEDITOR.dom.elementPath(firstElement); 
     editor.cwjdsjcs_just_updated = true; 

     editor._.selectionPreviousPath = currentPath; 
     editor.fire('selectionChange', { selection : sel, path : currentPath, element : firstElement }); 

     } 
     catch (e) 
     {} 
    }); // Blocker source END 

     editor.on('instanceReady', function(ev) 
       {  
        var messageTemplate1 = $("#messageTemplate1").html(); 

        CKEDITOR.instances.ckeditor99.setData(messageTemplate1, function() 

        { 
         alert ("setData done!");    
         this.checkDirty(); // true 


        }); 

        CKEDITOR.instances.ckeditor99.fire('confineselection'); 


       }); 

    } // init END 

}); // Plugin add END 

還有用變形手柄周圍出現的問題表。這隻發生在Firefox中,這是視頻:http://screencast.com/t/lxKJWb6NI有時候這個盒子會在刷新後消失,有時候不會。如果您想現場測試,請在我的評論中提供登錄信息。

這是我的配置:

CKEDITOR.editorConfig = function(config) 
{ 


    config.toolbar = 'MyToolbar'; 

    config.toolbar_MyToolbar = 
    [ 

     { name: 'clipboard', items : [ 'Undo','Redo' ] },   
     { name: 'styles', items : ['FontSize' ] }, 
     { name: 'basicstyles', items : [ 'Bold','Italic'] }, 
     { name: 'paragraph', items : ['Outdent','Indent' ] }, 

    ]; 
    config.startupShowBorders = false; 
    config.disableObjectResizing = true; 


    config.removePlugins = 'contextmenu'; 
    config.forcePasteAsPlainText = true; 
    config.pasteFromWordRemoveFontStyles = true; 
    config.pasteFromWordRemoveStyles = true; 
    config.extraPlugins = 'cwjdsjcsconfineselection'; 




}; 
+1

如果您鏈接到自己的問題,導致插件代碼可能會有所幫助的人的未來。 – codewaggle 2012-07-20 16:13:03

回答

2

嘗試刪除股利後觸發一個事件:

CKEDITOR.instances.ckeditor99.fire('confineselection'); 

改變這一行的插件代碼的來源:

editor.on('instanceReady', function(instance_ready_data) 
    { 

對此:

editor.on('confineselection', function(confineselection_data) 
    { 

您可能想要移動在另一個代碼塊內的elementPathUpdate上觸發的代碼塊。所以這個:

editor.on('confineselection', function(confineselection_data) 
    { 
     ...................................................... 
     ...................................................... 
     // Set path for known editable element, fire "selectionChange" hook to update selection throughout instance. 
     editor._.selectionPreviousPath = currentPath; 
     editor.fire('selectionChange', { selection : sel, path : currentPath, element : firstElement }); 
    }); // *** END - editor.on('instanceReady', function(e) 


    // When a new element is selected by the user, check if it's ok for them to edit it, 
    // if not move cursor back to last know editable selection 
    editor.on('elementsPathUpdate', function(resPath) 
    { 
     ...................................................... 
     ...................................................... 
     catch (e) 
     {} 
    }); 

變爲這樣:

editor.on('confineselection', function(confineselection_data) 
    { 
     ...................................................... 
     ...................................................... 
     // Set path for known editable element, fire "selectionChange" hook to update selection throughout instance. 
     editor._.selectionPreviousPath = currentPath; 
     editor.fire('selectionChange', { selection : sel, path : currentPath, element : firstElement }); 


     // When a new element is selected by the user, check if it's ok for them to edit it, 
     // if not move cursor back to last know editable selection 
     editor.on('elementsPathUpdate', function(resPath) 
     { 
     ...................................................... 
     ...................................................... 
     catch (e) 
     {} 
     });  

    }); // *** END - editor.on('instanceReady', function(e) 
+0

我終於設法在setData之後得到這個工作,但Firefox的問題仍然存在。所有其他瀏覽器都顯示無邊界的可編輯區域,但在Firefox中,您有這些某種轉換框句柄。你可以嘗試這裏:http://gcc-july.themantas.co.uk/auditions/actors-需要用戶名:gaga pssw:測試我插入插件代碼與eventlistener和setData在我的問題。因爲它工作正常,看起來setData發生在插件運行之前,但警報消息提示否則。 – Mantas 2012-07-25 12:30:04

+0

這是apears變形盒的視頻:http://screencast.com/t/lxKJWb6NI – Mantas 2012-07-25 12:40:06

+0

我看了一下。關於警報的順序,'setData()'需要時間,所以下一個警報發生在'setData()'完成之前。在'this.checkDirty();'之後移動'fire()'以保證安全。試試'this.fire()'。 – codewaggle 2012-07-25 18:12:32