CP측 드래그 앤 드롭은 jquery를 통해 쉽게 구현할 수 있습니다. 하지만 모바일에서는 잘 작동하지 않습니다. 그래서 모바일 단말기에서 드래그 앤 드롭 데모를 작성했습니다. 주로 사용되는 이벤트는 터치 이벤트(touchstart, touchmove 및 touchend)입니다.
이 데모에서 구현된 기능은 드래그할 수 있는 요소(여기서는 그림)입니다. 이러한 요소는 지정된 영역(콘솔)에 도달한 후 드래그할 수 있습니다. 요소가 컨트롤에 삽입된 후, 원래 드래그된 요소는 원래 위치로 돌아가고 새 요소는 여전히 콘솔 내에서 또는 콘솔 밖으로 드래그될 수 있습니다.
이 데모에서는 ajax 모듈, 드래그 모듈, 위치 모듈이라는 세 가지 모듈이 사용됩니다. ajax 모듈은 ajax 요청을 구현하는 데 사용됩니다(모든 이미지 리소스는 ajax 요청을 통해 얻음). 드래그 모듈은 요소 드래그를 구현하는 데 사용되며 위치 모듈은 요소 위치 작업(위치 초기화, 복원, 제거 등)을 구현하는 데 사용됩니다. ). 데모의 엔트리 파일은 indx.js 이며 이전 3개의 모듈 파일은 같은 폴더에 저장되어 있습니다. 코딩이 완료되면 webpack을 통해 패키징됩니다. 개발 코드는 app 폴더에 있고, 패키지된 코드는 build 폴더에 있습니다.
1. 터치 이벤트 소개
터치 이벤트에는 touchstart, touchmove, touchend 3가지가 있습니다. 터치스타트 이벤트는 손가락이 화면을 터치할 때 발생합니다. touchmove는 손가락이 화면을 가로질러 미끄러질 때 계속 실행됩니다. 이 이벤트 중에 비활성화하면 페이지 스크롤이 방지됩니다. touchend는 손가락을 화면에서 떼면 트리거됩니다. 마우스 이벤트의 공통 속성을 제공하는 것 외에도 이러한 세 가지 터치 이벤트의 이벤트 개체에는 다음 세 가지 속성도 포함됩니다.
터치: 현재 추적되는 터치 작업을 나타내는 터치 개체 배열입니다.
TargetTouches: 이벤트 대상과 관련된 Touch 개체의 배열입니다.
changeTouches: 마지막 터치 이후 변경된 내용을 나타내는 Touch 개체의 배열입니다.
이 경우에는 뷰포트를 기준으로 터치 포인트의 위치를 가져와야 합니다. event.targetTouches[0].clientX 및 event.targetTouches[0].clientY를 사용합니다.
two.ajax 모듈 코드
var $ = require('jquery'); var ajax = { //得到可拖拽图片的初始列表 getInitImg:function(parent){ var num = 50; $.ajax({ type:"GET", async:false,//这里使用同步加载,因为要让图片加载完成后才能做其他操作 url:'/Home/picwall/index', success:function(result){ if(result.status == 1) { $.each(result.data, function (index,item) { var src = item.pic_src; var width = parseInt(item.width); var height = parseInt(item.height); var ratio = num / height; var img = $('').attr("src",src).height(num).width(parseInt(width * ratio)); parent.append(img); }); } }, dataType:'json' }); } }; module.exports = ajax;//将ajax模块暴露出来
3. 위치 모듈 코드
var $ = require('jquery'); var position = { //初始化位置,gap是一个表示元素间距的对象 init:function(parent,gap){ var dragElem = parent.children(); //确保父元素是相对定位 if(parent.css('position') !== "relative"){ parent.css('position','relative'); } parent.css({ 'width':"100%", 'z-index':'10' }); //当前列表内容的宽度 var ListWidth = 0; //位于第几列 var j = 0; dragElem.each(function(index,elem){ var curEle = $(elem); //设置元素的初始位置 curEle.css({ position:"absolute", top:gap.Y, left:ListWidth + gap.X }); //为每个元素添加一个唯一的标识,在恢复初始位置时有用 curEle.attr('index',index); //将元素的初始位置保存起来 position.coord.push({ X:ListWidth + gap.X, Y:gap.Y }); j++; //设置父元素的高度 parent.height( parseInt(curEle.css('top')) + curEle.height() + gap.Y); ListWidth = curEle.offset().left + curEle.width(); }); }, //将子元素插入到父元素中 addTo:function(child,parent,target){ //父元素在视口的坐标 var parentPos = { X:parent.offset().left, Y:parent.offset().top }; //目标位置相对于视口的坐标 var targetPos = { X:target.offset().left, Y:target.offset().top }; //确保父元素是相对定位 if(parent.css('position') !== "relative"){ parent.css({ 'position':'relative' }); } parent.css({ 'z-index':'12' }); //将子元素插入父元素中 parent.append(child); //确定子元素在父元素中的位置并且保证子元素的大小不变 child.css({ position:absolute, top:targetPos.Y - parentPos.Y, left:targetPos.X - parentPos.X, width:target.width(), height:target.height() }); }, //将元素恢复到原来的位置 restore:function(elem){ //获得元素的标识 var index = parseInt( elem.attr('index') ); elem.css({ top:position.coord[index].Y, left:position.coord[index].X }); }, //拖拽元素的初始坐标 coord:[], //判断元素A是否在元素B的范围内 isRang:function(control,dragListPar,$target){ var isSituate = undefined; if(control.offset().top > dragListPar.offset().top){ isSituate = $target.offset().top > control.offset().top && $target.offset().left > control.offset().left && ($target.offset().left + $target.width()) < (control.offset().left + control.width()); }else{ isSituate = ($target.offset().top + $target.height())<(control.offset().top + control.height()) && $target.offset().top > control.offset().top && $target.offset().left > control.offset().left && ($target.offset().left + $target.width()) < (control.offset().left + control.width()); } return isSituate; } }; module.exports = position;
4. 모듈 코드 드래그
var $ = require('jquery'); var position = require('./position.js'); var drag = { //拖拽元素的父元素的id dragParen:undefined, //操作台的id值 control:undefined, //移动块相对视口的位置 position:{ X:undefined, Y:undefined }, //触摸点相对视口的位置,在滑动过程中会不断更新 touchPos:{ X:undefined, Y:undefined }, //开始触摸时触摸点相对视口的位置 startTouchPos:{ X:undefined, Y:undefined }, //触摸点相对于移动块的位置 touchOffsetPos:{ X:undefined, Y:undefined }, //获取拖拽元素父元素id和控制台的ID的值 setID:function(dragList,control){ this.dragParent = dragList; this.control = control; }, touchStart:function(e){ var target = e.target; //阻止冒泡 e.stopPropagation(); //阻止浏览器默认的缩放和滚动 e.preventDefault(); var $target = $(target); //手指刚触摸到屏幕上时,触摸点的位置 drag.startTouchPos.X = e.targetTouches[0].clientX; drag.startTouchPos.Y = e.targetTouches[0].clientY; //触摸元素相对视口的位置 drag.position.X = $target.offset().left; drag.position.Y = $target.offset().top; //触摸点相对于视口的位置,滑动过程中不断更新 drag.touchPos.X = e.targetTouches[0].clientX; drag.touchPos.Y = e.targetTouches[0].clientY; //触摸点相对于触摸元素的位置 drag.touchOffsetPos.X = drag.touchPos.X - drag.position.X; drag.touchOffsetPos.Y = drag.touchPos.Y - drag.position.Y; //给目标元素绑定touchMove事件 $target.unbind('touchmove').on('touchmove',drag.touchMove); }, touchMove:function(e){ var target = e.target; //阻止冒泡 e.stopPropagation(); //阻止浏览器默认的缩放和滚动 e.preventDefault(); var $target = $(target); //获得触摸点的位置 drag.touchPos.X = e.targetTouches[0].clientX; drag.touchPos.Y = e.targetTouches[0].clientY; //修改移动块的位置 $target.offset({ top: drag.touchPos.Y - drag.touchOffsetPos.Y, left: drag.touchPos.X - drag.touchOffsetPos.X }); //给移动元素绑定touchend事件 $target.unbind('touchend').on('touchend',drag.touchEnd); }, touchEnd:function(e) { var target = e.target; //阻止冒泡 e.stopPropagation(); //阻止浏览器默认的缩放和滚动 e.preventDefault(); var $target = $(target); var parent = $target.parent(); //得到控制台和拖动元素列表的父元素 var control = $("#" + drag.control); var dragListPar = $('#' + drag.dragParent); //拖动元素是否位于控制台 var sitControl = position.isRang(control, dragListPar, $target); //拖动结束后,如果拖拽元素的父元素是拖拽列表 if (parent.attr('id') === drag.dragParent) { //如果元素位于控制台 if (sitControl) { var dragChild = $target.clone(); //为克隆出的元素绑定touchstart事件 dragChild.unbind('touchstart').on('touchstart',drag.touchStart); //将克隆出的元素插入到控制台 position.addTo(dragChild, control, $target); } //将原来的触摸元素恢复到初始位置 position.restore($target); } // 拖拽结束后,如果拖拽元素的父元素是控制台,并且元素拖出了控制台 if (parent.attr('id') === drag.control && !sitControl) { $target.remove(); } } }; module.exports = drag;
5. 항목 파일 index.js 코드
require('../css/base.css'); require('../css/drag.css'); var $ = require('jquery'); var drag = require('./drag.js'); var position = require('./position.js'); var ajax = require('./ajax.js'); var dragList = $('#dragList'); //可拖拽元素的水平,竖直间距 var gap = { X:20, Y:10 }; //通过ajax获取可拖拽的元素的列表 ajax.getInitImg(dragList); //初始化可拖拽元素的位置 position.init(dragList,gap); //设置控制台的高度。控制台的高度为屏幕的高度减去拖拽列表的盖度 var control = $('#control'); control.height( $(window).height() - dragList.height() ); //给每个拖动元素绑定touchstart事件 var dragElem = dragList.children(); dragElem.each(function(index,elem){ $(elem).unbind('touchstart').on('touchstart',drag.touchStart); }); //拖拽元素的父元素的id值为dragList,操作台的id值为control drag.setID('dragList','control');
6. Webpack 패키징
위의 내용은 모듈형 프로그래밍의 아이디어를 사용하여 다양한 모듈에 필요한 기능을 모두 사용할 수 있도록 작성합니다. 소개하려고 하는데 브라우저에 require 메소드에 대한 정의가 없습니다. 따라서 위 코드는 브라우저에서 직접 실행할 수 없으며 먼저 패키징해야 합니다. webpack에 대해 잘 모르시는 분들은 이 글을 참고하시면 됩니다. webpack의 구성 파일은 다음과 같습니다.
var autoHtml = require('html-webpack-plugin'); var webpack = require('webpack'); var extractTextWebpack = require('extract-text-webpack-plugin');// 这个插件可以将css文件分离出来,为css文件位于单独的文件中 module.exports = { entry:{ 'index':'./app/js/index.js', 'jquery':['jquery'] }, output:{ path:'./build/', filename:'js/[name].js' }, module:{ loaders:[ { test:/\.css/, loader:extractTextWebpack.extract('style','css') } ] }, plugins:[ new extractTextWebpack('css/[name].css',{ allChunks:true }), new webpack.optimize.CommonsChunkPlugin({ name:'jquery', filename:'js/jquery.js' }), new autoHtml({ title:"拖拽", filename:"drag.html", template:'./app/darg.html', inject:true }) ] };
위는 에디터에서 소개한 jQuery 모바일 드래그 앤 드롭(모듈형 개발)입니다. 터치 이벤트, 웹팩), 모든 분들께 도움이 되었으면 좋겠습니다. 궁금한 사항이 있으시면 메시지를 남겨주시면 에디터가 시간 맞춰 답변해드리겠습니다. 또한 PHP 중국어 웹사이트를 지원해 주신 모든 분들께 감사드립니다!
더 많은 jQuery 모바일 드래그 앤 드롭(모듈 개발, 터치 이벤트, 웹팩) 관련 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!