English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

jQuery mobile drag and drop (modular development, touch event, webpack)

It is easy to implement drag and drop on the CP side with jQuery. However, it is not very useful on mobile devices. So, I wrote a drag and drop demo for mobile devices myself, mainly using touch events (touchstart, touchmove, and touchend).

The function implemented by this demo is: the draggable elements (in this case, images) are located in the list, and these elements can be dragged to the specified area. After reaching the specified area (console), the element is inserted into the console, the original dragging element returns to its original position, and the new element can still be dragged in the console and can also be dragged out of the console.

In this demo, there are three modules, namely the AJAX module, the drag module, and the position module. The AJAX module is used to implement AJAX requests (all image resources are obtained through AJAX requests), the drag module is used to implement element dragging, and the position module is used to implement element position operations (such as initialization, recovery, and removal). The entry file of the demo is indx.js, and the three module files are stored in the same folder. After coding is completed, it is packaged through webpack. The development code is located in the app folder, and the packaged code is located in the build folder.

1. Introduction to touch events

There are three touch events, namely touchstart, touchmove, and touchend. The touchstart event is triggered when a finger touches the screen. touchmove is triggered continuously when a finger slides on the screen. During this event, canceling its default can prevent page scrolling. touchend is triggered when a finger leaves the screen. In addition to providing common mouse event properties, the event objects of these three touch events also include the following three properties:

    touches: an array of touch objects representing the current tracked touch operation.

  targetTouches: an array of Touch objects specific to the event target.

  changeTouches: an array of Touch objects representing what has changed since the last touch.

In this case, we need to get the position of the touch point relative to the viewport, and I use event.targetTouches[0].clientX and event.targetTouches[0].clientY

The code of the second ajax module

var $ = require('jquery');
var ajax = {
//Get the initial list of draggable images
getInitImg: function(parent) {
var num = 50;
$.ajax({
type: "GET",
async: false,//Here we use synchronous loading because we need to wait for the image to load before performing other operations
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;//Expose the ajax module

Three, the code of the position module

var $ = require('jquery');
var position = {
//Initialize the position, gap is an object representing the spacing between elements
init:function(parent,gap){
var dragElem = parent.children();
//Ensure that the parent element is in relative positioning
if(parent.css('position') !== "relative"){
parent.css('position','relative');
}
parent.css({
'width':'100%,
'z',-index:'',10"}}"
});
//Current list content width
var ListWidth = 0;
//Location in which column
var j = 0;
dragElem.each(function(index,elem){
var curEle = $(elem);
//Set the initial position of the element
curEle.css({
position:"absolute",
top:gap.Y,
left:ListWidth + gap.X
});
//Add a unique identifier for each element, which is useful for restoring the initial position
curEle.attr('index',index);
//Save the initial position of the element
position.coord.push({
X:ListWidth + gap.X,
Y:gap.Y
});
j++;
//Set the height of the parent element
parent.height( parseInt(curEle.css('top')) + curEle.height() + gap.Y);
ListWidth = curEle.offset().left + curEle.width();
});
},
//Insert the child element into the parent element
addTo:function(child,parent,target){
//The coordinate of the parent element in the viewport
var parentPos = {
X:parent.offset().left,
Y:parent.offset().top
};
//The coordinate of the target position relative to the viewport
var targetPos = {
X:target.offset().left,
Y:target.offset().top
};
//Ensure that the parent element is in relative positioning
if(parent.css('position') !== "relative"){
parent.css({
'position':'relative'
});
}
parent.css({
'z',-index:'',12"}}"
});
//Insert the child element into the parent element
parent.append(child);
//Determine the position of the child element within the parent element and ensure that the size of the child element remains unchanged
child.css({
       position:absolute,
top:targetPos.Y - parentPos.Y,
left:targetPos.X - parentPos.X,
width:target.width(),
height:target.height()
});
},
//Restore the element to its original position
restore:function(elem){
//Obtain the identifier of the element
var index = parseInt( elem.attr('index') );
elem.css({
top:position.coord[index].Y,
left:position.coord[index].X
});
},
//Initial coordinates of the drag element
coord:[],
//Determine whether element A is within the range of element 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;

Four.drag module code

var $ = require('jquery');
var position = require('./position.js');
var drag = {
//The id of the parent element of the drag element
dragParen:undefined,
//The ID value of the operation console
control:undefined,
//The position of the moving block relative to the viewport
position:{
X:undefined,
Y:undefined
},
//The position of the touch point relative to the viewport, updated continuously during the sliding process
touchPos:{
X:undefined,
Y:undefined
},
//The position of the touch point relative to the viewport at the time of the initial touch
startTouchPos:{
X:undefined,
Y:undefined
},
//The position of the touch point relative to the moving block
touchOffsetPos:{
X:undefined,
Y:undefined
},
//Get the value of the id of the parent element of the dragging element and the ID of the console
setID:function(dragList,control){
this.dragParent = dragList;
this.control = control;
},
touchStart:function(e){
var target = e.target;
//Prevent bubble
e.stopPropagation();
//Prevent the browser's default zoom and scroll
e.preventDefault();
var $target = $(target);
//The position of the touch point when the finger just touches the screen
drag.startTouchPos.X = e.targetTouches[0].clientX;
drag.startTouchPos.Y = e.targetTouches[0].clientY;
//The position of the touch element relative to the viewport
drag.position.X = $target.offset().left;
drag.position.Y = $target.offset().top;
//The position of the touch point relative to the viewport, updated continuously during the scrolling process
drag.touchPos.X = e.targetTouches[0].clientX;
drag.touchPos.Y = e.targetTouches[0].clientY;
//The position of the touch point relative to the touch element
drag.touchOffsetPos.X = drag.touchPos.X - drag.position.X;
drag.touchOffsetPos.Y = drag.touchPos.Y - drag.position.Y;
//Bind the touchMove event to the target element
$target.unbind('touchmove').on('touchmove',drag.touchMove);
},
touchMove:function(e){
var target = e.target;
//Prevent bubble
e.stopPropagation();
//Prevent the browser's default zoom and scroll
e.preventDefault();
var $target = $(target);
//Obtain the position of the touch point
drag.touchPos.X = e.targetTouches[0].clientX;
drag.touchPos.Y = e.targetTouches[0].clientY;
//Modify the position of the moving block
$target.offset({
top: drag.touchPos.Y - drag.touchOffsetPos.Y,
left: drag.touchPos.X - drag.touchOffsetPos.X
});
//Bind the touchend event to the moving element
$target.unbind('touchend').on('touchend',drag.touchEnd);
},
touchEnd:function(e) {
var target = e.target;
//Prevent bubble
e.stopPropagation();
//Prevent the browser's default zoom and scroll
e.preventDefault();
var $target = $(target);
var parent = $target.parent();
//Get the parent element of the console and the drag element list
var control = $("#" + drag.control);
var dragListPar = $('#' + drag.dragParent);
//Whether the dragging element is located in the console
var sitControl = position.isRang(control, dragListPar, $target);
//After dragging, if the parent element of the dragged element is the drag list
if (parent.attr('id') === drag.dragParent) {
//If the element is located in the console
if (sitControl) {
var dragChild = $target.clone();
//Bind the touchstart event to the cloned element
dragChild.unbind('touchstart').on('touchstart',drag.touchStart);
//Insert the cloned element into the console
position.addTo(dragChild, control, $target);
}
//Restore the original touch element to its initial position
position.restore($target);
}
// After dragging, if the parent element of the dragged element is the console and the element is dragged out of the console
if (parent.attr('id') === drag.control && !sitControl) {
$target.remove();
}
}
};
module.exports = drag;

5. Entry file index.js code

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');
//Horizontal and vertical spacing of draggable elements
var gap = {
X:20,
Y:10
};
//Get the list of draggable elements through ajax
ajax.getInitImg(dragList);
//Initialize the position of the draggable elements
position.init(dragList,gap);
//Set the height of the console. The height of the console is the screen height minus the cover height of the drag list
var control = $('#control');
control.height( $(window).height() - dragList.height() );
//Bind the touchstart event to each draggable element
var dragElem = dragList.children();
dragElem.each(function(index,elem){
$(elem).unbind('touchstart').on('touchstart',drag.touchStart);
});
//The id value of the parent element of the drag element is dragList, and the id value of the operation console is control
drag.setID('dragList','control');

6. webpack packaging

The above uses the concept of modular programming, implementing different functions in different modules. You can use require() to import the functions you need. However, the browser does not have the definition of the require method. Therefore, the above code cannot be run directly in the browser and needs to be packaged first. If you are not familiar with webpack, you can check this article. The webpack configuration file is as follows:

var autoHtml = require('html-webpack-plugin');
var webpack = require('webpack');
var extractTextWebpack = require('extract-text-webpack-plugin');// This plugin can separate the css files, so that the css files are located in a separate file
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:"Drag",
filename:"drag.html",
template:'./app/darg.html',
inject:true
}
]
};

The above-mentioned is the jQuery mobile drag-and-drop (modular development, touch events, webpack) introduced by the editor to everyone. Hope it will be helpful to everyone. If you have any questions, please leave a message, and the editor will reply to everyone in time. Also, I would like to express my sincere gratitude to everyone for their support of the Yelling Tutorial website!

Statement: The content of this article is from the Internet, and the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, has not been manually edited, and does not assume relevant legal liability. If you find any copyright-infringing content, please send an email to: notice#oldtoolbag.com (When reporting, please replace # with @ and provide relevant evidence. Once verified, this site will immediately delete the infringing content.)

You may also like