从 TinyMCE 选择中提取样式
Pulling a style from a TinyMCE selection
我正在尝试实现一个 TinyMCE 按钮,它将选择的样式应用到整个框。 I'm having trouble, though, reading the style of the selection when the selection is buried in a span in a span in a paragraph.让我们以 'color' 为例。下面我有一个带有一些文本的框,我在段落中选择了 "here" 并将其设为红色。
该段落的 HTML 现在是:
将选择的样式应用于框的按钮背后的代码是
var selected_color = $(ed.selection.getNode()).css('color');
console.log("color pulled is ", selected_color);
$(ed.bodyElement).css('color', selected_color);
它不起作用,因为拉出的颜色是黑色,而不是红色,所以第三行只是重新应用已经存在的黑色。 (如果我将第三行的 selected_color
替换为 'blue'
一切都会变成蓝色。)所以问题是拉动当前选择的颜色。
有谁知道我如何才能可靠地做到这一点,无论选择多么隐蔽?
感谢您的帮助。
我也注意到有些奇怪的行为,有嵌套跨度和 div 的选择,但老实说我无法识别这是否是 TinyMCE 的错误,浏览器问题或两者的结合(最有可能)。
因此,在等待您提供更多信息(也许还有您的插件代码)的同时,我意识到 两个 提议来实现您想要的:第一个插件的行为类似于在 word 格式刷中,第二个是简单地将当前检测到的前景色应用于整个段落。
当您使用键盘或鼠标在编辑器中移动时,您会看到当前检测到的前景色 突出显示并作为背景应用到第二个插件按钮。
这里的关键点是从光标位置取回样式的两个函数:
function findStyle(el, attr) {
var styles, style, color;
try {
styles = $(el).attr('style');
if(typeof styles !== typeof undefined && styles !== false) {
styles.split(";").forEach(function(e) {
style = e.split(":");
if($.trim(style[0]) === attr) {
color = $(el).css(attr);
}
});
}
} catch (err) {}
return color;
}
function findForeColor(node) {
var $el = $(node), color;
while ($el.prop("tagName").toUpperCase() != "BODY") {
color = findStyle($el, "color");
if (color) break;
$el = $el.parent();
}
return color;
}
需要 try...catch
块来避免在重新设置所选文本样式时偶尔出现一些错误。如果您查看 TinyMCE 源代码,您会注意到大量的计时事件,这是处理样式和 css 时不可避免的常见做法,在用户交互时更是如此。 TinyMCE 的作者在制作编辑器 cross-browser.
方面做得非常出色
您可以试用下面Fiddle中的第一个插件。第二个插件比第一个更简单。 lastForeColor
是在ed.on('NodeChange')
中确定的,所以点击按钮的代码非常简单。
tinymce.PluginManager.add('example2', function(ed, url) {
// Add a button that opens a window
ed.addButton('example2', {
text: '',
icon: "apply-forecolor",
onclick: function() {
if(lastForeColor) {
var applyColor = lastForeColor;
ed.execCommand('SelectAll');
ed.fire('SelectionChange');
ed.execCommand('forecolor', false, applyColor);
ed.selection.collapse(false);
ed.fire('SelectionChange');
}
return false;
}
});
});
此外:我认为您的代码片段存在潜在问题:
$(ed.bodyElement).css('color', selected_color);
我想应该以不同的方式应用样式,所以在我的示例中,我使用标准的 TinyMCE 命令将前景色应用于所有对象,因为我无法完全 将您的屏幕截图转换为代码。请在评论中分享您的想法。
Fiddle 两个插件:https://jsfiddle.net/ufp0Lvow/
去块剂,
很棒的作品!谢谢!
您的 jsfiddle 成功了。我用示例中的内容替换了 HTML,并将 tinymce.init 中的选择器从文本区域更改为 div,它完美地从示例中提取了颜色。修改后的 jsfiddle 位于 https://jsfiddle.net/79r3vkyq/3/ 。我会长期研究和学习你的代码。
关于您关于
的问题
$(ed.bodyElement).css('color', selected_color);
我将 tinymce 附加到的 divs 都有 id,编辑器当前附加到的那个在 ed.bodyElement 中报告。我使用这个没有任何问题,但我使用你的
没有问题
ed.execCommand('SelectAll');
ed.fire('SelectionChange');
ed.execCommand('forecolor', false, applyColor);
再次感谢!干得好!
我正在尝试实现一个 TinyMCE 按钮,它将选择的样式应用到整个框。 I'm having trouble, though, reading the style of the selection when the selection is buried in a span in a span in a paragraph.让我们以 'color' 为例。下面我有一个带有一些文本的框,我在段落中选择了 "here" 并将其设为红色。
该段落的 HTML 现在是:
将选择的样式应用于框的按钮背后的代码是
var selected_color = $(ed.selection.getNode()).css('color');
console.log("color pulled is ", selected_color);
$(ed.bodyElement).css('color', selected_color);
它不起作用,因为拉出的颜色是黑色,而不是红色,所以第三行只是重新应用已经存在的黑色。 (如果我将第三行的 selected_color
替换为 'blue'
一切都会变成蓝色。)所以问题是拉动当前选择的颜色。
有谁知道我如何才能可靠地做到这一点,无论选择多么隐蔽?
感谢您的帮助。
我也注意到有些奇怪的行为,有嵌套跨度和 div 的选择,但老实说我无法识别这是否是 TinyMCE 的错误,浏览器问题或两者的结合(最有可能)。
因此,在等待您提供更多信息(也许还有您的插件代码)的同时,我意识到 两个 提议来实现您想要的:第一个插件的行为类似于在 word 格式刷中,第二个是简单地将当前检测到的前景色应用于整个段落。
当您使用键盘或鼠标在编辑器中移动时,您会看到当前检测到的前景色 突出显示并作为背景应用到第二个插件按钮。
这里的关键点是从光标位置取回样式的两个函数:
function findStyle(el, attr) {
var styles, style, color;
try {
styles = $(el).attr('style');
if(typeof styles !== typeof undefined && styles !== false) {
styles.split(";").forEach(function(e) {
style = e.split(":");
if($.trim(style[0]) === attr) {
color = $(el).css(attr);
}
});
}
} catch (err) {}
return color;
}
function findForeColor(node) {
var $el = $(node), color;
while ($el.prop("tagName").toUpperCase() != "BODY") {
color = findStyle($el, "color");
if (color) break;
$el = $el.parent();
}
return color;
}
需要 try...catch
块来避免在重新设置所选文本样式时偶尔出现一些错误。如果您查看 TinyMCE 源代码,您会注意到大量的计时事件,这是处理样式和 css 时不可避免的常见做法,在用户交互时更是如此。 TinyMCE 的作者在制作编辑器 cross-browser.
您可以试用下面Fiddle中的第一个插件。第二个插件比第一个更简单。 lastForeColor
是在ed.on('NodeChange')
中确定的,所以点击按钮的代码非常简单。
tinymce.PluginManager.add('example2', function(ed, url) {
// Add a button that opens a window
ed.addButton('example2', {
text: '',
icon: "apply-forecolor",
onclick: function() {
if(lastForeColor) {
var applyColor = lastForeColor;
ed.execCommand('SelectAll');
ed.fire('SelectionChange');
ed.execCommand('forecolor', false, applyColor);
ed.selection.collapse(false);
ed.fire('SelectionChange');
}
return false;
}
});
});
此外:我认为您的代码片段存在潜在问题:
$(ed.bodyElement).css('color', selected_color);
我想应该以不同的方式应用样式,所以在我的示例中,我使用标准的 TinyMCE 命令将前景色应用于所有对象,因为我无法完全 将您的屏幕截图转换为代码。请在评论中分享您的想法。
Fiddle 两个插件:https://jsfiddle.net/ufp0Lvow/
去块剂,
很棒的作品!谢谢!
您的 jsfiddle 成功了。我用示例中的内容替换了 HTML,并将 tinymce.init 中的选择器从文本区域更改为 div,它完美地从示例中提取了颜色。修改后的 jsfiddle 位于 https://jsfiddle.net/79r3vkyq/3/ 。我会长期研究和学习你的代码。
关于您关于
的问题$(ed.bodyElement).css('color', selected_color);
我将 tinymce 附加到的 divs 都有 id,编辑器当前附加到的那个在 ed.bodyElement 中报告。我使用这个没有任何问题,但我使用你的
没有问题ed.execCommand('SelectAll');
ed.fire('SelectionChange');
ed.execCommand('forecolor', false, applyColor);
再次感谢!干得好!