一个能够被拖动的元素。
使用CDK拖放中的示例,我想添加左侧和顶部位置的拖动元素的预览,而无需变换样式。 超文本标记语言 ... 使用 CDK 拖放中的示例,我想添加左侧和顶部位置的拖动元素的预览,而无需变换样式。 HTML <div class="example-boundary"> <div class="example-box" cdkDragBoundary=".example-boundary" cdkDrag> I can only be dragged within the dotted container </div> </div> <button> Preview the dragged element </buttona> 打字稿 import {Component} from '@angular/core'; import {CdkDrag} from '@angular/cdk/drag-drop'; /** * @title Drag&Drop boundary */ @Component({ selector: 'cdk-drag-drop-boundary-example', templateUrl: 'cdk-drag-drop-boundary-example.html', styleUrls: ['cdk-drag-drop-boundary-example.css'], standalone: true, imports: [CdkDrag], }) export class CdkDragDropBoundaryExample {} 现状 当你拖动元素时,DOM 中就会有这个 div <div _ngcontent-ng-c2320506461="" class="example-boundary"> <div _ngcontent-ng-c2320506461="" cdkdragboundary=".example-boundary" cdkdrag="" class="cdk-drag example-box" style="transform: translate3d(202px, -2px, 0px);"> I can only be dragged within the dotted container </div> </div> 预期结果 当您拖动元素并单击预览按钮时,它应该打开预览元素,如下所示。 <div class="example-boundary"> <div class="example-box" style="left: 96.13%; top: 9.92%; display: block;"> Now I can't be dragged, sorry </div> </div> 意味着变换样式应该替换为左侧和顶部位置。 @angular/cdk/drag-drop内部使用变换属性来放置盒子。无论是使用top、left和position属性还是在封装的内部细节中使用transform,都应该理解为封装。使用这两种方法都可以获得相同的结果。如果您想对 top 和 left 属性执行任何特定操作,您可以根据 transform 和元素原始位置或纯 JS 中的代码拖动功能来计算它们。 以下是你想要做的纯JS版本。 const box = document.querySelector('.example-box'); const boundary = document.querySelector(box.getAttribute('cdkDragBoundary') || ''); const posDisplay = document.querySelector('#pos'); const offset = { x: 0, y: 0 }; const onMouseMove = (e) => { e.preventDefault(); const [cx, cy] = [e.clientX, e.clientY]; const { width, height } = box.getBoundingClientRect(); let top = cy - offset.y; let left = cx - offset.x; const { width: bw, height: bh } = boundary?.getBoundingClientRect(); top = Math.min(top, (bh || innerHeight) - height); top = Math.max(top, 0); left = Math.min(left, (bw || innerWidth) - width); left = Math.max(left, 0); box.style.top = top + 'px'; box.style.left = left + 'px'; posDisplay.innerText = `left: ${left}px, top: ${top}px`; }; box.onmousedown = e => { e.preventDefault(); offset.x = e.clientX - box.offsetLeft; offset.y = e.clientY - box.offsetTop; window.onmousemove = onMouseMove; window.onmouseup = () => { window.onmousemove = null; window.onmouseup = null; }; } .example-boundary { position: relative; border: 1px dotted gray; width: 80vw; height: 80vh; margin: 0 10vmin; } .example-box { position: absolute; width: 200px; padding: 10px; border-radius: 10px; border: 1px solid green; cursor: grab; } #pos { height: 50px; padding: 0 10px; } <p id="pos">left: 0, top: 0</p> <div class="example-boundary"> <div class="example-box" cdkDragBoundary=".example-boundary"> I can only be dragged within the dotted container </div> </div> TLDR; 我制作了以下两个工作示例,可以满足您的要求。在这两种情况下,top 和 left 位置都是使用以下 正则表达式 通过捕获组 1 和 2 transform:\s*translate3d\((.+?),(.+?),.+?\) 来计算的。 克隆 DOM,这是我推荐的答案,它克隆 Angular 生成的 HTML 并手动删除不需要的属性。 存储数据,按照您的要求,它将 DOM 位置、宽度、高度等存储在变量中,然后进行渲染。 方法#1(克隆 DOM) 以下代码克隆 Angular 生成的 HTML 并手动删除不需要的属性。代码中的注释中有更多详细信息。 如果您只是想重新渲染拖到其他地方的内容,我个人建议使用此方法,因为它消除了管理属性的复杂性。 TS: /** * 1. Added a flag called `isPreviewShown` which toggles which HTML is visible, either the preview or the original * 2. Added a method called `showPreview` which clones the draggable contents and then manually removes unwanted attributes (you'll have to maintain this logic, so you may remove other attributes you don't need) * 3. Replaced `cssText` style attributes from `translate3d` to `top/left` values. I used the following [regular expression][2] for it `transform:\s*translate3d\((.+?),(.+?),.+?\)` and the replaced it to `left:$1; top:$2` **/ isPreviewShown = false; showPreview() { // clone the contents this.previewContainer.nativeElement.innerHTML = this.exampleBoundary.nativeElement.innerHTML; // clear unwanted attributes document.querySelectorAll('.preview-container *').forEach((content: HTMLElement) => { const attrs = content.getAttributeNames(); for (var attr in attrs) { if ( attrs[attr].indexOf('cdk') !== -1 // <-- remove cdk related attributes || attrs[attr].indexOf('_ng') === 0 // <-- remove angular relates attributes || attrs[attr].indexOf('ng-') === 0 // <-- remove more angular relates attributes ) { console.log('->> removed: ', attrs[attr]) content.removeAttribute(attrs[attr]); } } // transform/translate3d --> top/left content.style.cssText = content.style.cssText.replace(/transform:\s*translate3d\((.+?),(.+?),.+?\)/i, 'left:$1; top:$2') // remove cdk-drag class content.classList.remove('cdk-drag') }); console.log('>> Result: ', this.previewContainer.nativeElement.innerHTML) // show the preview this.isPreviewShown = true; this.cdr.detectChanges(); } HTML: <!-- 1. Added a `preview-container` which is where the preview is going to be shown 2. Added a `main-container` which is meant to make the `preview` to overlap the original content 3. Added an extra button called "Hide preview element" which hides the preview so you can drag again --> <div class="main-container"> <div class="example-boundary" #exampleBoundary> <div class="example-box" cdkDragBoundary=".example-boundary" cdkDrag> I can only be dragged within the dotted container </div> </div> <div class="preview-container example-box" #previewContainer [hidden]="!isPreviewShown"> </div> </div> <br> <button (click)="hidePreview()" [hidden]="!isPreviewShown"> Hide preview element </button> <button (click)="showPreview()" [hidden]="isPreviewShown"> Preview the dragged element </button> CSS: /** * 1. Add `position: relative` to the `main-container` so the `preview-container` size and position are shown relative to the main container. * 2. Had to add `:host ::ng-deep` to class `.example-box` so the CSS can be shared by both preview and original content (an alternative to this, is to set all style attributes inline by using [`ngStyle`][4] so you'll don't need a css class) */ :host ::ng-deep .example-box { /* no changes here */ } .main-container { position: relative; width: 400px; height: 400px; } .preview-container { position: absolute; background: white; width: 100%; height: 100%; top: 0px; left: 0px; z-index: 1; } 方法#2(存储数据) 这种方法完全按照您在注释中的要求,它将 DOM 位置、宽度、高度等存储在变量中,然后通过迭代变量来渲染它。 如果您稍后要操作单个项目(例如添加拖动时不存在的可配置内容),那么这种方法会比 #1 更好。 TS: /** * 1. Added an interface called `IDragAndDropItem` with all the attributes that are going to be stored. * 2. Added a flag called `isPreviewShown` which toggles which HTML is visible, either the preview or the original * 3. Added a method called `showPreview` which iterates the first DOM level and stores the desired attributes in the array `previewItems` * 4. Computed the `top` and `left` values from the `cssText` style attribute, matched the following [regular expression][2] captured group 1 and 2: `transform:\s*translate3d\((.+?),(.+?),.+?\)` */ export interface IDragAndDropItem { width: string; height: string; left: string | null; top: string | null; text: string; } isPreviewShown = false; previewItems: Array<IDragAndDropItem> = []; showPreview() { this.previewItems = []; // save the contents document .querySelectorAll('.example-boundary > *') // <-- purposely doesn't support nested DOM .forEach((content: HTMLElement) => { const position = content.style.cssText.match( /transform:\s*translate3d\((.+?),(.+?),.+?\)/i ); this.previewItems.push({ width: content.offsetWidth + 'px', height: content.offsetHeight + 'px', left: position ? position[1] || null : null, top: position ? position[2] || null : null, text: content.innerText }) }); // show the preview this.isPreviewShown = true; this.cdr.detectChanges(); // show html this.resultHtml.nativeElement.innerText = this.previewContainer.nativeElement.innerHTML; } HTML: <!-- 1. Added a `preview-container` which is where the `previewItems` is iterated and rendered. 2. Added a `main-container` which is meant to make the `preview` to overlap the original content 3. Added an extra button called "Hide preview element" which hides the preview so you can drag again --> <div class="main-container"> <div class="example-boundary" #exampleBoundary> <div class="example-box" cdkDragBoundary=".example-boundary" cdkDrag> I can only be dragged within the dotted container </div> </div> <div class="preview-container example-boundary" #previewContainer [hidden]="!isPreviewShown"> <div class="preview-box" *ngFor="let item of previewItems" [ngStyle]="{left: item.left, top: item.top, width: item.width, height: item.height}"> {{ item.text }} </div> </div> </div> <br> <button (click)="hidePreview()" [hidden]="!isPreviewShown"> Hide preview element </button> <button (click)="showPreview()" [hidden]="isPreviewShown"> Preview the dragged element </button> CSS: /** * 1. Add `position: relative` to the `main-container` so the `preview-container` size and position are shown relative to the main container. * 2. Had to share styles from `example-box` with `preview-box`, otherwise every `style` attribute should be also stored. */ .example-box, .preview-box { /* no changes here */ } .main-container { position: relative; width: 400px; height: 400px; } .preview-container { position: absolute; background: white; width: 100%; height: 100%; top: 0px; left: 0px; z-index: 1; }
如何使用InteractJs使可拖动元素跟随触摸移动坐标上的光标
我在容器内有一个可拖动元素,并且仅限于其边界。我使用 InteractJs 来实现这个。可拖动元素默认隐藏,并在触摸开始时变得可见。 然而我...
webpack无法解析react-spring/web模块中的react-spring_core.legacy-esm.js
我的webpack.config.js const 路径 = require("路径"); const webpack = require("webpack"); const CopyWebpackPlugin = require("copy-webpack-plugin"); const googleConfig = r...
我有以下代码,在检测 mousedown 和 mouseup 时有效。问题始于 mouseup,我试图检查目标元素是否具有特定的类。 t内的代码...
我想使用 OwlCarousel,并且使用了 OwlCarousel 网站内的 js 和 css 文件以及 cdnjs 文件,但是当我添加文件时,没有任何反应。 你能帮我一下吗,在哪里...
Shopify 可拖动库的简单“hello world”示例
寻找使用 Shopify 的 Draggable 库的一组可排序元素的简单工作示例。捆绑的示例对我来说不够简单。
我想制作一个可拖动对象的列表,就像这张图片左侧的那个: 为此,我修改了 Vue2InteractDraggable.vue 以与 VueJs3 一起使用,正如您在此代码和框中看到的那样,b ...
在 safari 中,单击已设置剪辑路径的图像时不会发出 Click 事件
我想将图像拖到设置了剪辑路径的 div 中。 当我在 Chrome 和 Firefox 浏览器中检查该图像元素上的元素时,该图像在检查元素中被选中但是......
将块从左侧容器拖到右侧容器后,它会从左侧容器中移除。如何防止从左侧容器中移除并且应该多次拖放相同......
我希望在我的 Blazor WebAssembly 组件中添加感知拖动事件的能力。我想要的真的很简单(我认为)。我不需要真正放下物品,我只需要感知 id n...
我想创建一个这样的菜单: https://www.casinofriday.com/en-row/casino 如果您使用 MDPI 屏幕查看它,您会看到它有箭头并且可以用鼠标拖动(在
Draggabilly javascript 调用函数无法识别对象
我有一个 Draggabilly 项目,定义如下; var draggie = new Draggabilly( draggableElem, { 和 draggie.on('dragEnd', function(e,p) { 然后我有许多创造价值的过程......
我正在 GPT 的帮助下构建每日计划程序。日历的每一天都分为 30 分钟间隔(时间段),我可以向每个时间段添加任务。我想在
我的网站上有一个可用的完整日历,我想实施“从外部事件拖放”。 到目前为止,一切都很好。拖放有点用。我可以在日历上删除事件。的...
在 Javascript 中触发“dragstart”后鼠标事件侦听器不工作
我目前正在开发一个拖放界面,想实现一个功能,允许用户通过右键单击将拖动的对象返回到其原始位置。 在下面的演示中,...
jqueryui draggable droppable issue
我需要一些帮助来理解这有什么问题。 当将项目放入可放置区域(模板位置)时,它会移动到另一个地方,然后当再次尝试将它拖动到正确的位置时,它...
我暂时尝试更改小部件类型,但它不起作用,我无法解决这个问题。 我的假设是,当我单击小部件时,它应该是可拖动的并且应该是拖动目标
我有这个运行良好的脚本,它做我想做的......但唯一的问题是它在快速移动 div 时滞后。 我在互联网上花了几个小时试图找到解决方案,比如添加
如何在我自己的网页中拖动和缩放一个div,就像谷歌地图一样?
我的网页中有一个固定尺寸的 div。例如:700 像素 X 500 像素。我想用鼠标放大这个 div,放大后,我想用鼠标左右移动它。实际...
sketch.com 上的这个叫什么?我如何在代码中实现它? [关闭]
元素可以在画布上任意拖动,同样我想实现一个像miro boards这样的画布页面,可以在画布中水平和垂直拖动滚动条。 我没试过