Dynamic Body Color using CKEditor
I have a situation on CKEditor that I would like to resolve. I use a jQuery color picker to add background color to a DIV tag. Then I allow the user to edit the Div tag contents using CKEditor. However, I noticed that there isn't a simple way to take the div tag's background color and then make that as the background color of the CKEditor when the editor loads up.
I have read up on bodyClass and bodyId and do not think that these solve my problem. I do not have a class element but an inline style declaration like
<div class="tp-header" style="background-color:#CCCCCC;">content</div>
I invoke the CKEditor as follows:
var editorId = 'editor1';
var instance = CKEDITOR.instances[editorId];
var color 开发者_JAVA百科= $('.' + headerElementClass).css('background-color');
if (instance) { CKEDITOR.remove(instance); }
$('#' + editorId).ckeditor({ toolbar: 'BasicHtml', height: '100px', width: '500px', fullPage: false, bodyClass : 'background-color:' + color });
$('#' + editorId).val($('.' + headerElementClass).html());
Notice the failed usage of bodyClass. Is there any way to do this? I have scourged around the site for answers but couldn't find one. I hope someone here has the answer.
I was thinking about this and I came up with a much simpler solution.
I'm not using the CKEditor jQuery adapter, so you may need to modify it to fit your situation.
I did test it using the standard JavaScript integration approach.
Quick Overview:
Set the variables.
Create the editor instance.
Insert this "addCss" function call:
CKEDITOR.instances[editorId].addCss( 'body { background-color: '+color+'; }' );
That's all there is to it. Here's a sample based on your code:
// I added the "id" attribute:
<div id="editor1" class="tp-header" style="background-color:#CCCCCC;">content</div>
// Declare the variables, I added "headerElementClass".
var headerElementClass = "tp-header";
var color = $('.' + headerElementClass).css('background-color');
var editorId = 'editor1';
// Create the instance.
var instanceOne = CKEDITOR.replace( editorId,
{
toolbar: 'Basic',
height: '100px',
width: '500px',
fullPage: false,
customConfig : 'yourCustomConfigFileIfUsed.js'
});
// Insert the "addCss" function call:
instanceOne.addCss( 'body { background-color: '+color+'; }' );
The addCss function call can be moved to your config file if you prefer (place it outside the editorConfig function).
Be Well, Joe
Leaving the more complicated approach, someone might find the concepts useful.
You could use ( bodyClass: 'nameOfClass' ), then assign a value to the background-color property of that class. But that's difficult because you have a dynamic background color.
To assign the background color dynamically you could do something like this: Starting with your code and continuing the use of jQuery:
var editorId = 'editor1';
var instance = CKEDITOR.instances[editorId];
var color = $('.' + headerElementClass).css('background-color');
// Create a unique body id for this instance "editor1" ( bodyIdForeditor1 )
var idForBody = 'bodyIdFor' + editorId;
if (instance) { CKEDITOR.remove(instance); }
// Use bodyId instead of the original bodyClass assignment
$('#' + editorId).ckeditor({
toolbar: 'BasicHtml',
height: '100px',
width: '500px',
fullPage: false,
bodyId : idForBody
});
$('#' + editorId).val($('.' + headerElementClass).html());
// After both the document and editor instance are ready,
// assign the background color to the body
// Wait for the document ready event
$(document).ready(function(){
// Wait for the instanceReady event to fire for this (editor1) instance
CKEDITOR.instances.editor1.on( 'instanceReady',
function( instanceReadyEventObj )
{
var currentEditorInstance = instanceReadyEventObj.editor;
var iframeDoc=null;
// Create a function because these steps will be repeated
function setIframeBackground()
{
// The CKEditor content iframe doesn't have a Name, Id or Class
// So, we'll assign an ID to the iframe
// it's inside a table data cell that does have an Id.
// The Id of the data cell is "cke_contents_editor1"
// Note that the instance name is the last part of the Id
// I'll follow this convention and use an Id of "cke_contents_iframe_editor1"
$("#cke_contents_editor1 iframe").attr("id", "cke_contents_iframe_editor1");
// Now use the iframe Id to get the iframe document object
// We'll need this to set the context and access items inside the iframe
$('#cke_iframe_editor1').each(
function(){ iframeDoc=this.contentWindow.document;}
);
// Finally we can access the iframe body and set the background color.
// We set the Id of the body when we created the instance (bodyId : idForBody).
// We use the iframe document object (iframeDoc) to set the context.
// We use the "color" variable created earlier
$('#' + idForBody, iframeDoc).css("background-color", color);
}
// Call the function to set the color when the editor instance first loads
setIframeBackground();
// When the user switches to "source" view mode, the iframe is destroyed
// So we need to set the color again when they switch back to "wysiwyg" mode
// Watch for the "mode" event and check if we're in "wysiwyg" mode
currentEditorInstance.on( 'mode', function()
{
if(currentEditorInstance.mode == 'wysiwyg')
setIframeBackground();
});
}
);
});
Be Well, Joe
codewaggle's answer is a good one, but if you want to set inline styles on the editor's <body>
element, you can do that too, using:
editor.document.getBody().setStyle()
or
editor.document.getBody().setStyles()
However, you'll need to redo this every time after calling editor.setData() and after the user switches back to wysiwyg mode (from source mode), because these things re-create the editor iframe. To do all that, set your styles using a function, say setEditorStyle
, in which you check first that editor.mode==='wysiwyg'
(editor.document
is null otherwise), then add that function as an event listener for the instanceReady
and mode
events; and perhaps also the contentDom
event if you ever call setData() and don't want to call it manually afterwards.
See some other StackOverflow answers here and here
Dynamic Body Color change CKEditor
Expert Suggestion
精彩评论