Skip to content

Repository files navigation

Marquee Selector

npm version License: MIT

🎮 Demo

體驗線上 Demo:Marquee Selector Demo

✨ 特性

  • 🎯 框架無關:純 Vanilla JavaScript 實現,可在任何前端框架中使用
  • 🎨 多目標支援:可同時追蹤多組不同的選取目標,各有獨立的回調
  • 🛡️ 智能保護機制:
    • 自動保護可拖拽元素(draggable="true")
    • 保護文字選取區域(input、textarea、contenteditable 等)
  • 🔄 完整生命週期:提供 onSelectionStart、onSelectionChange、onSelectionEnd、onClearClick 回調
  • 📍 精確碰撞檢測:支援滾動容器,使用 AABB 算法進行精確的碰撞檢測
  • 💾 記憶體優化:使用 WeakMap 快取選取狀態,避免記憶體洩漏
  • 🎨 CSS 可定制:通過 CSS 變數輕鬆定制外觀

📦 安裝

npm install @hardanonymous/marquee-selector

或使用 yarn:

yarn add @hardanonymous/marquee-selector

🚀 快速開始

import { MarqueeSelector } from "@hardanonymous/marquee-selector";
import "@hardanonymous/marquee-selector/style.css";

// 1. 初始化
const marquee = new MarqueeSelector({
  container: document.body,
});

// 2. 添加目標配置
marquee.addTarget({
  selector: ".item",
  onSelectionChange: (elements) => {
    console.log("選取變化:", elements);
    elements.forEach((el) => el.classList.add("selected"));
  },
  onClearClick: (elements) => {
    console.log("清除選取");
    elements.forEach((el) => el.classList.remove("selected"));
  },
});

// 3. 啟用框選
marquee.enable();

📚 使用範例

Vue 3

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue";
import { MarqueeSelector } from "@hardanonymous/marquee-selector";
import "@hardanonymous/marquee-selector/style.css";

const containerRef = ref<HTMLElement>();
const selectedIds = ref<number[]>([]);
let marquee: MarqueeSelector | null = null;

onMounted(() => {
  if (containerRef.value) {
    marquee = new MarqueeSelector({
      container: containerRef.value,
    });

    marquee.addTarget({
      selector: ".item",
      onSelectionChange: (elements) => {
        selectedIds.value = elements.map((el) =>
          Number(el.getAttribute("data-id"))
        );
      },
    });

    marquee.enable();
  }
});

onUnmounted(() => {
  marquee?.destroy();
});
</script>

<template>
  <div ref="containerRef">
    <div
      v-for="item in items"
      :key="item.id"
      :data-id="item.id"
      class="item"
      :class="{ selected: selectedIds.includes(item.id) }"
    >
      {{ item.name }}
    </div>
  </div>
</template>

React

import { useEffect, useRef, useState } from "react";
import { MarqueeSelector } from "@hardanonymous/marquee-selector";
import "@hardanonymous/marquee-selector/style.css";

function App() {
  const containerRef = useRef<HTMLDivElement>(null);
  const [selectedIds, setSelectedIds] = useState<number[]>([]);

  useEffect(() => {
    if (!containerRef.current) return;

    const marquee = new MarqueeSelector({
      container: containerRef.current,
    });

    marquee.addTarget({
      selector: ".item",
      onSelectionChange: (elements) => {
        const ids = elements.map((el) => Number(el.getAttribute("data-id")));
        setSelectedIds(ids);
      },
    });

    marquee.enable();

    return () => marquee.destroy();
  }, []);

  return (
    <div ref={containerRef}>
      {items.map((item) => (
        <div
          key={item.id}
          data-id={item.id}
          className={`item ${selectedIds.includes(item.id) ? "selected" : ""}`}
        >
          {item.name}
        </div>
      ))}
    </div>
  );
}

📖 完整文檔

查看 完整文檔 了解:

  • 詳細的 API 參考
  • 進階使用方式
  • 與拖拽功能整合
  • 工作原理說明
  • 效能優化建議
  • 常見問題解答

🎨 自定義樣式

通過 CSS 變數自定義框選框外觀:

:root {
  --marquee-border-width: 2px;
  --marquee-border-style: dashed;
  --marquee-border-color: #ff0000;
  --marquee-bg-color: rgba(255, 0, 0, 0.15);
  --marquee-z-index: 10000;
}

🤝 貢獻

歡迎提交 Issue 和 Pull Request!

📄 授權

MIT License - 詳見 LICENSE 文件

🔗 相關連結

About

MarqueeSelector 是一個框架無關的 JavaScript/TypeScript 框選工具,允許使用者通過滑鼠拖曳選取頁面上的元素。它提供了高度的靈活性和可定制性,支援多個目標配置、文字選取保護、拖拽元素保護等功能。

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages