问题
I'm trying to make it so that if you click the CKEditor's text area (where you type), it shows an alert, but I can't get it working and I'm not sure why.
Here's the JSFiddle: http://jsfiddle.net/C7N7r/44/
Please help!
HTML:
<form>
<textarea class="ckeditor" id="editor1">Some text.</textarea>
</form>
JS:
CKEDITOR.replace("editor1", {});
$(document).on("click", ".cke_contents", function() {
alert("CLICKED");
});
回答1:
The problem
With delegated event handler you are capturing click events for any elements with class cke_contents
that will ever exist in the document. And you are doing it right.
The problem is that .cke_contents
is never clicked. It never handles click
event. You can click it from code and your alert pops up.
CKEDITOR.on('instanceReady', function(){$('.cke_contents').click()})
This is because of an iframe
filling the full area of .cke_contents
. Events are not propagated across frames, nor are they generated independently for the frame.
How to solve it
You can set event handler inside the iframe
. You can access its contents as it does not violate same-origin policy (both the document and the frame have the same document.domain
).
CKEDITOR.on('instanceReady', function() {
$('.cke_contents iframe').contents().click(function() {
alert('Clicked!');
});
});
jQuery.contents() returns its content document for iframe
, if it does not violate same-origin policy.
Problem is that instanceReady is triggered for each CKEditor instance and the code above adds click handler to all CKEditors, therefore the handlers could be duplicated.
However, this can be solved by assigning the handlers more locally, just to the currently becoming ready editor:
CKEDITOR.on('instanceReady', function(evt) {
$(evt.editor.container.$).find('iframe').contents().click(function() {
alert('Clicked!');
});
});
This works OK as you can see on JsFiddle.
Side notes
Originally I did not get jQuery event delegation and thought you are trying to add your event handler before the element with .cke_contents
exists (your code is executed much earlier). Without event delegation you would need to use CKEditor API, namely instanceReady event of the editor, only that way you can be sure you are adding your event handler to an already existing element. ($(document).ready(…);) is still too early as you can see via console.log($('.cke_contents').toSource());
.
BTW your attempt to replace your textarea with CKEditor manually just throws an exception as it already has been replaced. Try wrapping it in try {…} catch (e) { console.log(e); }
to see it.
回答2:
You can use the CKEditor API to do it in a simple way:
function clickListener(e) {
alert("clicked")
}
CKEDITOR.on('instanceReady', function(ev){
ev.editor.editable().attachListener(ev.editor.document, "click", clickListener)
})
demo at http://jsfiddle.net/up3HG/1/
回答3:
Is it not just the wrong class selector being used? Use .ckeditor
instead:
$(document).ready(function() {
$(document).on("click", ".ckeditor", function() {
alert("Clicked!");
});
});
来源:https://stackoverflow.com/questions/21469339/clicking-ckeditor-content-to-show-alert