从TinyMCE选择中拉出样式

时间:2017-01-27 19:06:49

标签: tinymce-4

我试图实现一个TinyMCE按钮,将选择的样式应用于整个框。但是,当选择被隐藏在段落中的跨度中时,我会遇到麻烦。我们考虑一下颜色'例如。下面我有一个包含一些文字的方框,我已经选择了"这里"在段落中并使其变红。

enter image description here

段落的HTML现在是:

enter image description here

我的按钮后面的代码将选择的样式应用到框中

if (isset($data['page_id'])) 
{
  if (array_key_exists($data['page_id'], $pages_data)) 
  {
    echo "<pre>";
    var_dump($pages_data);
    $pages_data[$data['page_id']] += array(
      $data['article_category'] =>  $data['count_article_category'],
    );
  } else {
    // $pages_data[$data['article_category']] = $data['average_ctr'];
    // $pages_dat a[$data['page_id']] = $data['page_id'];
    $pages_data[$data['page_id']] = array(
      $data['article_category'] =>  $data['count_article_category'],
    );
  }
  echo "<pre>";
  print_r($pages_data);
}

它不起作用,因为拉出的颜色是黑色而不是红色,所以第三行只是重新应用已经存在的黑色。 (如果我用 var selected_color = $(ed.selection.getNode()).css('color'); console.log("color pulled is ", selected_color); $(ed.bodyElement).css('color', selected_color); 替换第三行中的selected_color,一切都变为蓝色。)所以问题是拉出当前选择的颜色。

有谁知道如何可靠地做到这一点,无论选择的埋藏程度如何?

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

我也注意到有些奇怪的行为,有嵌套的span和div的选择,但老实说,我无法识别这是TinyMCE的错误,浏览器问题还是两者的结合(最有可能) )。

所以,等待你的更多信息(也许也是你的插件代码)同时我实现了两个提议来实现你想要的东西:第一个插件的行为类似于word中的格式画家,第二种是简单地将当前检测到的前景色应用于整个段落。

当您使用键盘或鼠标移动编辑器时,您将看到当前检测到的前景色突出显示并作为背景应用于第二个插件按钮。

enter image description here

这里的关键点是从光标位置返回样式的两个函数:

  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的作者做了很棒的工作来使编辑器跨浏览器。

您可以在下面的小提琴中试用第一个插件。第二个插件比第一个插件更简单。 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命令将前景色应用于所有,因为我无法完全转换你的截图到代码。请在评论中分享您的想法。

摆弄两个插件:https://jsfiddle.net/ufp0Lvow/

答案 1 :(得分:0)

解块器,

出色的工作!谢谢!

你的jsfiddle成功了。我用我的例子中的内容替换了HTML,并将tinymce.init中的选择器从textarea更改为div,它从我的示例中完美地拉出了颜色。修改过的jsfiddle位于https://jsfiddle.net/79r3vkyq/3/。我将在很长一段时间内学习并学习你的代码。

关于

的问题
$(ed.bodyElement).css('color', selected_color);

divs我将所有的id附加到了id,而编辑器当前附加的那个在ed.bodyElement中报告。我使用它没有遇到任何问题,但使用

我没有问题
ed.execCommand('SelectAll');
ed.fire('SelectionChange');
ed.execCommand('forecolor', false, applyColor);

再次感谢!太棒了!