generated from template/vite-react-template
update temp
This commit is contained in:
202
public/drag-demo.html
Normal file
202
public/drag-demo.html
Normal file
@@ -0,0 +1,202 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Tiptap 拖拽换行演示</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.demo-container {
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.instructions {
|
||||
background: #f8fafc;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 6px;
|
||||
padding: 16px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.instructions h3 {
|
||||
margin-top: 0;
|
||||
color: #1e293b;
|
||||
}
|
||||
|
||||
.instructions ul {
|
||||
margin: 8px 0;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.instructions li {
|
||||
margin: 4px 0;
|
||||
color: #475569;
|
||||
}
|
||||
|
||||
/* 编辑器样式 */
|
||||
.tiptap {
|
||||
min-height: 300px;
|
||||
padding: 16px;
|
||||
border: 1px solid #d1d5db;
|
||||
border-radius: 6px;
|
||||
background: white;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.tiptap:focus {
|
||||
border-color: #3b82f6;
|
||||
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
||||
}
|
||||
|
||||
/* 拖拽相关样式 */
|
||||
.tiptap .ProseMirror-dropcursor {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
height: 1.2em;
|
||||
width: 2px;
|
||||
background-color: #3b82f6;
|
||||
margin-left: -1px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.tiptap .ProseMirror-gapcursor {
|
||||
display: none;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.tiptap .ProseMirror-gapcursor:after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: -2px;
|
||||
width: 20px;
|
||||
border-top: 1px solid #3b82f6;
|
||||
animation: ProseMirror-cursor-blink 1.1s steps(2, start) infinite;
|
||||
}
|
||||
|
||||
@keyframes ProseMirror-cursor-blink {
|
||||
to {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.tiptap .ProseMirror-selectednode {
|
||||
outline: 2px solid #3b82f6;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* 可拖拽块的样式 */
|
||||
.tiptap .draggable-block {
|
||||
position: relative;
|
||||
cursor: grab;
|
||||
transition: all 0.2s ease;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.tiptap .draggable-block:hover {
|
||||
background-color: rgba(59, 130, 246, 0.05);
|
||||
padding: 4px;
|
||||
margin: -4px;
|
||||
}
|
||||
|
||||
.tiptap .draggable-block:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
/* 拖拽状态下的样式 */
|
||||
.tiptap .dragging {
|
||||
opacity: 0.5;
|
||||
transform: rotate(2deg);
|
||||
background-color: rgba(59, 130, 246, 0.1);
|
||||
}
|
||||
|
||||
.tiptap .drop-target {
|
||||
background-color: rgba(59, 130, 246, 0.1);
|
||||
border: 2px dashed #3b82f6;
|
||||
border-radius: 4px;
|
||||
padding: 8px;
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
/* 段落样式 */
|
||||
.tiptap p {
|
||||
margin: 0.75em 0;
|
||||
}
|
||||
|
||||
.tiptap h1, .tiptap h2, .tiptap h3 {
|
||||
margin: 1.5em 0 0.5em 0;
|
||||
}
|
||||
|
||||
.tiptap ul, .tiptap ol {
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Tiptap 多行拖拽换行演示</h1>
|
||||
|
||||
<div class="instructions">
|
||||
<h3>🎯 使用说明</h3>
|
||||
<ul>
|
||||
<li><strong>拖拽段落:</strong> 将鼠标悬停在任何段落上,然后拖拽它到新位置</li>
|
||||
<li><strong>拖拽标题:</strong> 标题也可以拖拽重新排序</li>
|
||||
<li><strong>拖拽列表项:</strong> 列表项可以在列表内部或列表之间拖拽</li>
|
||||
<li><strong>视觉反馈:</strong> 拖拽时会有蓝色指示线显示插入位置</li>
|
||||
<li><strong>多行支持:</strong> 长段落会保持完整性,整个段落一起移动</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="demo-container">
|
||||
<div id="editor"></div>
|
||||
</div>
|
||||
|
||||
<script type="module">
|
||||
import { TextEditor } from './src/tiptap/editor.ts';
|
||||
|
||||
// 初始化编辑器
|
||||
const editor = new TextEditor();
|
||||
const editorElement = document.getElementById('editor');
|
||||
|
||||
const initialContent = `
|
||||
<h2>欢迎使用拖拽编辑器</h2>
|
||||
<p>这是第一个段落。你可以尝试拖拽这个段落到其他位置。鼠标悬停时段落会有高亮效果,然后你就可以拖拽它了。</p>
|
||||
<p>这是第二个段落,包含更多文本。这个段落演示了如何拖拽包含多行文本的段落。无论段落有多长,整个段落都会作为一个整体进行移动。</p>
|
||||
<h3>功能特点</h3>
|
||||
<ul>
|
||||
<li>支持段落拖拽重排</li>
|
||||
<li>支持标题拖拽</li>
|
||||
<li>支持列表项拖拽</li>
|
||||
<li>实时视觉反馈</li>
|
||||
</ul>
|
||||
<p>这是一个较长的段落,用来演示多行文本的拖拽功能。当你拖拽这个段落时,整个段落内容都会一起移动,包括所有的文本和格式。这样确保了内容的完整性和编辑的便利性。</p>
|
||||
<h3>试试拖拽功能</h3>
|
||||
<p>试着拖拽上面的任何段落或标题到新的位置。你会看到一个蓝色的指示线,显示内容将被插入的位置。</p>
|
||||
<p>最后一个段落。你可以将这个段落拖拽到文档的任何位置。</p>
|
||||
`;
|
||||
|
||||
editor.createEditor(editorElement, {
|
||||
html: initialContent,
|
||||
placeholder: '开始输入,或拖拽现有内容来重新排序...',
|
||||
onUpdateHtml: (html) => {
|
||||
console.log('内容更新:', html);
|
||||
}
|
||||
});
|
||||
|
||||
// 确保编辑器获得焦点
|
||||
setTimeout(() => {
|
||||
editor.foucus();
|
||||
}, 100);
|
||||
</script>
|
||||
</body>
|
||||
</html>`;
|
||||
149
public/test-drag.html
Normal file
149
public/test-drag.html
Normal file
@@ -0,0 +1,149 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>拖拽测试</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.editor-container {
|
||||
border: 2px solid #e5e7eb;
|
||||
border-radius: 8px;
|
||||
min-height: 400px;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.debug-info {
|
||||
background: #f1f5f9;
|
||||
border: 1px solid #cbd5e1;
|
||||
border-radius: 6px;
|
||||
padding: 12px;
|
||||
margin: 20px 0;
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* 确保我们的拖拽样式生效 */
|
||||
.tiptap {
|
||||
min-height: 350px;
|
||||
padding: 20px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.tiptap .draggable-block {
|
||||
position: relative;
|
||||
cursor: grab;
|
||||
transition: all 0.2s ease;
|
||||
border-radius: 4px;
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
.tiptap .draggable-block:hover {
|
||||
background-color: rgba(59, 130, 246, 0.08);
|
||||
padding: 4px 8px;
|
||||
margin: -2px -6px;
|
||||
}
|
||||
|
||||
.tiptap .draggable-block:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.tiptap .dragging {
|
||||
opacity: 0.6;
|
||||
transform: rotate(1deg);
|
||||
background-color: rgba(59, 130, 246, 0.1) !important;
|
||||
}
|
||||
|
||||
.tiptap .ProseMirror-dropcursor {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
height: 1.2em;
|
||||
width: 3px;
|
||||
background-color: #3b82f6;
|
||||
margin-left: -1px;
|
||||
z-index: 10;
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
.status {
|
||||
padding: 8px 12px;
|
||||
border-radius: 4px;
|
||||
margin: 10px 0;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.status.ready {
|
||||
background: #dcfce7;
|
||||
color: #166534;
|
||||
border: 1px solid #bbf7d0;
|
||||
}
|
||||
|
||||
.status.dragging {
|
||||
background: #fef3c7;
|
||||
color: #92400e;
|
||||
border: 1px solid #fde68a;
|
||||
}
|
||||
|
||||
.status.dropped {
|
||||
background: #dbeafe;
|
||||
color: #1e40af;
|
||||
border: 1px solid #bfdbfe;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🧪 拖拽功能测试</h1>
|
||||
|
||||
<div class="status ready" id="status">
|
||||
✅ 编辑器已就绪 - 可以开始拖拽测试
|
||||
</div>
|
||||
|
||||
<div class="debug-info" id="debug">
|
||||
等待拖拽操作...
|
||||
</div>
|
||||
|
||||
<div class="editor-container">
|
||||
<div id="editor"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 简单的调试信息显示
|
||||
function updateDebug(message) {
|
||||
document.getElementById('debug').textContent = new Date().toLocaleTimeString() + ': ' + message;
|
||||
}
|
||||
|
||||
function updateStatus(message, type = 'ready') {
|
||||
const status = document.getElementById('status');
|
||||
status.textContent = message;
|
||||
status.className = 'status ' + type;
|
||||
}
|
||||
|
||||
// 全局事件监听器来监控拖拽状态
|
||||
document.addEventListener('dragstart', () => {
|
||||
updateStatus('🟡 正在拖拽中...', 'dragging');
|
||||
updateDebug('拖拽开始');
|
||||
});
|
||||
|
||||
document.addEventListener('dragend', () => {
|
||||
updateStatus('✅ 拖拽结束', 'ready');
|
||||
updateDebug('拖拽结束');
|
||||
});
|
||||
|
||||
document.addEventListener('drop', () => {
|
||||
updateStatus('🔵 已放置', 'dropped');
|
||||
updateDebug('元素已放置');
|
||||
setTimeout(() => {
|
||||
updateStatus('✅ 编辑器已就绪 - 可以开始拖拽测试', 'ready');
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
updateDebug('页面加载完成,等待编辑器初始化...');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user