评论存档自定义 UI
默认情况下,评论存档下拉面板通过在工具栏配置中添加 'commentsArchive'
按钮显示在工具栏中。有关更多信息,请参阅 评论 指南。
在本指南中,您将学习如何在您的应用程序中准备一个自定义评论存档 UI,并在您选择的容器中显示它。
您应该只显示一个评论存档 UI 实例,以避免在多个位置使用相同的 DOM 元素。这意味着,除其他事项外,如果您为评论存档提供自己的自定义 UI,则不应该将 'commentsArchive'
按钮添加到工具栏配置中。
# 开始之前
在本指南中,将使用 CKEditor 云服务和 实时协作评论 功能。但是,评论功能 API 也可以以类似的方式与 独立评论 功能一起使用。
在继续之前,请确保您的编辑器已正确集成到评论功能中。
# 准备 HTML 结构
在本指南中,我们将准备一个带有自定义侧边栏的编辑器集成。
将有两个选项卡,允许用户在侧边栏中显示的内容之间切换。默认情况下,侧边栏将显示编辑器的常规宽侧边栏。另一个选项卡将切换侧边栏内容,以显示已解决的评论。
首先,通过扩展 div.editor-container__sidebar
容器来调整 HTML 结构
<div class="main-container">
...
<div class="editor-container" id="editor-container">
<div class="editor-container__editor-wrapper">
<div class="editor-container__editor"><div id="editor"></div></div>
<div class="editor-container__sidebar">
<div class="tabs">
<button class="tabs__item active" data-target="editor-annotations">Sidebar</button>
<button class="tabs__item" data-target="archive">Comments archive</button>
</div>
<div class="sidebar active" id="editor-annotations"></div>
<div class="sidebar sidebar--archive" id="archive">
<div class="comments-archive">
<div class="comments-archive__list"></div>
</div>
</div>
</div>
</div>
</div>
...
</div>
然后,为侧边栏添加样式
<style>
.ck.ck-toolbar_grouping {
height: 40px;
}
.editor-container__sidebar {
margin: 0;
padding: 0;
}
.sidebar {
display: none;
font-size: 20px;
padding: 0 10px 10px;
border: 1px solid #ccced1;
border-left: none;
overflow: hidden;
box-sizing: border-box;
height: 0;
}
.sidebar.active {
display: block;
min-height: calc(100% - 40px);
}
.sidebar--archive.active {
overflow: auto;
}
.comments-archive__list {
padding: 0;
margin: 0;
}
.comments-archive__list:empty:before {
display: block;
content: "There are no archived comment threads.";
margin-top: 20px;
font-size: 13px;
text-align: center;
font-style: italic;
color: #555;
}
.comments-archive__list > .ck-annotation-wrapper {
margin-top: 10px;
}
.tabs {
width: 100%;
min-height: 40px;
display: flex;
flex-direction: row;
align-items: center;
border-top: 1px solid #ccced1;
}
.tabs__item {
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
width: 100%;
height: 100%;
min-height: 40px;
border: 1px solid #ccced1;
border-width: 0 1px;
opacity: 0.5;
box-sizing: border-box;
padding: 0;
}
.tabs__item:first-child {
border-left: none;
}
.tabs__item.active {
background: #fff;
opacity: 1.0;
}
</style>
# 实现自定义评论存档 UI 插件
现在,创建一个插件,它将使用提供的 HTML 结构,并使用已解决的评论线程填充评论存档容器。
选项卡的行为将作为简单的 DOM 事件监听器来实现。
您可以观察 CommentsArchiveUI#annotationViews
集合上的更改,以填充评论存档选项卡内容。
此外,为了获得更好的用户体验,只要在侧边栏中显示评论存档,常规评论线程的批注将以内联显示模式显示。这将使用户在存档打开时也能访问常规评论线程数据。
class CustomCommentsArchiveUI extends Plugin {
static get requires() {
// We will use a property from the `CommentsArchiveUI` plugin, so add it to requires.
return [ 'CommentsArchiveUI' ];
}
init() {
this.tabs = document.querySelectorAll( '.tabs__item' );
this.sidebars = document.querySelectorAll( '.sidebar' );
// Switch the side panel to the appropriate tab after clicking it.
this.tabs.forEach( item => {
item.addEventListener( 'click', () => this.handleTabClick( item ) );
} );
this.initCommentsArchive();
}
// Switches between the active tabs.
// Shows appropriate tab container and set the CSS classes to reflect the changes.
handleTabClick( tabElement ) {
if ( tabElement.classList.contains( 'active' ) ) {
return;
}
const annotationsUIs = this.editor.plugins.get( 'AnnotationsUIs' );
const targetId = tabElement.dataset.target;
const sidebarContainer = document.getElementById( targetId );
this.tabs.forEach( item => {
item.classList.remove( 'active' );
} );
this.sidebars.forEach( item => {
item.classList.remove( 'active' );
} );
tabElement.classList.add( 'active' );
sidebarContainer.classList.add( 'active' );
const isCommentsArchiveOpen = targetId === 'archive';
// If the comments archive is open, switch the display mode for comments to "inline".
//
// This way the annotations for regular comments threads will be displayed next to them
// when a user clicks on the comment thread marker.
//
// When the comments archive is closed, switch back to displaying comments annotations in the wide sidebar.
annotationsUIs.switchTo( isCommentsArchiveOpen ? 'inline' : 'wideSidebar' );
}
initCommentsArchive() {
// Container for the resolved comment threads annotations.
const commentsArchiveList = document.querySelector( '.comments-archive__list' );
// The `CommentsArchiveUI` plugin handles all annotation views that can be used
// to render resolved comment threads inside the comments archive container.
const commentsArchiveUI = this.editor.plugins.get( 'CommentsArchiveUI' );
// First, handle the initial resolved comment threads.
for ( const annotationView of commentsArchiveUI.annotationViews ) {
commentsArchiveList.appendChild( annotationView.element );
}
// Handler to append new resolved thread inside the comments archive custom view.
commentsArchiveUI.annotationViews.on( 'add', ( _, annotationView ) => {
if ( !commentsArchiveList.contains( annotationView.element ) ) {
commentsArchiveList.appendChild( annotationView.element );
}
} );
// Handler to remove the element when thread has been removed or reopened.
commentsArchiveUI.annotationViews.on( 'remove', ( _, annotationView ) => {
if ( commentsArchiveList.contains( annotationView.element ) ) {
commentsArchiveList.removeChild( annotationView.element );
}
} );
}
}
最后,将新插件添加到编辑器中。
ClassicEditor
.create( document.querySelector( '#editor' ), {
// ...
plugins: [
// ...
CustomCommentsArchiveUI
]
} )
.then( /* ... */ )
.catch( /* ... */ );
# 演示
与您的同事共享此页面的完整 URL,以便实时协作!
点击工具栏中的“添加评论”按钮
添加评论线程,然后使用“勾号”图标 解决评论线程。最后,您可以在“评论存档”选项卡中看到已解决的评论线程。我们每天都在努力使我们的文档保持完整。您是否发现过时的信息?是否缺少内容?请通过我们的 问题跟踪器 报告。
随着版本 42.0.0 的发布,我们重新编写了许多文档,以反映新的导入路径和功能。我们感谢您的反馈,帮助我们确保文档的准确性和完整性。