问题
I implemented a TinyMCE button to increase the letter spacing at http://fiddle.tinymce.com/Z9eaab/31. If you enter the words "some text" in the text area at the bottom and then select "some" and hit the "Increase letter spacing" button multiple times, the letter spacing only increases the first time. If you select the second word, "text," the spacing increases each time you hit "Increase letter spacing." as it should.
I can see from the console.log on line 9 that when it doesn't work it's because the current spacing read doesn't reflect the last increase, so it just keeps redoing the first one.
<script type="text/javascript">
tinymce.PluginManager.add('example', function(editor, url) {
// Add a button that opens a window
editor.addButton('example1', {
text: 'Increase letter spacing',
icon: false,
onclick: function() {
var currentSpacing = new Number($(tinyMCE.activeEditor.selection.getNode()).css('letter-spacing').replace('px', ''));
console.log("spacing read is" + currentSpacing);
currentSpacing = currentSpacing + 1;
tinymce.activeEditor.formatter.register('increaseSpacing', {
inline: 'span',
styles: {
'letter-spacing': currentSpacing + 'px'
}
});
tinymce.activeEditor.formatter.apply('increaseSpacing');
}
});
editor.addButton('example2', {
text: 'Decrease letter spacing',
icon: false,
onclick: function() {
var currentSpacing = new Number($(tinyMCE.activeEditor.selection.getNode()).css('letter-spacing').replace('px', ''));
currentSpacing = currentSpacing - 1;
tinymce.activeEditor.formatter.register('decreaseSpacing', {
inline: 'span',
styles: {
'letter-spacing': currentSpacing + 'px'
}
});
tinymce.activeEditor.formatter.apply('decreaseSpacing');
}
});
// Adds a menu item to the tools menu
editor.addMenuItem('example', {
text: 'Example plugin',
context: 'tools',
onclick: function() {
// Open window with a specific url
editor.windowManager.open({
title: 'TinyMCE site',
url: 'http://www.tinymce.com',
width: 400,
height: 300,
buttons: [{
text: 'Close',
onclick: 'close'
}]
});
}
});
});
tinymce.init({
selector: "textarea",
plugins: "example",
toolbar: "example1 example2 undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image"
});
</script>
<form method="post" action="dump.php">
<textarea name="content"></textarea>
</form>
Does anyone know what's going on?
回答1:
You're using selection.getNode()
which finds the common parent node of the start and end points of the selection. This is not the node that is in the current selection.
In your case you want the <span>
you've created, but what you've actually asked for is its enclosing <p>
(subsequently you're checking its current letter-spacing
CSS value, which it won't have).
To correct this, after applying the formatting, grab the span (either created previously, or newly added), and set the current selection to it. You can do this using selection.getStart():
var spanNode = tinyMCE.activeEditor.selection.getStart();
tinymce.activeEditor.selection.select(spanNode);
When used after the tinymce.activeEditor.formatter.apply()
, it will be the correct span.
Here's the updated code (I've made a number of other formatting changes):
<script type="text/javascript">
tinymce.PluginManager.add('example', function(editor, url) {
// Add a button that opens a window
editor.addButton('example1', {
text: 'Increase letter spacing',
icon: false,
onclick: function() {
var currentSpacing = 0;
var $selectedContent = $(tinyMCE.activeEditor.selection.getContent({'format': 'html'}));
if ($selectedContent.is("span") && $selectedContent.css('letter-spacing')) {
currentSpacing = +($selectedContent.css('letter-spacing').replace('px', ''));
}
currentSpacing += 1;
tinymce.activeEditor.formatter.apply('letterSpacing', {
value: currentSpacing + 'px'
});
var spanNode = tinyMCE.activeEditor.selection.getStart();
tinymce.activeEditor.selection.select(spanNode);
}
});
editor.addButton('example2', {
text: 'Decrease letter spacing',
icon: false,
onclick: function() {
var currentSpacing = 0;
var $selectedContent = $(tinyMCE.activeEditor.selection.getContent({'format': 'html'}));
if ($selectedContent.is("span") && $selectedContent.css('letter-spacing')) {
currentSpacing = +($selectedContent.css('letter-spacing').replace('px', ''));
}
currentSpacing -= 1;
tinymce.activeEditor.formatter.apply('letterSpacing', {
value: currentSpacing + 'px'
});
var spanNode = tinyMCE.activeEditor.selection.getStart();
tinymce.activeEditor.selection.select(spanNode);
}
});
// Adds a menu item to the tools menu
editor.addMenuItem('example', {
text: 'Example plugin',
context: 'tools',
onclick: function() {
// Open window with a specific url
editor.windowManager.open({
title: 'TinyMCE site',
url: 'http://www.tinymce.com',
width: 400,
height: 300,
buttons: [{
text: 'Close',
onclick: 'close'
}]
});
}
});
});
tinymce.init({
selector: "textarea",
plugins: "example",
toolbar: "example1 example2 undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image",
formats: {
'letterSpacing': {
inline: 'span',
styles: {
'letter-spacing': '%value'
}
}
}
});
</script>
<form method="post" action="dump.php">
<textarea name="content"></textarea>
</form>
Demo: http://fiddle.tinymce.com/wYfaab/2
来源:https://stackoverflow.com/questions/45898296/custom-tinymce-4-x-button-to-increase-letter-spacing-not-working