从后台拿到图片后信息后,想在前端实现拖拽改变图片顺序
首先模拟一串图片
ts:
imgarr = [
'assets/img/1.jpg',
'assets/img/2.png',
'assets/img/3.jpg',
]
html:
<div>
<div style="overflow: hidden;background:#cdcdcd" dragsortbeauty>
<div *ngFor="let img of imgarr" style="width: 200px;height: 200px; float: left; box-sizing: border-box;padding: 20px;margin-right: 30px;" >
<img src="{{img}}" style="width: 100%;height: 100%">
<div>{{img}}</div>
</div>
</div>
</div>
这样就模拟出从后台拿取数据展示在前端的样子了
然后实现拖拽排序,可以给图片添加鼠标按下抬起事件实现
html:
<img src="{{img}}" style="width: 100%;height: 100%" (mousedown)="imgmousedown(event,img)" (mouseup)="imgmouseup(img)">
ts:
upimg = ''
downimg = ''
imgmousedown(e,img) {
this.downimg = img
//防止浏览器默认行为(W3C)
if(e && e.preventDefault){
e.preventDefault();
}
//IE中组织浏览器行为
else{
window.event.returnValue=false;
return false;
}
}
imgmouseup(img) {
this.upimg = img
// 这里为排序方式 这里用的是按下鼠标图片和抬起鼠标图片相互替换
var downimgnum = 0
var upimgnum = 0
var downimgtext = ''
var upimgtext = ''
for (var i = 0; i < this.imgarr.length; i++) {
if (this.imgarr[i] === this.downimg) {
downimgnum = i
downimgtext = this.imgarr[i]
}
if (this.imgarr[i] === this.upimg) {
upimgnum = i
upimgtext = this.imgarr[i]
}
}
this.imgarr[downimgnum] = upimgtext
this.imgarr[upimgnum] = downimgtext
}
到这里拖拽排序的的效果就实现了 在一张图片上按下鼠标移动到另外一张图片松开鼠标 两图片位置会相互替换
但是因为阻止了浏览器的默认行为 拖动图片时跟随鼠标移动的半透明图片就没有了 这个可以使用指令来实现
创建指令dragsortbeauty.ts文件
import {
Directive, // 创建一个指令必须依赖这个装饰器
ElementRef, // 获取原生dom的
Input, // 接收外部数据的
Renderer2, // 渲染相关的(v4+),angular2.x 用的是Renderer(v4里面依旧标记不赞成deprecate),两者大同小异,具体看手册API的变动
HostListener, // 监听事件
} from '@angular/core';
@Directive({
selector: '[dragsortbeauty]',
})
export class dragsortinstruct {
public div: HTMLDivElement;
// 判断是否按下鼠标
isDown = false
constructor(
private el: ElementRef,
private r2: Renderer2
) {
}
CheckContentType(src,x,y) {
this.div = this.r2.createElement('div');
// 往当前指令绑定的元素添加一个div的子元素
this.r2.appendChild(this.el.nativeElement, this.div);
// 设置div相关的样式
this.r2.setStyle(this.div, 'position', 'fixed');
this.r2.setStyle(this.div, 'width', '160px');
this.r2.setStyle(this.div, 'height', '160px');
this.r2.setStyle(this.div, 'top', (y-100)+'px');
this.r2.setStyle(this.div, 'left', (x-100)+'px');
this.r2.setStyle(this.div, 'background-image', 'url("'+src+'")');
this.r2.setStyle(this.div, 'background-size', '100% 100%');
this.r2.setStyle(this.div, 'background-position', 'center');
this.r2.setStyle(this.div, 'display', 'block');
this.r2.setStyle(this.div, 'pointer-events', 'none');
this.r2.setStyle(this.div, 'opacity', '.5');
this.r2.addClass(this.div, 'createHoverDiv');
}
// 鼠标按下事件
@HostListener('mousedown', ['$event']) mymousedown(btn: any) {
var x = btn.x
var y = btn.y
// 如果鼠标按下位置是图片位置 创建元素
if (btn.target.classList[0] === 'dsimg') {
this.CheckContentType(btn.target.currentSrc,x,y);
this.isDown = true
}
}
// 鼠标移动事件
@HostListener('mousemove', ['$event']) onMousemove(btn: any){
//判断该元素是否被点击了
if(this.isDown) {
console.log(btn)
// 鼠标移动时创建的元素移动
this.r2.setStyle(this.div, 'top', (btn.y-100)+'px');
this.r2.setStyle(this.div, 'left', (btn.x-100)+'px');
}
}
@HostListener('document:mouseup', ['$event']) mymouseup(btn: any) { // 鼠标抬起事件
// 鼠标抬起时删除添加的元素
if(this.isDown){
this.isDown = false
this.r2.removeChild(this.el.nativeElement, this.div);
}
}
}
在app.modules.ts中引入指令
import { dragsortinstruct } from './dragsort/dragsortinstruct';
@NgModule({
declarations: [
dragsortinstruct,
],
...
})
export class AppModule { }
在html中使用指令dragsortbeauty 并给图片指定class名dsimg(用于在指令中判断是否在图片上按下鼠标)
<div>
<div style="overflow: hidden;background:#cdcdcd" dragsortbeauty>
<div *ngFor="let img of imgarr" style="width: 200px;height: 200px; float: left; box-sizing: border-box;padding: 20px;margin-right: 30px;" >
<img src="{{img}}" style="width: 100%;height: 100%" (mousedown)="imgmousedown(event,img)" (mouseup)="imgmouseup(img)" class="dsimg">
<div>{{img}}</div>
</div>
</div>
</div>
这时在图片上按下鼠标拖动时 会有一个半透明图片给随鼠标移动 鼠标抬起消失