---
title: "使用 JavaScript 创建节点视图"
description: "使用 Vanilla JavaScript 在 Tiptap 中构建自定义节点视图。直接操作节点属性和交互式内容。"
canonical_url: "https://tiptap.zhcndoc.com/editor/extensions/custom-extensions/node-views/javascript"
---

# 使用 JavaScript 创建节点视图

使用 Vanilla JavaScript 在 Tiptap 中构建自定义节点视图。直接操作节点属性和交互式内容。

如果你习惯于不使用框架（例如 Vue 或 React），使用这些框架可能会感觉过于复杂。好消息是：你可以在你的节点视图中使用 Vanilla JavaScript。你只需了解一些基本知识，接下来我们就一个一个来看。

## 使用 JavaScript 渲染节点视图

要在编辑器中渲染节点视图，你需要执行以下步骤：

1. [创建节点扩展](https://tiptap.zhcndoc.com/editor/extensions/custom-extensions/create-new/node.md)
2. 使用 `addNodeView()` 注册一个新的节点视图
3. 编写你的渲染函数
4. [配置 Tiptap 使用你的新节点扩展](https://tiptap.zhcndoc.com/editor/getting-started/configure.md)

以下是你的节点扩展的样子：

```js
import { Node } from '@tiptap/core'

export default Node.create({
  // 配置 …

  addNodeView() {
    return ({ editor, node, getPos, HTMLAttributes, decorations, extension }) => {
      const dom = document.createElement('div')

      dom.innerHTML = '你好，我是一个节点视图！'

      return {
        dom,
      }
    }
  },
})
```

明白了吗？让我们看看这个如何运作。你可以随意复制下面的示例开始使用。

> **Interactive demo:** [JavaScript](https://embed.tiptap.dev/preview/GuideNodeViews/JavaScript)

这个节点视图甚至可以与编辑器进行交互。现在是时候看看它是如何建立联系的。

## 访问节点属性

编辑器会将一些有用的信息传递给你的渲染函数。其中一个是 `node` 属性。这个属性使你能够访问节点视图中的节点属性。假设你为你的节点扩展 [添加了一个属性](https://tiptap.zhcndoc.com/editor/extensions/custom-extensions/extend-existing.md#attributes) 名称为 `count`。你可以像这样访问该属性：

```js
addNodeView() {
  return ({ node }) => {
    console.log(node.attrs.count)

    // …
  }
}
```

## 更新节点属性

你甚至可以在节点视图中更新节点属性，利用传递给渲染函数的 `getPos` 属性。通过一个包含更新后属性的对象来触发新的事务：

```js
addNodeView() {
  return ({ editor, node, getPos }) => {
    const { view } = editor

    // 创建一个按钮 …
    const button = document.createElement('button')
    button.innerHTML = `这个按钮已经被点击了 ${node.attrs.count} 次。`

    // … 当它被点击时 …
    button.addEventListener('click', () => {
      if (typeof getPos === 'function') {
        // … 触发一个事务，对于文档中的当前位置 …
        view.dispatch(view.state.tr.setNodeMarkup(getPos(), undefined, {
          count: node.attrs.count + 1,
        }))

        // … 然后把焦点设置回编辑器。
        editor.commands.focus()
      }
    })

    // …
  }
}
```

这似乎有点复杂吗？如果你在项目中已经使用了 [React](https://tiptap.zhcndoc.com/editor/extensions/custom-extensions/node-views/react.md) 或 [Vue](https://tiptap.zhcndoc.com/editor/extensions/custom-extensions/node-views/vue.md)，可以考虑使用它们。使用这些框架会稍微简单一些。

## 添加可编辑内容

要向你的节点视图添加可编辑内容，你需要传递一个 `contentDOM`，这是用于内容的容器元素。以下是一个包含非可编辑和可编辑文本内容的节点视图的简化示例：

```js
// 创建节点视图的容器
const dom = document.createElement('div')

// 给其他包含文本的元素设置 `contentEditable = false`
const label = document.createElement('span')
label.innerHTML = '节点视图'
label.contentEditable = false

// 创建内容的容器
const content = document.createElement('div')

// 将所有元素附加到节点视图容器
dom.append(label, content)

return {
  // 传递节点视图容器 …
  dom,
  // … 以及内容容器：
  contentDOM: content,
}
```

明白了吗？你可以随意做任何你喜欢的事情，只要你返回一个节点视图的容器和另一个内容的容器。以下是上面示例的实际应用：

> **Interactive demo:** [JavaScriptContent](https://embed.tiptap.dev/preview/GuideNodeViews/JavaScriptContent)

请记住，这些内容是由 Tiptap 渲染的。这意味着你需要指明允许什么样的内容，比如在你的节点扩展中使用 `content: 'inline*'`（这就是我们在上面示例中使用的内容）。
