tinymce系列(三) tinymce 常用API介绍

tinymce 常用 API 介绍

这篇文章将会介绍常用的 API,对于下面的示例代码,很多都用到了一个 editor 的变量。 注意 editor 是当前的实例,而非全局变量,如需要使用全局变量改用 tinymce.activeEditor
editor 通常来自 PluginManager.add 注册插件后,回调参数中会携带 editor 实例

引入模块

tinymce.util.Tools.resolve

参考代码节选自 :tinymce 的 fullpage 插件

var global = tinymce.util.Tools.resolve('tinymce.PluginManager')
var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools')
var global$2 = tinymce.util.Tools.resolve('tinymce.html.DomParser')
var global$3 = tinymce.util.Tools.resolve('tinymce.html.Node')
var global$4 = tinymce.util.Tools.resolve('tinymce.html.Serializer')

如果不使用 util.Tools.resolve 引入,部分功能也可以通过 tinymce.PluginManager 直接调用


注册插件

PluginManager.add(‘插件名称’, function(editor,path){})

参数作用
editor获取当前 tinymce 实例
path获取当前加载的 URL(是相对 tinymce 的网络路径,主要用于加载其他额外资源的时候会用到)

* editor 对象作为当前 tinymce 的实例非常重要,包括当前插件中的事件绑定,获取当前实例的配置等

* editor 等同于 tinymce.activeEditortinymce.get(‘my_editor’)

官方示例如下,在 add 的回调方法中进行按钮注册,逻辑绑定等处理
除了基础按钮,下拉菜单,还有非常多的内置表单类型,详情查看文档 tinymce.editor.ui.registry

tinymce.PluginManager.add('MyPlugin', function(editor, url) {
  // Register a toolbar button that triggers an alert when clicked
  // To show this button in the editor, include it in the toolbar setting
  editor.ui.registry.addButton('myCustomToolbarButton', {
    text: 'My Custom Button',
    onAction: function() {
      alert('Button clicked!')
    }
  })

  // Register a menu item that triggers an alert when clicked
  // To show this menu item in the editor, include it in the menu setting
  editor.ui.registry.addMenuItem('myCustomMenuItem', {
    text: 'My Custom Menu Item',
    onAction: function() {
      alert('Menu item clicked')
    }
  })

  // Either return plugin metadata or do not return
  return {
    name: 'MyPlugin',
    url: 'https://mydocs.com/myplugin'
  }
})

获取编辑器传入的参数

editor.getParam

getParma 接收 2 个参数

  1. 要获取的配置变量名
  2. 获取不到的时候的默认值

参数传递在 tinymce.init 方法中开始传入,比如传入一个 myvalue 参数:

业务代码中

tinymce.init({
  selector: 'textarea.tinymce',
  myvalue: { key: 'value' } // 这里的参数是任意类型,可以为string、回调函数等(回调函数建议通过事件的方式触发)
})

插件逻辑中,使用 getParam 获取参数

// 如果要使用 editor 必须在 tinymce.PluginManager.add 回调里面拿到 editor 实例
var someval = editor.getParam('myvalue', { key: '1' })

// 如果想在其他地方获取参数,可以使用 tinymce 当前获取焦点的编辑器获取实例
var someval1 = tinymce.activeEditor.getParam('myvalue', { key: '1' })

// 也可以通过指定 tinymce 的节点ID获取 (textarea.tinymce 就是 class名为 tinymce的textarea 标签)
var someval2 = tinymce.get('textarea.tinymce').getParam('myvalue')

事件监听与派发

editor.fire() 和 editor.on()

派发后的事件在业务逻辑中,或者不同的插件中也能监听到,只能能获取 editor 实例的地方都能监听

事件派发:通过 editor.fire('事件名',参数值)
事件监听:事件派发后,通过 editor.on('事件名', 回调函数) 进行监听

实现局部的事件派发:

参考使用 tinymce.util.eventdispatcher

var eventDispatcher = new EventDispatcher()
eventDispatcher.on('click', function() {
  console.log('data')
})
eventDispatcher.fire('click', { data: 123 })

tinymce 内置请求

建议还是通过业务逻辑完成请求,避免在插件中发起请求

JSON 请求

var json = new tinymce.util.JSONRequest({
  url: 'somebackend.php',
  params: ['a', 'b'],
  success: function(result) {
    console.dir(result)
  }
})

XHR 请求

// Sends a low level Ajax request
tinymce.util.XHR.send({
  url: 'someurl',
  success: function(text) {
    console.debug(text)
  }
})

// Add custom header to XHR request
tinymce.util.XHR.on('beforeSend', function(e) {
  e.xhr.setRequestHeader('X-Requested-With', 'Something')
})

JSONP 请求 在文档没有详细列出,在 tinymce.js 源码可以看到相关的逻辑

JSONP 虽然是通过添加 script 标签发出的请求,不过会在底层参数中加上对应的资源标识,所以可以使用 callback 找到发出的请求对应的参数值

tinymce JSONP 源码实现部分:

var JSONP = {
  callbacks: {},
  count: 0,
  send: function(settings) {
    var self = this,
      dom = DOMUtils$1.DOM,
      count = settings.count !== undefined ? settings.count : self.count
    var id = 'tinymce_jsonp_' + count
    self.callbacks[count] = function(json) {
      dom.remove(id)
      delete self.callbacks[count]
      settings.callback(json)
    }
    dom.add(dom.doc.body, 'script', {
      id: id,
      src: settings.url,
      type: 'text/javascript'
    })
    self.count++
  }
}

JSONP 在插件中使用,发送请求

const $jsonp = tinymce.util.Tools.resolve('tinymce.util.JSONP')

$jsonp.send({
  url: 'someurl',
  callback: function(json) {
    resolve(json)
  }
})

动态添加资源

有时候会有动态加载 JS,或者动态加载样式的需求

tinymce 有时候是通过 iframe 的形式嵌入,直接使用 document.body 插入的资源也无法影响 iframe 内容,所以需要使用内置的 API 进行添加

动态加载 JS tinymce.dom.scriptloader

// Load a script from a specific URL using the global script loader
tinymce.ScriptLoader.load('somescript.js')

// Load a script using a unique instance of the script loader
var scriptLoader = new tinymce.dom.ScriptLoader()

scriptLoader.load('somescript.js')

// Load multiple scripts
var scriptLoader = new tinymce.dom.ScriptLoader()

scriptLoader.add('somescript1.js')
scriptLoader.add('somescript2.js')
scriptLoader.add('somescript3.js')

scriptLoader.loadQueue(function() {
  alert('All scripts are now loaded.')
})

通过添加 dom 节点方式添加 tinymce.dom.domutils

tinymce.activeEditor.dom.add(tinymce.activeEditor.getBody(), 'script', {
  src: 'somescript4.js',
  type: 'text/javascript'
})

获取和操作 dom 节点 和 操作 html

操作 dom 的时候尽可能使用内置的 DomQuery 等之类的 API,因为有时候 tinymce 是通过 iframe 的形式嵌入,普通的 document.querySelector 可能无法找到对应的 dom,插入的资源也无法影响 iframe 内容

如果要使用 document.querySelector 等原生 API,使用 tinymce.activeEditor.getBody() 或 editor.dom.doc 替换 document

editor.dom.doc.querySelector('.my_plugin') // 获取到编辑器中 .my_plugin 的节点

tinymce.activeEditor.getBody() 或 editor.dom.doc 永远都指向于 tinymce 的 dom 实例

  • 获取 dom 节点,更多适用于已有 dom 节点,需要操作节点中的内容

tinymce.dom.DomQuery

tinymce 提供了类似 JQ 的功能。不过没有 JQ 那么完善,使用方法可以直接通过 $ = tinymce.dom.DomQuery 或者使用 $ = tinymce.util.Tools.resolve('tinymce.dom.DomQuery')


  • html 操作,更多适用于字符串类型解析为 dom 类型

把 HTML 字符串解析 html 节点tinymce.html.domparser

把 HTML 解析单个节点 tinymce.html.node

获取光标选中内容

选中的文本会有 2 个情况,在代码的注释有说明。代码节选中 zk_quick_style 部分

相关 API 文档:

光标操作: tinymce.dom.selection

功能是把选中的文本/没选中状态下把该段文本包裹一个指定的样式

/**
 * 获取选中的内容
 * @param {*} editor
 */
function getRangeText(editor = tinymce.activeEditor) {
  let rngInfo = editor.selection.getRng()
  let rangeText = rngInfo.commonAncestorContainer.textContent
  if (!rangeText) {
    return ''
  }

  // 这里是因为如果有3段文本,选中其中2段的时候,commonAncestorContainer 的文本其实是给出了3段合并的文字
  // 但是选中范围是根据第一段文字和最后一段文字来计算的位置,所以要根据开头文本开始匹配
  let _startText = rngInfo.startContainer.textContent
  rangeText = rangeText.replace(new RegExp(`.*(${_startText}.*)`), '$1')

  let _start = rngInfo.startOffset
  let _end = rngInfo.endOffset
  let _select = _end - _start

  if (_select == 0 || _select == rangeText.length) {
    // 情况1:_select == 0 就是没有选中任何文本,那就把当前的 div 的文本都提出来,走默认就行,并且创建选取,选中该文本
    // 情况2:在同一行中,选中了全部的字,这时候应该把他上级的节点也选中,否则使用 insert 的时候上面会多一个空行
    editor.selection.select(rngInfo.commonAncestorContainer)
  } else {
    // 如果有选中内容,并且考虑多行的情况, _end 记录的是最后一行选中的字符,而不是光标全中的长度
    let _endText = rngInfo.endContainer.textContent
    rangeText = rangeText.replace(new RegExp(`(.*)${_endText}`), '$1')
    rangeText += _endText.substring(0, _end)
    rangeText = rangeText.substring(_start, rangeText.length)
  }
  return rangeText
}

保存快照(撤销和重做)

原文文档:tinymce.undomanager

在进行一些操作步骤后如果想记录该操作用用户可以撤销的话,可以使用以下指令

editor.undoManager.add()

执行内置指令

指令文档 execcommand

web 中也有内置指令 MDN-execCommand不过该 API 已经废弃,虽然可能还能调用(不清楚兼容性),推荐还是使用 tinymce 封装过的 execCommand 进行指令执行

对于常见的 加粗,居中 等操作。web 有一套指令,tinymce 在这基础上也封装了独有的指令,调用方式如下:

// 示例
editor.execCommand('指令名称')

// 左对齐指令
editor.execCommand('JustifyLeft')

// 居中
editor.execCommand('JustifyCenter')

收集到的常用指令如下:

指令名称效果
bold加粗
italic斜体
subscript下标
superscript上标
strikeThrough删除线
underline下划线
insertOrderedList插入有序列表
insertUnorderedList插入无序列表
justifyCenter居中
justifyFull环绕对齐
justifyLeft左对齐
justifyRight右对齐
insertHorizontalRule插入水平尺

文档没有列出很多的资料名称,不过可以通过查阅源码找到想要执行的指令,在 tinymce.js 文件中搜索 EditorCommands.prototype.setupCommands 可以看到大多数的指令和实现方式

注册自己的指令

相关文档: addcommand

代码来自官网的示例:

注册了一个叫 mycommand 的指令。效果是通过 内置的 windowManager 弹出 当前选中的文本

editor.addCommand('mycommand', function(ui, v) {
  editor.windowManager.alert('Hello world!! Selection: ' + editor.selection.getContent({ format: 'text' }))
})

// 执行指令
editor.execCommand('mycommand')

插入和设置内容

分别是 setContentinsertContent

editor.setContent(`<p>把整个编辑器内容设置为这段文本</p>`)
editor.insertContent(`<p>在光标当前位置插入当前文本</p>`)

最后

tinymce 常用的 API 大概就是以上的内容,已经涵盖了时间监听,获取 dom 节点,光标操作,内部指令等。

光有 API 还是不太够,下一章将会介绍 tinymce 常用内置 UI 组件介绍

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值