Skip to content

Auto-Plugin/autoTeleport

Repository files navigation

DOM Teleport

🚀 一个轻量级的 JavaScript 库,用于在 DOM 中传送(移动)元素,同时保留其响应式绑定和事件监听器。

✨ 特性

  • 🎯 保留响应式绑定 - 移动 DOM 元素而不是复制,保留 Vue/React 等框架的响应式绑定
  • 🔄 支持回退 - 可以轻松将元素放回原位
  • 📦 灵活的 API - 支持类实例和便捷函数两种调用方式
  • 🎨 多种插入位置 - 支持 append、prepend、before、after
  • 🔍 智能元素查找 - 自动支持 ID、选择器和 DOM 元素
  • ⛓️ 链式调用 - 流畅的 API 设计
  • 🐛 调试模式 - 内置调试日志功能

📁 项目结构

dom-teleport/
├── src/
│   ├── core/
│   │   ├── DomTeleport.js      # 核心类
│   │   └── constants.js        # 常量和枚举
│   ├── utils/
│   │   └── helpers.js          # 工具函数
│   └── main.js                 # 主入口文件
├── test/
│   └── index.test.html         # 测试文件
├── examples/
│   ├── index.html              # 示例导航
│   ├── demo.html               # 原生 JS 示例
│   ├── vue-demo.html           # Vue 3 示例
│   └── react-demo.html         # React 18 示例
└── dist/                       # 构建输出
    ├── index.js                # CommonJS 格式
    └── index.esm.js            # ES Module 格式

🧪 在线示例

examples/ 目录下提供了多个示例:

  1. index.html - 示例导航页
  2. demo.html - 原生 JavaScript 基础示例
  3. vue-demo.html - Vue 3 响应式测试
  4. react-demo.html - React 18 状态测试

运行示例

# 克隆仓库
git clone https://github.com/wenps/dom-teleport.git
cd dom-teleport

# 构建项目
npm install
npm run build

# 使用任意 HTTP 服务器运行
# 方式 1: 使用 Python
python3 -m http.server 8000

# 方式 2: 使用 Node.js http-server
npx http-server

# 然后访问 http://localhost:8000/examples/

📦 安装

�📦 安装

npm install dom-teleport

或使用 yarn:

yarn add dom-teleport

🚀 快速开始

基础用法

import DomTeleport from 'dom-teleport';

// 通过 ID 传送元素
const teleporter = new DomTeleport('myElement');
teleporter.appendTo('targetContainer');

// 放回原位
teleporter.back();

使用便捷函数

import { teleport, TeleportPosition } from 'dom-teleport';

// 快速传送
teleport('myElement', 'targetContainer');

// 指定位置
teleport('myElement', 'targetContainer', TeleportPosition.PREPEND);

📖 详细使用说明

1. 类实例化方式(推荐)

创建实例

import DomTeleport from 'dom-teleport';

// 通过 ID 创建
const teleporter = new DomTeleport('myElement');

// 通过选择器创建
const teleporter = new DomTeleport('.my-class');
const teleporter = new DomTeleport('#myElement');

// 通过 DOM 元素创建
const element = document.getElementById('myElement');
const teleporter = new DomTeleport(element);

// 开启调试模式
const teleporter = new DomTeleport('myElement', { debug: true });

传送方法

// 追加到目标元素内部末尾
teleporter.appendTo('targetContainer');

// 插入到目标元素内部开头
teleporter.prependTo('targetContainer');

// 插入到目标元素之前
teleporter.insertBefore('targetElement');

// 插入到目标元素之后
teleporter.insertAfter('targetElement');

// 通用方法(可指定位置)
import { TeleportPosition } from 'dom-teleport';
teleporter.to('targetContainer', TeleportPosition.APPEND);

回退和重置

// 放回原位
teleporter.back();

// 以当前位置为新的原始位置
teleporter.resetOriginalPosition();

链式调用

new DomTeleport('myElement')
  .appendTo('container1')
  .back()
  .prependTo('container2')
  .resetOriginalPosition()
  .insertAfter('sibling');

获取元素和销毁

// 获取源元素
const element = teleporter.getElement();

// 销毁实例(清理引用)
teleporter.destroy();

2. 便捷函数方式

import { teleport, TeleportPosition } from 'dom-teleport';

// 基础用法(默认 append)
const instance = teleport('source', 'target');

// 指定位置
teleport('source', 'target', TeleportPosition.PREPEND);
teleport('source', 'target', TeleportPosition.BEFORE);
teleport('source', 'target', TeleportPosition.AFTER);

// 可以继续操作返回的实例
instance.back();

3. 传送位置枚举

import { TeleportPosition } from 'dom-teleport';

TeleportPosition.APPEND   // 追加到目标元素内部末尾
TeleportPosition.PREPEND  // 插入到目标元素内部开头
TeleportPosition.BEFORE   // 插入到目标元素之前
TeleportPosition.AFTER    // 插入到目标元素之后

🎯 实际应用场景

场景 1: Vue 组件传送

import DomTeleport from 'dom-teleport';

// 在 Vue 组件中传送元素到 body,保留响应式绑定
export default {
  mounted() {
    this.teleporter = new DomTeleport(this.$refs.modal);
    this.teleporter.appendTo(document.body);
  },
  beforeUnmount() {
    this.teleporter.back();
    this.teleporter.destroy();
  }
}

场景 2: React 组件传送

import { useEffect, useRef } from 'react';
import DomTeleport from 'dom-teleport';

function Modal() {
  const modalRef = useRef(null);
  
  useEffect(() => {
    const teleporter = new DomTeleport(modalRef.current);
    teleporter.appendTo(document.body);
    
    return () => {
      teleporter.back();
      teleporter.destroy();
    };
  }, []);
  
  return <div ref={modalRef}>Modal Content</div>;
}

场景 3: 动态工具栏

import DomTeleport from 'dom-teleport';

const toolbar = new DomTeleport('toolbar', { debug: true });

// 根据上下文切换工具栏位置
function switchContext(context) {
  if (context === 'editor') {
    toolbar.appendTo('editor-container');
  } else if (context === 'preview') {
    toolbar.appendTo('preview-container');
  } else {
    toolbar.back(); // 恢复到原始位置
  }
}

场景 4: 拖拽排序

import DomTeleport from 'dom-teleport';

let currentTeleporter = null;

function onDragStart(element) {
  currentTeleporter = new DomTeleport(element);
}

function onDrop(targetElement, position) {
  if (currentTeleporter) {
    if (position === 'before') {
      currentTeleporter.insertBefore(targetElement);
    } else {
      currentTeleporter.insertAfter(targetElement);
    }
    currentTeleporter.resetOriginalPosition(); // 重置为新位置
  }
}

function onDragCancel() {
  if (currentTeleporter) {
    currentTeleporter.back(); // 取消拖拽,放回原位
    currentTeleporter.destroy();
  }
}

场景 5: 响应式布局切换

import DomTeleport from 'dom-teleport';

const sidebar = new DomTeleport('sidebar');

function handleResize() {
  if (window.innerWidth < 768) {
    // 移动端:侧边栏移到主内容下方
    sidebar.insertAfter('main-content');
  } else {
    // 桌面端:侧边栏回到原位
    sidebar.back();
  }
}

window.addEventListener('resize', handleResize);
handleResize();

🔍 元素查找逻辑

DomTeleport 使用智能查找逻辑来定位元素:

  1. 如果传入的是 HTMLElement,直接使用
  2. 如果传入的是字符串:
    • 首先尝试通过 document.getElementById() 查找(当做 ID)
    • 如果找不到,再通过 document.querySelector() 查找(当做选择器)
// 以下都是有效的调用方式
new DomTeleport('myId');              // ID
new DomTeleport('#myId');             // 选择器
new DomTeleport('.my-class');         // 选择器
new DomTeleport('[data-role="btn"]'); // 选择器
new DomTeleport(domElement);          // DOM 元素

⚠️ 注意事项

  1. 原始位置保存: 创建实例时会自动保存元素的原始位置,包括父节点和相邻兄弟节点
  2. 响应式绑定: 由于使用的是 DOM 移动而非克隆,所有事件监听器和框架绑定都会保留
  3. 错误处理: 所有方法都会在出错时抛出异常,建议使用 try-catch 包裹
  4. 内存管理: 不再使用时应调用 destroy() 方法清理引用

📝 API 参考

DomTeleport 类

构造函数

new DomTeleport(source: string | HTMLElement, options?: {
  debug?: boolean
})

实例方法

  • to(target, position) - 传送到指定位置
  • appendTo(target) - 追加到目标元素内部末尾
  • prependTo(target) - 插入到目标元素内部开头
  • insertBefore(target) - 插入到目标元素之前
  • insertAfter(target) - 插入到目标元素之后
  • back() - 放回原位
  • resetOriginalPosition() - 重置原始位置
  • getElement() - 获取源元素
  • destroy() - 销毁实例

实例属性

  • sourceElement - 源 DOM 元素
  • isTeleported - 是否已传送
  • debug - 是否开启调试模式

便捷函数

teleport(
  source: string | HTMLElement,
  target: string | HTMLElement,
  position?: TeleportPosition
): DomTeleport

枚举

TeleportPosition {
  APPEND = 'append',
  PREPEND = 'prepend',
  BEFORE = 'before',
  AFTER = 'after'
}

🤝 贡献

欢迎提交 Issue 和 Pull Request!

📄 许可证

MIT License

🎉 致谢

感谢所有贡献者和使用者!

About

一个简单的传送框组件

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published