English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
jQueryを使用すると、CP端のドラッグ操作は非常に簡単に実現できますが、モバイル端では使いにくいです。そこで、私はモバイル端のドラッグdemoを作成しました。主に使用するイベントはタッチイベント(touchstart、touchmove、touchend)です。
このdemoが実現する機能は、ドラッグ可能な要素(ここでは画像)がリストにあり、これらの要素が指定されたエリアにドラッグできることです。要素が指定されたエリアに到達すると、要素がコンソールに挿入され、元のドラッグ要素は元の位置に戻され、新しい要素はコンソール内でドラッグ可能であり、コンソールからもドラッグ可能です。
このdemoでは、3つのモジュールを使用しています。それらはajaxモジュール、dragモジュール、positionモジュールです。ajaxモジュールはajaxリクエストの実現に使用されます(すべての画像リソースはajaxリクエストで取得されます)。dragモジュールは要素のドラッグ操作に使用されます。positionモジュールは要素の位置操作に使用されます(例えば、位置の初期化、復元、削除など)。demoのエントリーファイルはindx.jsで、前述の3つのモジュールファイルは同じフォルダーに保存されています。コードが完成した後、webpackでパッケージ化されます。開発コードはappフォルダーにありますが、パッケージ化されたコードはbuildフォルダーに保存されます。
一. タッチイベントの紹介
タッチイベントは3つあります。touchstart、touchmove、touchendです。touchstartは指がスクリーンに触れたときにトリガーされます。touchmoveは指がスクリーン上をスライドすると連続してトリガーされます。このイベントが発生中にデフォルトをキャンセルすると、ページのスクロールを防ぐことができます。touchendは指がスクリーンから離れたときにトリガーされます。これらのタッチイベントのイベントオブジェクトは、マウスイベントの一般的な属性に加えて、以下の3つの属性も含みます:
touches: 現在追跡中のタッチ操作のtouchオブジェクトの配列です。
targetTouches: 特定のイベントターゲットに対するTouchオブジェクトの配列です。
changeTouches: この前のタッチ以来何が変わったかを示すTouchオブジェクトの配列です。
この例では、タッチポイントがビューポートに対する相対位置を取得する必要があります。私はevent.targetTouches[0].clientXとevent.targetTouches[0].clientYを使用しています
二. 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モジュールを外部に公開します
三.positionモジュールのコード
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-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-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;
四.dragモジュールのコード
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;
五.入口文件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()を使って導入できますが、ブラウザには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 モバイル端末のドラッグ(モジュール化開発、タッチイベント、webpack)であり、皆さんに役立つことを願っています。何かご不明な点があれば、コメントを残してください。編集者は迅速に回答します。また、呐喊教程サイトへのサポートに感謝しています。
声明:本文の内容はインターネットから収集され、著作権者に帰属します。インターネットユーザーが自発的に貢献し、アップロードしたものであり、本サイトは所有権を持ちません。また、人工的な編集は行われていません。著作権侵害を疑う内容があれば、メールを送信してください:notice#oldtoolbag.com(メール送信時は、#を@に変更してください。報告を行い、関連する証拠を提供してください。一旦確認が取れましたら、本サイトは即座に侵害を疑われるコンテンツを削除します。)