| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- // 右键菜单模块(复制自 client/js/disk/right-click-menu.js)
- (() => {
- class ResourceManagerRightClickMenu {
- constructor(options = {}) {
- this.target = options.target || document.body;
- this.menu = options.menu || null;
- this.onAction = options.onAction || (() => {});
- this.onBeforeShow = options.onBeforeShow || null;
- this.lastRightClickTarget = null;
- this.handleContextMenu = this.handleContextMenu.bind(this);
- this.handleDocumentClick = this.handleDocumentClick.bind(this);
- this.handleKeydown = this.handleKeydown.bind(this);
- this.bindEvents();
- }
- bindEvents() {
- if (!this.target || !this.menu) {
- console.error('[RightClickMenu] 缺少 target 或 menu 元素', { target: this.target, menu: this.menu });
- return;
- }
- this.target.addEventListener('contextmenu', this.handleContextMenu);
- document.addEventListener('click', this.handleDocumentClick);
- document.addEventListener('keydown', this.handleKeydown);
- this.menu.addEventListener('click', (e) => {
- const btn = e.target.closest('[data-action]');
- if (!btn) return;
- const action = btn.dataset.action;
- this.hide();
- this.onAction(action, e);
- });
- }
- handleContextMenu(e) {
- const editable = e.target.closest('input, textarea');
- if (editable) {
- return;
- }
- e.preventDefault();
-
- // 保存右键点击的目标元素
- this.lastRightClickTarget = e.target;
-
- // 如果有回调,在显示菜单前调用
- // 如果回调返回 false,不显示菜单
- if (this.onBeforeShow) {
- const shouldShow = this.onBeforeShow(e);
- if (shouldShow === false) {
- return;
- }
- }
-
- this.show(e.clientX, e.clientY);
- }
- handleDocumentClick(e) {
- // 点击重命名输入框时不隐藏菜单
- if (e.target.classList.contains('rename-input')) {
- return;
- }
- if (this.menu && !this.menu.contains(e.target)) {
- this.hide();
- }
- }
- handleKeydown(e) {
- if (e.key === 'Escape') {
- this.hide();
- }
- }
- show(x, y) {
- if (!this.menu) return;
- this.menu.classList.add('show');
- const { innerWidth, innerHeight } = window;
- const rect = this.menu.getBoundingClientRect();
- let left = x;
- let top = y;
- if (left + rect.width > innerWidth) {
- left = innerWidth - rect.width - 8;
- }
- if (top + rect.height > innerHeight) {
- top = innerHeight - rect.height - 8;
- }
- this.menu.style.left = `${left}px`;
- this.menu.style.top = `${top}px`;
- }
- hide() {
- if (this.menu) {
- this.menu.classList.remove('show');
- }
- }
- }
- window.ResourceManagerRightClickMenu = ResourceManagerRightClickMenu;
- })();
|