آموزش Drag کردن عناصر با ماوس و کیبرد با جی کوئری

نوشته شده توسط محمد نمازی در ۳ مهر ۱۳۹۲

همونطور که میدونید توی html5 که drag خیلی ظاهر زیبایی نداره.چون توی drag کردن باید خود المنت هم جابه جا بشه که این اتفاق نمی افته… اگر هم بخواهید JQUERY UI  یا سایر پلاگین ها رو استفاده کنید، هیچ شناختی رو المنتی که drag میشه یا نحوه ی drag کردن ندارید…این طور شد که جرقه ساخت این آموزش در ذهنم ایجاد شد .

همچنین این کد رو طوری طراحی کردم که با دکمه های بالا و پایین و چپ و راست کیبرد هم میتونید المنت مورد نظرتون رو جابه جا کنید، که این کار فقط برای یک المنت انجام میشه.

یادآوری : وردپرس برای Drag و Drop در قسمت ابزارک ها از jQuery UI استفاده می کنه.

این آموزش ساده است در صورتی که شما با مفاهیم اولیه جی کوئری آشنایی داشته باشید. این کد از بخشهای زیر تشکیل شده:

کدهای 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>

 

که یک کتابخانه جی کوئری ویک سند حاوی کدهای CSS و جی کوئری به اون متصل شده.

برای فعال کردن 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 میشه،اگر المنت دیگری رو انتخاب کرد یا یکی از اعضای داخلی خودش انتخاب شد،به هیچ رنگی در نیاد..

برای این که منظورم رو متوجه بشید به این تصویر توجه کنید ..

pic

وقتی که این کد نوشته نشه، در هنگام 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'});
        });
});

 

نکته : اگر دقت کنید متوجه میشید که این کد فقط برای عناصری طراحی شده که با position موقعیت دهی شده باشند و دلیل این امر واضحه، اگر بخواهیم drag کردن رو روی المنتی پیاده سازی کنیم که margin داشته باشه، صفحه به طور کلی به هم میریزه.

اول کد نویسی همیشه از رویداد ready برای document استفاده می کنیم تا مشکلی در اجرای کدهای جی کوئری پیش نیاد. در خط دوم کد، می خواهیم کد جا به جایی المنت با کلید های کیبرد رو بنویسیم.

نکته :رویداد keydown هنگامی اجرا میشه که یکی از دکمه های کیبرد فشار داده بشه و به صورت زیر استفاده میشه: 

$('selectror').keydown(handler);

که handler تابعی هست که وقتی اون رویداد انجام بشه، اتفاق میفته.

اول از رویداد keydown استفاده شده، یعنی هر وقت که یک از دکمه های کیبرد به پایین رفت باید تابعی اجرا بشه.. بعد با شرط ها چک میشه که دکمه ای که فشار داده شده شناسایی بشه…

نکته : e.keyCode یعنی کاربر چه دکمه ای رو فشار داده. و این e هنگامی که رویدادی اجرا میشه، یه سری از اطلاعات مربوط به اون رویداد رو توی خودش ذخیره میکنه. 

$(document).keydown(function(e){
e.keyCode
)};

این کد همیشه یه عدد رو برمیگردونه و شما باید با شرط ها اون رو شناسایی کنید.

اگه دکمه چپ فشار داده شده باشه، مقدار ۳۷ برگردونده میشه و توی بلاک مربوط به این شرط دستور داده میشه که با تابع animate مقدار چپ اون المنت رو در عرض سه میلی ثانیه پنج واحد کم کنه…

یادآوری : وقتی کد به این شکل نوشته شده باشه… 

{'top':'-=5'}

یعنی مقدار top اون المنت هر چقدر که بود ۵ واحد از اون کم کن، و توجه داشته باشید به این دلیل مقدار اجرای animation رو کم نوشتم چون ممکنه پس از برداشتن دستتون از روی دکمه های بالا و پائین و چپ و راست باز هم همچنان انیمیشن اجرا بشه…

نکته : شاید بپرسید چرا برای بردن المنت به سمت چپ مقدار right اون المنت رو زیاد نکردم؟؟  چون توی کد نویسی ها معمولاً مقادیری که به برای موقعیت دهی استفاده میشه top و left هست و اگه شما توی کدنویسی خودتون از مقادیری غیر از این دو استفاده کردید، باید این کد رو متناسب با نیازتون تغییر بدید.

اگر دکمه بالا رو فشار بدید، مقدار ۳۸ و اگر دکمه راست رو فشار بدید مقدار ۳۹  و اگر دکمه پایین رو فشار بدید مقدار ۴۰ برگردونده میشه که به همون شیوه ای که در بالا توضیح دادم المنت موردنظر به بالا و پائین یا چپ و راست حرکت می کنه. سعی کنید به جای استفاده از کلاس draggable از کلاس های دیگه ای استفاده کنید چون اگه چند تا المنت با همین کلاس داشته باشید، یکدفعه همشون با هم حرکت می کنند. و در اینجا رویداد keydown  تموم میشه و متحرک سازی المنت با کیبرد به پایان میرسه… در اینجا می خواهیم Drag کردن با ماوس رو پیاده سازی کنیم… امیدوارم که خسته نشده باشید 1x1.trans آموزش Drag کردن عناصر با ماوس و کیبرد با جی کوئری اول از رویداد mousedown استفاده شده، یعنی وقتی کلیک شد(حالا فرقی نمی کنه چه راست کلیک چه کلیک کردن با دکمه چپ) و استفاده از این رویداد سلیقه ای هست و میتونید به جای این رویداد از click هم استفاده کنید. بعد مقدار اون شیئی رو که روی اون کلیک شده رو توی یک متغیر به نام thisElement ریختم.در برنامه نویسی سعی کنید این کار رو انجام بدید، در صورتی که به جای this از همون گزینشگر بالایی استفاده کنید مشکلاتی در اجرا پیش میاد..مثلاً ممکنه شما هشت تا المنت رو کلاس draggable دادید و وقتی شما یک رو drag می کنید، اون هفت تا المنت هم راه میفتند و یه وضع ناجوری توی صفحه تون پیش میاد.حالا جالبه بدونید که این this که توی متغیر ذخیره شده  با سایر this هایی که توی کد هست فرق میکنه.حالا جلوتر که بریم متوجه میشید… در خط بعدی دستور داده میشه که وقتی ماوس روی سند حرکت کرد تابعی رو به اجرا دربیاره

نکته : رویداد mousemove  یعنی وقتی ماوس حرکت کنه و به شکل زیر استفاده میشه. 

$('selector').mousemove(handler)
نکته : حتماً دقت کردید که دو تا رویداد توی هم نوشتم؟  دلیلش اینه در جی کوئری رویدادی وجود نداره که هر دو کار رو با هم انجام بده، یعنی رویدادی که وقتی روی المنت کلیک شد و ماوس حرکت کرد، اجرا بشه. در ضمن اجرای رویداد دوم وابسته به رویداد اول هست یعنی تا وقتی اولی اجرا نشه دومی هم اجرا نمیشه. به این نکته هم توجه داشته باشید، به این دلیل از document استفاده کردم که حالت کلی تری داره و اگر بخواهید از draggable. استفاده کنید، باید بعضی از جاهای کد رو تغییر بدید. و نکته دیگر اینکه وقتی شما در رویداد دوم  از this استفاده کنید، جی کوئری document رو برای شما بر می گردونه به همین خاطر از متغیر thisElement که اون رو ایجاد کرده بودیم، استفاده می کنیم.

در اینجا متغیر هایی تحت عنوان a و b تعریف شده و سپس متغیرهای x و y که برای موقعیت دهی ماوس و المنت در طول درگ کردن استفاده میشه. هر المنتی که Drag شد از وسط همون المنت کشیده میشه… پس، اندازه طول و عرض رو با توابع width و height می گیریم و چون می خواهیم از وسط drag بشه نصفشون می کنیم یا تقسیم بر ۲ می کنیم. ممکنه المنت margin داشته باشه و اگه margin داشته باشه، ماوس هم به همون اندازه ازش فاصله می گیره و هنگام Drag کردن المنت، یه کمی زشت به نظر میاد، برای همین ما مقادیر margin-top و margin-left رو می گیریم و به موقعیت ماوس اضافه می کنیم تا دقیقاً در وسط المنت قرار بگیره(البته گفته بودم که نباید margin به المنت داده بشه، ولی می تونید هنگام درگ کردن margin ها رو بگیرید و اون مقادیر رو به position بدید.) اگر هم margin اون المنت ۰ باشه که هیچ اتفاقی نمیفته…

نکته : تابع parseFloat در جاوا اسکریپت یک رشته رو که حاوی عدد هست رو می گیره و عدد اون رو با رقمهای اعشارش بر می گردونه.  در ضمن jQuery مقادیر margin و padding رو با px بر می گردونه که با استفاده از تابع parseFloat این رشته ی عددی رو به عدد تبدیل می کنه و px رو از آخر اون حذف میکنه. اگر می خواهید اعداد بدون قسمت اعشاری برگردانده شوند از تابع parseInt استفاده کنید.

سپس با استفاده از e.pageX و e.pageY موقعیت ماوس در هر لحظه برگردونده میشه، و با استفاده از متغیر های a و b و یک منهای ساده ماوس المنت موقعیت دهی میشه. سپس با تابع CSS موقعیت این المنت رو در صفحه مشخص می کنیم. مقدار top رو برابر با y و مقدار left رو برابر با x،در ضمن opacity اون المت رو هم کم کردم چون به نظر من جلوه ی بهتری داره.

یادآوری : رویداد mousemove پشت سرهم و مکرر اجرا میشه و مقدار های جدیدی در متغیرهای x و y قرار می گیره.

خب در اینجا drag کردن تموم شد، ولی اگه دقت کنید این المنت حتی بعد از برداشتن دستتون از روی دکمه ماوس هم Drag میشه…اشکال کجاست؟؟ باید رویداد mousemove رو لغو کنید. که در خط بعدی همین کار انجام شده…

نکته : تابع mouseup هنگامی اجرا میشه که دکمه ی ماوس که فشار داده شده، رها بشه. 

$('selector').mouseup(handler);

تابع unbind کنترلگر رویدادهایی(event handler) رو که قبلاً اجرا شده حذف میکنه و یک پارامتر میگیره و اون پارامتر هم همان کنترلگر رویدادی است که حذف میشه.

$('selector').unbind(event);

حالا موقعی که دکمه ماوس رها میشه،با تابع unbind دستور دادیم که کنترلگر رویداد mousemove رو برای document لغو کن و opacity اون المنت رو به حالت اولیه که ۱ هست برگردون.

اینجا دیگه از می تونید از this استفاده کنید چون مستقیماً برمیگرده به همون draggable .

بدون دیدگاه دسته‌بندی : آموزش

دیدگاه‌تان را ارسال کنید ...