آموزش Drag کردن عناصر با ماوس و کیبرد با جی کوئری
نوشته شده توسط محمد نمازی در ۳ مهر ۱۳۹۲همونطور که میدونید توی html5 که drag خیلی ظاهر زیبایی نداره.چون توی drag کردن باید خود المنت هم جابه جا بشه که این اتفاق نمی افته… اگر هم بخواهید JQUERY UI یا سایر پلاگین ها رو استفاده کنید، هیچ شناختی رو المنتی که drag میشه یا نحوه ی drag کردن ندارید…این طور شد که جرقه ساخت این آموزش در ذهنم ایجاد شد .
همچنین این کد رو طوری طراحی کردم که با دکمه های بالا و پایین و چپ و راست کیبرد هم میتونید المنت مورد نظرتون رو جابه جا کنید، که این کار فقط برای یک المنت انجام میشه.
این آموزش ساده است در صورتی که شما با مفاهیم اولیه جی کوئری آشنایی داشته باشید. این کد از بخشهای زیر تشکیل شده:
کدهای HTML:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <link type="text/css" rel="stylesheet" href="style.css" /> <script type="text/javascript" src="jquery-1.10.2.min.js"></script> <script type="text/javascript" src="script.js"></script> <title>آموزش درگ کردن عناصر با جی کوئری</title> </head> <body> <div> </div> </body> </html>
برای فعال کردن drag باید به المنت مورد نظر کلاس draggable رو بدید..
کدهای CSS:
.draggable{ /* CSS codes */ } .draggable:hover,.draggable:active{ cursor:move; } .draggable::selection,.draggable *::selection{ background-color:transparent; }
برای المنتی که drag میشه باید یه استایلی رو در نظر بگیرید تا اون المنت به طور واضح نمایان بشه و معلوم بشه که اون المنت داره drag میشه. درخط ۴ تا ۶ مشخص می کنیم که وقتی المنتیی که drag میشه hover شد،ماوس به شکلی دربیاد که کاربر بفهمه این المنت drag میشه… و در خط ۷ تا ۹ تعیین می کنیم که وقتی که المنت drag میشه،اگر المنت دیگری رو انتخاب کرد یا یکی از اعضای داخلی خودش انتخاب شد،به هیچ رنگی در نیاد..
برای این که منظورم رو متوجه بشید به این تصویر توجه کنید ..
وقتی که این کد نوشته نشه، در هنگام drag کردن ماوس به طور خودکار بخشی از متن رو انتخاب می کنه و رنگ پس زمینه اون رو آبی انتخاب می کنه، خب حالا ما توی این کد گفتیم اگه بخشی از متن هم انتخاب شد، رنگ پس زمینه برای اون المنت انتخاب نکن..
کدهای jQuery:
$(document).ready(function(e){ $(document).keydown(function(e){ if(e.keyCode==37){$('.draggable').animate({'left':'-=5'},3);} if(e.keyCode==39){$('.draggable').animate({'left':'+=5'},3);} if(e.keyCode==38){$('.draggable').animate({'top':'-=5'},3);} if(e.keyCode==40){$('.draggable').animate({'top':'+=5'},3);} }) $('.draggable').mousedown(function(e){ var thisElement = this; $(document).mousemove(function(e){ a=$(thisElement).width()/2 + parseInt($(thisElement).css('margin-left')); b=$(thisElement).height()/2 + parseInt($(thisElement).css('margin-top')); var x = e.pageX-(a); var y = e.pageY-(b); $(thisElement).css({'position':'absolute','top': y +'px', 'left': x +'px','opacity':'.45'}); }); }).mouseup(function(){ $(document).unbind('mousemove'); $(this).css({'opacity':'1'}); }); });
اول کد نویسی همیشه از رویداد ready برای document استفاده می کنیم تا مشکلی در اجرای کدهای جی کوئری پیش نیاد. در خط دوم کد، می خواهیم کد جا به جایی المنت با کلید های کیبرد رو بنویسیم.
$('selectror').keydown(handler);
که handler تابعی هست که وقتی اون رویداد انجام بشه، اتفاق میفته.
اول از رویداد keydown استفاده شده، یعنی هر وقت که یک از دکمه های کیبرد به پایین رفت باید تابعی اجرا بشه.. بعد با شرط ها چک میشه که دکمه ای که فشار داده شده شناسایی بشه…
$(document).keydown(function(e){ e.keyCode )};
این کد همیشه یه عدد رو برمیگردونه و شما باید با شرط ها اون رو شناسایی کنید.
اگه دکمه چپ فشار داده شده باشه، مقدار ۳۷ برگردونده میشه و توی بلاک مربوط به این شرط دستور داده میشه که با تابع animate مقدار چپ اون المنت رو در عرض سه میلی ثانیه پنج واحد کم کنه…
{'top':'-=5'}
یعنی مقدار top اون المنت هر چقدر که بود ۵ واحد از اون کم کن، و توجه داشته باشید به این دلیل مقدار اجرای animation رو کم نوشتم چون ممکنه پس از برداشتن دستتون از روی دکمه های بالا و پائین و چپ و راست باز هم همچنان انیمیشن اجرا بشه…
اگر دکمه بالا رو فشار بدید، مقدار ۳۸ و اگر دکمه راست رو فشار بدید مقدار ۳۹ و اگر دکمه پایین رو فشار بدید مقدار ۴۰ برگردونده میشه که به همون شیوه ای که در بالا توضیح دادم المنت موردنظر به بالا و پائین یا چپ و راست حرکت می کنه. سعی کنید به جای استفاده از کلاس draggable از کلاس های دیگه ای استفاده کنید چون اگه چند تا المنت با همین کلاس داشته باشید، یکدفعه همشون با هم حرکت می کنند. و در اینجا رویداد keydown تموم میشه و متحرک سازی المنت با کیبرد به پایان میرسه… در اینجا می خواهیم Drag کردن با ماوس رو پیاده سازی کنیم… امیدوارم که خسته نشده باشید اول از رویداد mousedown استفاده شده، یعنی وقتی کلیک شد(حالا فرقی نمی کنه چه راست کلیک چه کلیک کردن با دکمه چپ) و استفاده از این رویداد سلیقه ای هست و میتونید به جای این رویداد از click هم استفاده کنید. بعد مقدار اون شیئی رو که روی اون کلیک شده رو توی یک متغیر به نام thisElement ریختم.در برنامه نویسی سعی کنید این کار رو انجام بدید، در صورتی که به جای this از همون گزینشگر بالایی استفاده کنید مشکلاتی در اجرا پیش میاد..مثلاً ممکنه شما هشت تا المنت رو کلاس draggable دادید و وقتی شما یک رو drag می کنید، اون هفت تا المنت هم راه میفتند و یه وضع ناجوری توی صفحه تون پیش میاد.حالا جالبه بدونید که این this که توی متغیر ذخیره شده با سایر this هایی که توی کد هست فرق میکنه.حالا جلوتر که بریم متوجه میشید… در خط بعدی دستور داده میشه که وقتی ماوس روی سند حرکت کرد تابعی رو به اجرا دربیاره
$('selector').mousemove(handler)
در اینجا متغیر هایی تحت عنوان a و b تعریف شده و سپس متغیرهای x و y که برای موقعیت دهی ماوس و المنت در طول درگ کردن استفاده میشه. هر المنتی که Drag شد از وسط همون المنت کشیده میشه… پس، اندازه طول و عرض رو با توابع width و height می گیریم و چون می خواهیم از وسط drag بشه نصفشون می کنیم یا تقسیم بر ۲ می کنیم. ممکنه المنت margin داشته باشه و اگه margin داشته باشه، ماوس هم به همون اندازه ازش فاصله می گیره و هنگام Drag کردن المنت، یه کمی زشت به نظر میاد، برای همین ما مقادیر margin-top و margin-left رو می گیریم و به موقعیت ماوس اضافه می کنیم تا دقیقاً در وسط المنت قرار بگیره(البته گفته بودم که نباید margin به المنت داده بشه، ولی می تونید هنگام درگ کردن margin ها رو بگیرید و اون مقادیر رو به position بدید.) اگر هم margin اون المنت ۰ باشه که هیچ اتفاقی نمیفته…
سپس با استفاده از e.pageX و e.pageY موقعیت ماوس در هر لحظه برگردونده میشه، و با استفاده از متغیر های a و b و یک منهای ساده ماوس المنت موقعیت دهی میشه. سپس با تابع CSS موقعیت این المنت رو در صفحه مشخص می کنیم. مقدار top رو برابر با y و مقدار left رو برابر با x،در ضمن opacity اون المت رو هم کم کردم چون به نظر من جلوه ی بهتری داره.
خب در اینجا drag کردن تموم شد، ولی اگه دقت کنید این المنت حتی بعد از برداشتن دستتون از روی دکمه ماوس هم Drag میشه…اشکال کجاست؟؟ باید رویداد mousemove رو لغو کنید. که در خط بعدی همین کار انجام شده…
$('selector').mouseup(handler);
تابع unbind کنترلگر رویدادهایی(event handler) رو که قبلاً اجرا شده حذف میکنه و یک پارامتر میگیره و اون پارامتر هم همان کنترلگر رویدادی است که حذف میشه.
$('selector').unbind(event);
حالا موقعی که دکمه ماوس رها میشه،با تابع unbind دستور دادیم که کنترلگر رویداد mousemove رو برای document لغو کن و opacity اون المنت رو به حالت اولیه که ۱ هست برگردون.
اینجا دیگه از می تونید از this استفاده کنید چون مستقیماً برمیگرده به همون draggable .