-
Notifications
You must be signed in to change notification settings - Fork 14
/
index_fa.html
executable file
·919 lines (812 loc) · 89.7 KB
/
index_fa.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>
jQuery vs MooTools: Choosing Between Two Great JavaScript Frameworks
</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="Shortcut Icon" href="favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="css/blueprint/screen.css" type="text/css" media="screen, projection">
<link rel="stylesheet" href="css/blueprint/print.css" type="text/css" media="print">
<!--[if IE]><link rel="stylesheet" href="css/blueprint/ie.css" type="text/css" media="screen, projection"><![endif]-->
<link rel="stylesheet" href="css/blueprint/src/typography.css" type="text/css" media="screen" title="no title" charset="utf-8">
<style>
body {
font-size: 100%;
color: #444;
background: #fff;
font-family: "Georgia", Arial, Helvetica, sans-serif;
}
h1, h2, h3, h4 {
color: #626262;
}
h1 {
text-align: center;
margin: 20px !important;
font-size: 90px;
padding: 0 !important;
padding:0 0 10px;
}
div.caption {
font-size: 14px;
text-align: right;
margin: auto;
width: 800px;
position: relative;
top: -25px;
background-color: none;
}
a, a.visited {
color: #004d9b;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
p.footnote {
font-size: 12px;
text-align:right;
margin-top: 0px;
position: relative;
top: -8px !important;
top: 0px;
}
p.about {
font-size: 12px;
}
tr td {
border-bottom: 1px solid #999;
vertical-align: top;
}
tr th {
background: #999;
color: #fff;
}
.dsq-item-cp {
display: none;
}
div.trans {
font-size: 10px;
}
ul#dsq-comments {
max-height:800px !important;
overflow:auto !important;
padding:0 10px 0 0 !important;
}
</style>
<!-- RTL CSS -->
<style type="text/css">
body { direction: rtl; text-align: right; font-family: Tahoma, Arial; font-size: 0.9em; }
.container th, .container tr, .container td { direction: rtl; text-align: right; }
pre { direction: ltr; text-align: left; margin-left: 20px; }
h3 { margin-top: 30px; }
h2 { margin-top: 40px; }
</style>
<script src="http://www.google.com/jsapi"></script>
<script>
google.load("mootools", "1.2.2");
</script>
<script src="js/Lighter/Ligher.uncompressed.js" type="text/javascript" charset="utf-8"></script>
<script>
window.addEvent('domready', function(){
var toc = $$('ul a');
$$('a:not(.stbutton)').each(function(a) {
if (toc.contains(a)) return;
a.set('target', '_blank');
});
if (Browser.Engine.trident) return;
// Highlight all "pre" elements in a document.
$$('pre').light({
altLines: 'hover',
indent: 2,
mode: 'pre',
path: 'js/Lighter/'
});
});
</script>
</head>
<body>
<div class="container">
<h1 class="span-24 last">jQuery vs MooTools</h1>
<div class="caption">
نوشته شده توسط <a href="http://www.clientcide.com">Aaron Newton</a> در مه 2009<br />ترجمه شده توسط <a href="http://boplo.ir" target="_blank">امیرحسین حجتی پور</a> در تیر ماه 1388
<div class="trans">
همچنین مقاله به زبانهای <a href="/index.html">انگلیسی</a>، <a href="/index_pt-br.html">برزیلی</a>، <a href="/index_es-ar.html">اسپانیایی</a> و <a href="/index_cn.html">چینی</a> در دسترس است.
</div>
</div>
<p>
خیلی از کاربران که این روزها کار با جاوااسکریپت را آغاز می کنند، با مسئله انتخاب مرجع (library) مواجه می شوند. حال چه برای استفاده و چه برای شروع یادگیری. اگر شما برای مجموعه یا شرکتی فعالیت می کنید احتمالا آنها قبلا برای شما فریم ورک (Framework) مورد نظرشان را انتخاب کرده اند. اگر آنها <a href="http://www.mootools.net">MooTools</a> را انتخاب کرده اند و شما به <a href="http://www.jquery.com">jQuery</a> عادت دارید، باز هم این مقاله می تواند برای شما تا حدی سودمند باشد.
</p>
<p>
<a href="http://twitter.com/joshink/statuses/1671986611">روزانه</a> <a href="http://twitter.com/jezusisstoer/statuses/1642244246">ارسالهای</a> <a href="http://twitter.com/digitalcampaign/statuses/1622094648">بسیار زیادی</a> <a href="http://twitter.com/jesswma/statuses/1605733380">در توییتر(Twitter)</a> به انتخاب بین MooTools و jQuery پرداخته میشود و با توجه به پرطرفداری این موضوع، هدف این مقاله، راهنمایی جهت انتخاب گزینه مناسب برای شماست.
</p>
<h3>رفع مسئولیت</h3>
<p>
من یک توسعه دهنده(Developer) و کاربر مرجع MooTools هستم و بر روی این فریم ورک فعالیت می کنم. من وبلاگی درباره MooTools دارم همچنین مؤلف شاخصترین<a href="http://www.mootorial.com"> مرجع آموزشی آنلاین</a> و <a href="http://www.amazon.com/gp/product/1430209836?ie=UTF8&tag=clientside-20&link_code=as3&camp=211189&creative=373489&creativeASIN=1430209836">کتابی درباره MooTools</a> هستم. پس طبیعتا من تا حدی به MooTools متمایل تر می باشم. همچنین باید ذکر کنم که من چندان از jQuery استفاده نکرده ام. اگر شما یک توسعه دهنده jQuery هستید و نکته اشتباهی در مقاله یافتید لطفا با من تماس بگیرید تا اصلاح گردد. هدف من بیان شفاف تفاوتها و ویژگیهاست نه برتری دادن فریم ورکی خاص به دیگری.
</p>
<h3>هدف</h3>
<p>
هدف همانطور که بطور ضمنی بیان شد، مسئله انتخاب بین این دو فریم ورک، با بررسی تفاوتهای آنهاست. مقاله با بیان این مطلب شروع خواهد شد که <b>هر دوی آنها، گزینه های کاملا مناسبی برای انتخاب می باشند</b>. هر کدام دارای نقاط قوت و ضعفی هستند ولی در کل هر دو انتخاب کاملی محسوب می شوند بنابراین شما از برگزیدن یکی، به هیچ وجه متضرر نخواهید شد. فریم ورکهای دیگری هم وجود دارند که هر کدام می توانند گزینه های کاملا مناسبی باشند از قبیل <a href="http://www.dojotoolkit.org/">Dojo</a>، <a href="http://www.prototypejs.org/">Prototype</a>، <a href="http://developer.yahoo.com/yui/">YUI</a>، <a href="http://extjs.com/">Ext</a> و غیره. هر کدام امکانات متعددی برای اهداف شما دارند. قصد این مقاله، تمرکز بر روی فریم ورکهایی است که بحث درباره انتخاب بینشان، بطور فزاینده ای مطرح می شود یعنی MooTools و jQuery. امکانات قابل توجهی در هر دو تعبیه شده که می توانید با کمی تلاش، آنها را فرا بگیرید. در آخر باید عنوان کنم که من به هیچ وجه قصد متقاعد کردن کسی برای انتخاب گزینه ای خاص را ندارم.<br />شما می توانید <a href="http://www.clientcide.com/3rd-party-libraries/jquery-vs-mootools-mootools-vs-jquery/">مطلب کوتاه من درباره انگیزه ایجاد این مقاله</a> را در وبسایت من مطالعه کنید.
</p>
<h3>سرفصل ها</h3>
<ul>
<li><a href="#mottos">شعار سازندگان گویای همه چیز است</a></li>
<li><a href="#learning">شیوه آموزش و پشتیبانی</a></li>
<li><a href="#javascript">جاوااسکریپت برای چه مقاصدی مناسب است</a></li>
<ul style="margin-bottom: 0px">
<li><a href="#dom">کمی بیشتر همراه با DOM</a></li>
<li><a href="#inheritance">"ارث بری" یا Inheritance در جاوااسکریپت</a></li>
<li><a href="#self">"مرجع درونی" یا Self refrence</a></li>
</ul>
</li>
<li><a href="#jsfun">MooTools جاوااسکریپت را لذتبخش تر می کند</a></li>
<li><a href="#domfun">jQuery استفاده از DOM را لذتبخش تر می کند</a></li>
<li><a href="#cando">هر کاری که تو بتونی، من بهترش رو می تونم</a></li>
<li><a href="#yourway">MooTools به شما امکان حفظ ساختارتان را می دهد</a></li>
<li><a href="#chaining">انسجام توسط یک "الگوی طراحی"</a></li>
<li><a href="#reuse">استفاده چندباره ی کدها در jQuery</a></li>
<li><a href="#classes">استفاده چندباره ی کدها در MooTools</a>
<ul>
<li><a href="#mooinheritance">MooTools و "ارث بری"</a></li>
<li><a href="#extension">توسعه و بکارگیری کلاسها</a></li>
</ul>
</li>
<li><a href="#conclusion">زمان انتخاب</a></li>
<li><a href="#discussion">بحث و گفتگو</a></li>
</ul>
<h2>آمارها</h2>
<table>
<tr>
<th></th>
<th>هسته jQuery</th>
<th>هسته MooTools</th>
</tr>
<tr>
<td>حجم مرجع</td>
<td>55.9K</td>
<td>64.3K</td>
</tr>
<tr>
<th colspan="3">امکانات</th>
</tr>
<tr>
<td>مجوز</td>
<td><a href="http://en.wikipedia.org/wiki/MIT_License" title="MIT License">MIT</a> & <a href="http://en.wikipedia.org/wiki/GPL" title="GPL">GPL</a></td>
<td><a href="http://en.wikipedia.org/wiki/MIT_License" title="MIT License">MIT</a></td>
</tr>
<tr>
<td>امکانات DOM</td>
<td>بلی</td>
<td>بلی</td>
</tr>
<tr>
<td>متحرک سازی</td>
<td>بلی</td>
<td>بلی</td>
</tr>
<tr>
<td>بدست گیری رویدادها (Events)</td>
<td>بلی</td>
<td>بلی</td>
</tr>
<tr>
<td>انتخابگرهای CSS3</td>
<td>بلی (به عنوان زیرمجموعه)</td>
<td>بلی (به عنوان زیرمجموعه)</td>
</tr>
<tr>
<td>Ajax</td>
<td>بلی</td>
<td>بلی</td>
</tr>
<tr>
<td>توسعه های محلی (منهای توسعه های Element)</td>
<td>حدود یک جین برای Array، Object ، String</td>
<td>حدود شش جین برای Array، Object، String، Function و Number</td>
</tr>
<tr>
<td>ارث بری</td>
<td>مستقیما پشتیبانی نمی شود</td>
<td>بوسیله متد سازنده شی <em><a href="http://mootools.net/docs/core/Class/Class">Class</a></em></td>
</tr>
<tr>
<th colspan="3">معیارهای دیگر</th>
</tr>
<tr>
<td>افزونه ها</td>
<td>صدها افزونه غیررسمی بصورت مجموعه در <a href="http://plugins.jquery.com/">plugins.jquery.com</a></td>
<td>حدود 4 جین از افزونه ها بصورت رسمی در <a href="http://mootools.net/more">mootools.net/more</a>, & <a href="http://mootools.net/plugins">mootools.net/plugins</a></td>
</tr>
<tr>
<td>مرجع UI رسمی</td>
<td>بلی</td>
<td>خیر</td>
</tr>
</table>
<p class="footnote">
اطلاعات براساس آمار موجود در <a href="http://jquery.com">jquery.com</a>، <a href="http://mootools.net">mootools.net</a> و <a href="http://en.wikipedia.org/wiki/Comparison_of_JavaScript_frameworks">wikipedia.com</a>.
</p>
<a name="mottos"></a>
<h2>شعار سازندگان گویای همه چیز است</h2>
<p>
اگر به سایت jQuery مراجعه کنید این جمله را در بالای صفحه اصلی مشاهده خواهید کرد:
</p>
<blockquote>jQuery یک مرجع جاوااسکریپت سریع و کم حجم است. این مرجع، دسترسی به اجزا صفحه HTML، به دست گیری رویدادها، متحرک سازی، امکانات AJAX برای توسعه وب سریعتر را ساده می کند. jQuery برای تغییر شیوه نگارش جاوااسکریپت طراحی شده است.</blockquote>
<p>
و اگر به سایت MooTools مراجعه کنید:
</p>
<blockquote>MooTools یک فریم ورک فشرده، ماژولار و شیء گرای جاوااسکریپت، برای تبدیل کاربران متوسط جاوااسکریپت به توسعه دهندگان حرفه ای آن است. MooTools از طریـق APIهای قدرتمند، کاملا مسـتند و منسـجم خود، امـکان ایجاد کدهای قدرتمند، انعطاف پذیر و معتبر برای همه مرورگرها(cross-browser) را به شـــما می دهد.</blockquote>
<p>
به نظر من این جملات جمع بندی مناسبی را ارائه می دهند که تا اینجا اگر از من بپرسید (من اینطور فرض می کنم که شما این مقاله را تا انتها مطالعه خواهید کرد) مفهوم این نیست که کدام فریم ورک بهتر یا بدتر است بلکه اینطور است که شما قصد چه کاری را دارید. این دو فریم ورک حرفهای مشابهی را نزده اند. دامنه امکانات آنها مشابه است ولی یکی نیست.
</p>
<p>
jQuery درباره HTML، رویدادها، AJAX، متحرک سازی و توسعه وب صحبت می کند و MooTools درباره شیء گرایی، انعطاف پذیری و توانایی بالا. آرمان jQuery "تغییر شیوه نگارش جاوااسکریپت" بیان شده در حالیکه MooTools برای تبدیل کاربران متوسط به حرفه ای طراحی گشته.
</p>
<p>
بخشی از این تصمیم گیری مربوط به درک مفهوم <em>"فریم ورک"</em> و <em>"ابزار (toolkit)"</em> می شود. MooTools <em>فریم ورکی</em> است که برای تعیین نحوه اجرای جاوااسکریپت <em>به شیوه ای که باید باشد</em> کوشش می کند (با توجه به نظر مؤلفان آن). هدف آن تعیین شیوه اجرای یک API، بصورتی که کاملا شبیه جاوااسکریپت باشد و همه امکانات مورد نیاز نه فقط برای DOM را فراهم آورد (مترجم: واژه DOM، مخفف عبارت Document Object Model است. DOM ساختار صفحه HTML را به شکل یک درخت تبدیل می کند تا دسترسی به تمام اجزای صفحه از طریق روابط والد و فرزندی و شیء گرایی امکانپذیر شود. بدون DOM، محتوای یک صفحه برای جاوااسکریپت، چیزی جز کوهی از کلمات و حرفهای بی معنی نیست). jQuery <em>ابزاریست</em> که به شما امکان استفاده آسان مجموعه ای از متدها و فرمانها را می دهد این متدها در یک سیستم طراحی شده اختصاصی، کار کردن با DOM را بسیار لذت بخش می سازد. بسیار پیش می آید که کاربران در حین نگارش جاوااسکریپت تلاش خود را معطوف کار با DOM می کنند و در این حالت jQuery همه آن چیزیست که نیاز دارید.
</p>
<p>
بسیاری از کدهایی که با MooTools نوشته می شوند حالت خود جاوااسکریپت را دارند. اگر شما به برنامه نویسی با جاوااسکریپت علاقه چندانی ندارید یادگیری MooTools بسیار کسل کننده خواهد بود در غیر اینصورت اگر به جاوااسکریپت و توانایی های آن علاقه مندید من شخصا MooTools را پیشنهاد می کنم.
</p>
<a name="learning"></a>
<h2>شیوه آموزش و پشتیبانی</h2>
<p>
ابتدا باید ذکر کرد که jQuery روی هم رفته برای یادگیری آسانتر است. همچنین دارای حالت خاصی از نگارش است که به کدهای معمول کمتر شباهت دارد. اگر همه چیزی که لازم دارید راه اندازی سریع برخی امکانات جاوااسکریپت بدون یادگیری این زبان است، jQuery احتمالا گزینه مناسبتری برای شماست. این بدین معنا نیست که MooTools از انجام این کار ناتوان است بلکه باید قبول کرد که تسلط در MooTools برای کاربران تازه وارد در جاوااسکریپت کمی دشوارتر خواهد بود و یا می شود گفت کمتر بودن منابع آموزشی MooTools در مقابل jQuery خود بر این ادعا تاکید دارد.
</p>
<p>
اگر به مقایسه انجمنهای گفتگوی jQuery (<a href="http://docs.jquery.com/Discussion">بخش Disscussion در سایت jQuery</a>) و MooTools (<a href="http://mooforum.net/">انجمن غیررسمی</a>، <a href="irc://irc.freenode.net/#mootools">irc</a> و <a href="http://groups.google.com/group/mootools-users">mailing list</a>) بپردازید، به سرعت متوجه دو نکته خواهید شد: 1) انجمنهای jQuery بطور قابل ملاحظه ای گسترده تر است (به دلیل یادگیری آسانتر که ذکر شد) و 2) آنها بسیار در ترویج مرجع خود فعال هستند. اگر بخواهیم این دو را اندازه گیری کنیم مثلا براساس تعداد کاربران، تعداد جستجو در گوگل، تعداد کتابهای فروش رفته و غیره؛ برتری متریک jQuery کاملا مشهود است.
</p>
<p>
با این تفاسیر، درباره اینکه چطور MooTools می تواند انتخاب شود باید اطلاعاتی درباره کاری که این دو انجام میدهند بیان کرد. در نهایت فریم ورکی که انتخاب می کنید کارهایی که مایلید انجام دهید و برنامه نویس شدن شما را محقق می کند (البته <i>اگر</i> دوست دارید برنامه نویس جاوااسکریپت شوید).
</p>
<a name="javascript"></a>
<h2>جاوااسکریپت برای چه مقاصدی مناسب است</h2>
<p>
بخشی از تصمیمی که می خواهید بگیرید ارتباط مستقیمی دارد با کاری می خواهید با جاوااسکریپت انجام دهید. جاوااسکریپت معمولی بدون فریم ورک را در نظر بگیرید. این زبان شیء های محلی (Native) از قبیل <a href="https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Global_Objects/String">Strings</a>، <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Number">Numbers</a>، <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Function">Functions</a>، <a href="https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Global_Objects/Array">Arrays</a>، <a href="https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Global_Objects/Date">Dates</a>، <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/RegExp">Regular Expressions</a> و غیره را در اختیار شما قرار می دهد به اضافه یک مدل ارث بری (Inheritance model) که برخی مواقع بطور غیرعلنی prototypal inheritance خطاب می شود (که در ادامه به آن پرداخته خواهد شد). امکانات و کدهای مربوط به ارث بری جزء بخشهای طبیعی و معمول زبانهای برنامه نویسی هستند و حقیقتا در قبال مرورگر یا وب یا CSS یا HTML کاری برای انجام ندارند. شما هر کدی را بصورت عادی می توانید با جاوااسکریپت بنویسید اما از آنجایی که نتیجه این زبان، در %99 مواقع توسط مرورگر قابل رؤیت است، به عنوان یک زبان برای مرورگرها شناخته شده و کاربران به توانایی پشت صحنه آن پی نمی برند.
</p>
<p>
قابل درک است که بیشترین برخورد ما با این زبان در مواجهه با مرورگر و DOM است ولی در واقع جاوااسکریپت یک زبان قدرتمند و عمیق است که می تواند تفاوتهای پراهمیت دو فریم ورک پرطرفدار یعنی MooTools و jQuery را بارز سازد.
</p>
<a name="dom"></a>
<h3>کمی بیشتر همراه با DOM</h3>
<p>
jQuery باز هم بهترین گزینه خواهد بود اگر تصور شما بر آن است که تمام کاری که جاوااسکریپت انجام می دهد به "بده بستان" با صفحه ختم می شود. این موضوع زمانی نمود پیدا می کند که این سیستم قدرتمند معمولا ظاهری شبیه به برنامه نویسی های معموال را ندارد. فعالیتهای دیگر در جاوااسکریپت هم توسط این سیستم قابل اجراست ولی اگر تمرکز و فوکوس شما روی DOM ،CSS، متحرک سازی، دریافت اطلاعات توسط AJAX است، jQuery این مسئله را پوشش می دهد در حالیکه نیاز به سبک معمولی و دمده جاوااسکریپت هم نباشد. jQuery متدهایی را برای موارد غیر از DOM نیز ارائه می دهد؛ مانند روشی که برای شمارش آرایه ها دارد - <i><a href="http://docs.jquery.com/Utilities/jQuery.each">(each(array, fn.$</a></i> – یا متدی برای پالایش رشته ها - <i><a href="http://docs.jquery.com/Utilities/jQuery.trim">(trim(str.$</a></i> . اما وجود اکثر این متدها چندان حیاتی نیستند وقتی فعالیت روی DOM و دسترسی به اجزای آن انجام می شود (از قبیل کار با CSS، مدیریت اطلاعات HTML و تعریف رویداد هنگام کلیک شدن بخشی از صفحه و غیره).
</p>
<p>
اما اگر عمیقتر به آن نگاه کنید متوجه خواهید شد که jQuery تمرکزی روی فعالیتهای خارج از DOM ندارد. این یکی از دلایلی است که یادگیری ساده آن را به ارمغان آورده ولی محدودیت در نگارش جاوااسکریپت هم با آن همراه شده. این توجیهی است که او تمایلی به حرکت از یک سیستم خشک <i>مختص DOM</i> را ندارد. او از خواص ارث بری و حتی امکانات ابتدایی محلی برای متغیرهای جاوااسکریپت محروم است، در واقع <i>او نیازی هم به آنها ندارد</i>. اگر نیاز به استفاده از regular expressions، arrays، strings، dates، functions را دارید، جاوااسکریپت کمک شما خواهد بود. jQuery برای شما DOM را به یک زمین بازی تبدیل می کند ولی سایر فعالیتها در حیطه تعریف آن نیستند.
</p>
<p>
این نکته ای است که MooTools را کاملا متمایز می سازد. به غیر از تمرکز انحصاری روی DOM، گستره این فریم ورک به کل زبان جاوااسکریپت می رسد (باید اضافه کرد که براساس تجربه ای که من با jQuery داشته ام، تمام فعالیتهای ممکن با jQuery، با MooTools هم قابل اجراست ولی به شکلی کاملا متفاوت). اگر jQuery محیط DOM را به زمین بازی شما مبدل می کند MooTools خود زبان جاوااسکریپت را زمین بازی شما می کند و این یکی از دلایلی است که یادگیری اش را مشکلتر ساخته.
</p>
<a name="inheritance"></a>
<h3>ارث بری یا Inheritance در جاوااسکریپت</h3>
<p>
زبان جاوااسکریپت دارای قابلیتهای فوق العاده ای است. برای تازه کارها، این زبان براساس توابع یا <a href="http://en.wikipedia.org/wiki/Functional_programming">functional</a> است به این معنا که توابع به عنوان اشیاء رده بالایی اجرا میشوند که امکان ارسالشان بصورت متغیر وجود دارد مانند اشیاء String و Number و غیره. این زبان با همین مفهوم ذهنی طراحی شده و زمانی که از این روش استفاده می کنید اکثر متدها و الگوها(Patterns) بخوبی کار می کنند. به اختلاف بین دو مورد زیر توجه کنید:
</p>
<pre class="js">for (var i = 0; i < myArray.length; i++) { /* do stuff */ }</pre>
<p>
و
</p>
<pre class="js">myArray.forEach(function(item, index) { /* do stuff */ });</pre>
<p>
جاوااسکریپت دارای یک <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Inheritance">مدل ارث بری</a> است. این مدل با اینکه منحصر به فرد نیست ولی کم نظیر است. در این زبان بجای تعریف کلاس و نمونه گیری آن، ارث بری بصورت <i><a href="http://en.wikipedia.org/wiki/Prototype-based_programming">prototypal</a></i> صورت می گیرد. بدین معنا که اشیاء مستقیما از اشیاء دیگر بدست می آیند (به ارث می رسند – inherit می شوند). اگر در یک شیء، مشخصه یا Propertyای درخواست گردد، جاوااسکریپت به دنبال آن در شیء فرزند (Child) جستجو می کند و اگر پیدا نکرد جستجو را در شی والد (Parent) ادامه می دهد. به همین دلیل است که یک آرایه، به هنگام تعریف می تواند متدهای آرایه ها را بپذیرد:
</p>
<pre class="js">[1,2,3].forEach(function(item) { alert(item) }); //this alerts 1 then 2 then 3</pre>
<p>
متدی با عنوان "<a href="https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Objects:Array:forEach">forEach</a>" برای آرایه بالا تعریف نشده پس جاوااسکریپت به دنبال این متد در شیء والد یعنی شیء Arrays می گردد. وقتی این متد را برای شیء از نوع آرایه بکار می برید، این زبان، در شیء شما، این متد را درخواست می کند و اگر متدی با این نام وجود نداشت، به سراغ متدهای شیء مخصوص همه آرایه ها می رود. این بدین معناست که متد <em>forEach</em>در حافظه مربوط به شیء بالا قرار نگرفته بلکه در حافظه مربوط به شیء اصلی آرایه ها (prototype of arrays) جای دارد. این یک شیوه فوق العاده کارآمد و مفید است (شایان گفتن است که متد <em>each</em> در MooTools متناظر با متد <em>forEach</em> است).
</p>
<a name="self"></a>
<h3>مرجع درونی یا Self refrence</h3>
<p>
جاوااسکریپت یک عبارت خاص دارد: “this”. تعریف اجمالی این عبارت برای من کمی مشکل است ولی در کل می توان گفت این عبارت در یک متد، به شیءای که متد در آن واقع است اشاره دارد. این قابلیت به اشیاء امکان ارجاع به خودشان را در متدهایشان می دهد و کاربرد دیگری ندارد. اهمیت این ویژگی اینجاست که وقتی شما اشیاء فرزند و نمونه های متعددی از آنها را داشته باشید چطور متدها را، به شیء خودشان ارجاع می دهید؟ وقتی متد در کلاس والد وجود داشته باشد و در کلاس فرزند نباشد، این عبارت امکان ارجاع به متد اصلی را به نمونه ها می دهد (<a href="http://www.quirksmode.org/js/this.html">توضیحات تفصیلی درباره عبارت this</a> و <a href="https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Operators/Special_Operators/This_Operator">مقاله ای دیگر در موزیلا</a>).
</p>
<p>
عبارت this به اشیایی که به ارث برده شده اند، امکان ارجاع به متدهای خودشان را می دهد. اما گاهی پیش می آید که شما نیاز به ارجاع به مکان دیگری از طریق this را دارید که در این حالت باید از <a href="http://alternateidea.com/blog/articles/2007/7/18/javascript-scope-and-binding">binding</a> استفاده شود. binding مقدار <i>متفاوتی</i> را برای this در متد مشخص می کند. متد each از طریق پارامتر دوم خود امکان تعیین منبع شیء را فراهم می کند. به مثال زیر توجه کنید:
</p>
<pre class="js">var ninja = {
weapons: ['katana', 'throwing stars', 'exploding palm technique'],
log: function(message) {
console.log(message);
},
logInventory: function() {
this.weapons.each(function(weapon) {
//we want "this" to point to ninja...
this.log('this ninja can kill with its ' + weapon);
}, this); //so we pass "this" (which is ninja) to Array.each
}
};
ninja.logInventory();
//this ninja can kill with its katana
//this ninja can kill with its throwing stars
//this ninja can kill with its exploding palm technique</pre>
<p>
در مثال بالا و در متد <em>logInventory</em> ، ما ninja را به متدی که به آرایه منصوب شده ارجاع دادیم که می تواند عملیات log را بر روی خود ninja انجام دهد در حالیکه اگر با استفاده از پارامتر دوم each، شیء را به اصطلاح bind نمی کردیم، عبارت this همچنان به <em>window</em> اشاره می داشت.
</p>
<p>
اینها نمونه هایی از روشهای قدرتمند جاوااسکریپت برای ارث بری، ارجاع درونی و binding و مشخصه های سودمند prototype بودند. نکته نامطلوب این است که جاوااسکریپت این امکانات را بطور کامل و سودمند ارائه نمی دهد و اینجاست که MooTools <i>جلوه نمایی </i> خواهد کرد. MooTools این الگوها را بسیار ساده و دلپذیر در دسترس قرار می دهد. شما می توانید کدهای خود را با کدهای abstract بیشتری تولید کنید (مترجم: الگوی abstract امکاناتی برای معرفی منابع ارجاعات به کدها را فراهم می کند) که در یک اجرای طولانی، بسیار قابل استفاده و قدرتمند نمایان می شود. فهمیدن اینکه الگوها چطور می توانند مقدارپذیر (valuable) باشند و چطور باید از آنها استفاده کرد به کمی تلاش نیازمند است اما در نهایت کدهای شما بطور فوق العاده ای چندبار مصرف (reusable) و قابل مدیریت می شود. درباره این دو خصوصیت در ادامه بحث خواهد شد.
</p>
<a name="jsfun"></a>
<h2>MooTools جاوااسکریپت را لذتبخش تر می کند</h2>
<p>
از آانجاییکه تمــرکز MooTools بر روی APIهای جاوااســکریــپت است، این زبان را پایدارتر و منسجم تر می کند. این فریم ورک تلاش زیادی برای تغییر شیوه کدنویسی نمی کند بلکه فوکوسی ویژه برای دلپذیرتر و قابل تحملتر کردن جاوااسکریپت دارد. می توان گفت در واقع MooTools یک extension یا توسعه برای زبان جاوااسکریپت است. سعی او بر آن است که جاوااسکریپت را به موقعیتی که باید باشد برساند. بخش اعظم هسته آن به تقویت اشیاء Function، String، Array، Number، Element و غیره اختصاص دارد و بخش دیگر امکانی مهمی که ارائه می دهد تابعیست با نام <em><a href="http://mootools.net/docs/core/Class/Class">Class</a></em>.
</p>
<p>
حالا <em>Class</em>شباهت بیشتری به روشهای تعریف الگوهای ارث بری که در زبانهایی مثل Java یا ++C سراغ داریم، دارد اما <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Class-Based_vs._Prototype-Based_Languages">این همه موضـــوع نــیست</a>. کاری که <em>Class</em> انجام می دهد دسترسی و استفاده آسان از مدل ارث بری prototypal است (مترجم: شیء گرایی در بسیاری از زبانها بر پایه تعریف کلاس است و در جاوااسکریپت بر پایه prototype به معنای دسترسی و ارتباط نمونه هاست). این خواص توسط MooTools معرفی نشده اند و منحصر به فرد نیستند اما jQuery فاقد هر دوی آنهاست. jQuery هیچ مدلی برای ارث بری ندارد و امکاناتی هم برای اشیاء محلی مثل String و Array تعریف نکرده. این یک کاستی ساده نیست که نویسندگان jQuery به سادگی جبران کنند در واقع می توان گفت آنها ابزاری طراحی کرده اند با مقاصد متفاوت. همانطور که MooTools جاوااسکریپت را مفرح می سازد، jQuery نیز کار با DOM را دلپذیرتر می کند و آنها با این دیدگاه، محدودیتهای خود را پذیرفته اند.
</p>
<a name="domfun"></a>
<h2>jQuery استفاده از DOM را لذتبخش تر می کند</h2>
<p>
و این دلیل قابل دسترس تر بودن jQuery است. او از شما فراگیری جاوااسکریپت را نمی خواهد. او شما را به اعماق مدلهای ارث بری و کاربرد this و binding و اشیاء محلی پرتاب نمی کند. وقتی از طریق <a href="http://docs.jquery.com/Tutorials:How_jQuery_Works">آموزش رسمی</a> خود jQuery، به یادگیری آن اقدام می کنید، این اولین مثالی است که آورده شده:
</p>
<pre class="js">window.onload = function() {
alert("welcome");
}</pre>
<p>و این سومین است:</p>
<pre class="js">$(document).ready(function() {
$("a").click(function(event) {
alert("Thanks for visiting!");
});
});</pre>
<p>
اگر فراگیری MooTools را از طریق <a href="http://www.amazon.com/gp/product/1430209836?ie=UTF8&tag=clientside-20&link_code=as3&camp=211189&creative=373489&creativeASIN=1430209836">کتاب آن</a> یا <a href="http://www.mootorial.com/wiki">آموزش اینترنتی آن</a> (که مؤلف هر دوی آنها من هستم) آغاز کنید، خواهید دید که شیوه معرفی کاملا متفاوت است. با اینکه در آموزش MooTools امکان نادیده گرفتن ترتیب مباحث وجود دارد و می توان مستقیما سراغ افکتها و بخشهای DOM رفت ولی این آموزش با طرح چیزهایی مانند <em>Class</em> یا پرسیدن سوالاتی از قبیل آیا شما یک برنامه نویس مبتدی هستید یا آیا فقط قصد اضافه کردن امکاناتی به سایت خود هستید، شروع می شود. با این وضعیت، jQuery برای شما بسیار دوستانه تر است.
</p>
<p>
به عبارت دیگر اگر قصد یادگیری خود زبان جاوااسکریپت را دارید، MooTools بهترین وسیله است. او امکاناتی را معرفی می کند که زبان جاوااسکریپت در حال حرکت به سمت آنهاست (بسیاری از متدهای Native در <a href="https://developer.mozilla.org/En/New_in_JavaScript_1.8">جاوااسکریپت 1.8</a> و بالاتر معرفی خواهند شد). اگر به برنامه نویسی آشنا هستید مخصوصا به مدلهای شیء گرایی <em>و</em> تابعی (functional)، فریم ورک MooTools الگوهای طراحی شگفت انگیز و فوق العاده زیادی را داراست.
</p>
<a name="cando"></a>
<h2>هر کاری که تو بتونی، من بهترش رو می تونم</h2>
<p>
اغلب به ازای امکاناتی که jQuery ارائه داده است نمونه مشابهی در MooTools یافت می شود. اما این ویژگی برای jQuery صادق نیست و بسیاری از امکانات MooTools را نمی توان در jQuery شبیه سازی کرد زیرا همانطور که گفته شد، تمرکز آن بر روی DOM قرار دارد. دامنه امکانات MooTools از jQuery بیشتر است ولی شما از استفاده گسترده تر منع نشده اید. برای مثال jQuery فاقد سیستم ارث بری است اما این مشکلی نیست زیرا می توانید از قابلیت <em>Class</em> موجود در MooTools بصورت تلفیقی در jQuery بهره ببرید (یا چنین قابلیتی را خودتان در jQuery طراحی کنید) و یا حتی از <a href="http://code.google.com/p/jquery-inheritance/updates/list">پلاگین مخصوص ارث بری در آن</a> استفاده کنید (من از این پلاگین استفاده نکرده ام ولی اینطور به نظر می رسد که قابلیتهای خوبی برای این منظور داشته باشد).
</p>
<p>اگر به مثال ذیل از jQuery دقت کنید:</p>
<pre class="js">$(document).ready(function() {
$("a").click(function(event) {
alert("Thanks for visiting!");
});
});</pre>
<p>
و آن را به MooTools ترجمه کنید، خواهید داشت:
</p>
<pre class="js">window.addEvent('domready', function() {
$$('a').addEvent('click', function(event) {
alert('Thanks for visiting!');
});
});</pre>
<p>
شباهت زیادی دارند، اینطور نیست؟
</p>
<p>
این یک مثال پیچیده تر از jQuery است:
</p>
<pre class="js">$(document).ready(function() {
$("#orderedlist li:last").hover(function() {
$(this).addClass("green");
},
function() {
$(this).removeClass("green");
});
});</pre>
<p>
و در MooTools داریم:
</p>
<pre class="js">window.addEvent('domready',function() {
$$('#orderedlist li:last-child').addEvents({
mouseenter: function() {
this.addClass('green');
},
mouseleave: function() {
this.removeClass('green');
}
});
});</pre>
<p>
مجددا بسیار شبیه هستند ولی من می توانم ثابت کنم که نسخه MooTools کد بالا، بسیار روشنتر است ولی این بحث باعث طولانی تر شدن مقاله می گردد. بصورت کوتاه، کد MooTools دو رویداد تعریف کرده یکی برای ورود ماوس (mouse enter) و یکی برای خروج ماوس (mouse leave) و برای هر یک متدی مشخص کرده در حالیکه کد jQuery فشرده تر می باشد. متد <em><a href="http://docs.jquery.com/Events/hover">hover</a></em> آن دو پارامتر دریافت می کند که اولی برای ورود ماوس و دومی برای خروج ماوس اجرا می شود. من شخصا معتقدم که نمونه کد MooTools منطقی تر و گویاتر است ولی نه کاملا ملموس.
</p>
<p>
کدهای jQuery گاهی خیلی برای من مبهم می شوند. از نگاه کردن متدها اغلب چیز زیادی بدست نمی آید و تحلیل آنها مشکل است. این می تواند به این خاطر باشد که من با کدهای MooTools مأنوس تر هستم و خواندن درک آنها برای من آسانتر است. اما نکته ای که در MooTools قابل ستایش می دانم، نامگذاری مناسب متدها و کلاسهاست که تقریبا همیشه نام عمل با کارکرد آن متناظر است و کمترین شبهه در آن وجود دارد. شما در همه زبانهای برنامه نویسی باید به سراغ بخش آموزش آن بروید تا با نحوه استفاده و سینتکس کدها آشنا شوید ولی در MooTools کافی است تا با روش منسجم و پایدار APIهای آن آشنا شوید.
</p>
<a name="yourway"></a>
<h2>MooTools به شما امکان حفظ ساختارتان را می دهد</h2>
<p>اما اگر شما به شیوه یا سینتکس jQuery علاقه داشته باشید، یک نمونه دیگر از توانایی MooTools را می توان در سادگی تغییر شیوه ها براساس میلتان بیان کرد. اگر بخواهیم متد <em>hover</em> در jQuery را در MooTools شبیه سازی کنیم، کافی است مشابه زیر عمل کنیم:</p>
<pre class="js">Element.implement({
hover : function(enter,leave){
return this.addEvents({ mouseenter : enter, mouseleave : leave });
}
});
//and then you could use it exactly like the jQuery version:
$$('#orderlist li:last').hover(function(){
this.addClass('green');
},
function(){
this.removeClass('green');
});
</pre>
<p>البته پلاگینهایی هم وجود دارد که <a href="http://github.com/cheeaun/mooj/tree/master">سینتکس (Syntax) استاندارد jQuery را برای MooTools</a> ایجاد می کنند. تمرکز MooTools روی توسعه آن است، به هر چیزی که مایلید. این ویژگی است که اغلب با jQuery امکانپذیر نیست. MooTools می تواند کاملا شبیه jQuery شود (خود را به شکل آن را دربیاورد) ولی jQuery توانایی تبدیل شدن به MooTools را ندارد. اگر میخواهید کلاس ایجاد کنید، اشیاء محلی را توسعه دهید و یا کارهای مشابه انجام دهید، با MooTools می توانید. این کدها را خودتان تولید کنید.</p>
<a name="chaining"></a>
<h2>انسجام توسط یک "الگوی طراحی"</h2>
<p>
به نمونه های بیشتری توجه کنید. این یک مثال از سایت jQuery است:
</p>
<pre class="js">$(document).ready(function() {
$('#faq').find('dd').hide().end().find('dt').click(function() {
$(this).next().slideToggle();
});
});</pre>
<p>
این شیوه ایست که من شخصا ترجیح نمی دهم. به کد دقت کنید، فهمیدن اینکه این کدها چه کاری انجام می دهند کار آسانی نیست. بصورت دقیقتر، درک اینکه <i>end.</i> چه کاری انجام می دهد و <i>find.</i> بعد از آن چطور عمل می کند و به کدام <i>end.</i> مرتبط است، کمی پیچیده به نظر می آید. حالا به سراغ مستندات jQuery در سایتش برویم، آنجا بطور شفاف نحوه کارکرد <i>end.</i> را توضیح داده (این متد مقادیر را براساس مرجع faq# به حالت اول باز میگرداند یا موقعیت را reset می کند.). اما این برای من کمی غریب به نظر می آید. در زمان کار با jQuery، من اغلب اطمینان نداشتم که متدی خاص، چه مقداری را بر خواهد گرداند (return خواهد کرد). اما در عمل این موضوع از نظر تعداد بالایی از کاربران jQuery، اینطور به نظر نمی رسد و آنها راضی هستند پس من این مسئله را هم سلیقه ای در نظر میگیرم.
</p>
<p>
حالا به کد بالا در محیط MooTools توجه کنید:
</p>
<pre class="js">window.addEvent('domready', function() {
var faq = $('faq');
faq.getElements('dd').hide();
faq.getElements('dt').addEvent('click', function() {
this.getNext().slide('toggle');
});
});
</pre>
<p>
مجددا نمونه کد با MooTools طولانی تر است ولی واضحتر نیز هست. همچنین دقت کنید که الگوی طراحی در اینجا ذخیره سازی مرجع به faq#، در یک متغیر است در حالیکه jQuery از متد <i>end.</i> خود برای بازگرداندن مرجع استفاده می کند. امکان ایجاد کدهای زنجیروار (chained) سطح بالا در MooTools وجود دارد (مترجم: عبارت chain برای امکان استفاده از توابع و متدها، بلافاصله بعد از هم مانند نمونه های بالا می باشد. معنای لغوی chain زنجیر است که متدها به حلقه های زنجیر که به هم متصل و بصورت متوالی می آیند تشبیه شده). به نمونه زیر نگاه کنید:
</p>
<pre class="js">item.getElements('input[type=checkbox]')
.filter(function(box) {
return box.checked != checked;
})
.set('checked', checked)
.getParent()[(checked) ? 'addClass' : 'removeClass']('checked')
.fireEvent((checked) ? 'check' : 'uncheck');</pre>
<p>
ولی در واقع، این روش کدنویسی (وجود کدهای زیاد در رویداد domready) برای هر فریم ورکی، جالب به نظر نمی رسد. بهتر است که کدهای خود را به تکه های چندبار مصرف تبدیل کنیم.
</p>
<a name="reuse"></a>
<h2>استفاده چندباره ی کدها در jQuery</h2>
<p>
وقتی بر روی پروژه ای کار می کنید استفاده از برخی افکتها و امکانات فریم ورکها مانند انتخاب اجزاء DOM، اضافه کردن رویدادهای کلیک و mouseover و غیره بصورت کدهای معمولی بسیار وسوسه انگیز خواهد بود. ایجاد کد با این شیوه بسیار و کارآمد و سریع الوصول است. اما مشکل اصلی این شیوه یعنی نوشتن همه کدها در عبارت domready این است که بسیاری از کدها عملیات مشابه یا تکراری انجام می دهند ولی برای مکانهای متفاوت (مترجم: رویداد domready در MooTools و متد ready. در jQuery کاربردشان به این صورت است که زمانی اجرا می شوند که ساختار DOM بطور کامل در دسترس باشد بنابراین استفاده از آنها، تضمینی بر صحیح اجرا شدن کدهای مربوط به DOM است). اگر ما برای بخش FAQ (که مثالش در بالا ذکر شد) الگویی طراحی کنیم، می توانیم به جای تکرار و تولید کدها در همه صفحات، فقط از آنها استفاده کنیم. آیا روش ما برای این الگو، تکرار ساختار کدها در همه صفحات است؟
</p>
<p>
یک راه ساده برای ایجاد قابلیت چندبار مصرفی، قرار دادن کدها در یک تابع و ارسال داده ها از طریق پارامتر تابع است. این یک نمونه از کد بالا در jQuery است:
</p>
<pre class="js">function faq(container, terms, definitions) {
$(container).find(terms).hide().end().find(definitions).click(function() {
$(this).next().slideToggle();
});
};
$(document).ready(function() {
faq('#faq', 'dd', 'dt');
});</pre>
<p>
این روش به دو دلیل مهم و اساسی زیر بهتر است:
</p>
<ol>
<li>
اگر در آینده بخواهیم تفییری در نحوه کارکرد کدها داشته باشیم (مثلا فعالیتهای اضافی براساس رویداد کلیک داشته باشیم یا اطلاعات را توسط AJAX دریافت کنیم) کافیست تا متد اصلی <i>faq</i> را تغییر دهیم تا رفتار آن در همه صفحات و بخشهای بکار گرفته شده عوض شود و یا اگر نسخه جدیدی از jQuery عرضه گردد که تغییراتی در کدها لازم باشد، بجای جستجو و تغییر انبوهی از کدها، متد اصلی به سرعت یافت و اصلاح می شود. من تلاش می کنم تا بخشی از کدها که بصورت کلی اجرا می شوند را مشخص کنم و حجمشان را تا حد امکان پایین بیاورم به این ترتیب، رفع اشکال، توسعه، بروزرسانی فریم ورک و تغییر ساختار به راحتی بیشتری انجام می گیرد.
</li>
<li>
دلیل دوم حجم کم کدهاست. با استفاده چندباره از یک کد، مقادیری تکرار نمی گردد و در همه محیطهای برنامه نویسی قابل تغییر است همچنین بازدیدکنندگان به هنگام بارگذاری (Load) صفحه حجم کمتری را دریافت خواهند کرد.
</ol>
<p>
jQuery در واقع سیستم تمیزی برای تعریف این قبیل کدهای چندبار مصرف نیست در حالیکه روش زیر به روش ساده استفاده از توابع ارجحیت دارد (و روش تابع به روش خام ارجحیت دارد). jQuery کاربران را به نگارش کدهای شخصی بصورت <a href="http://docs.jquery.com/Plugins/Authoring">jQuery plug-ins</a> تشویق می کند که در آن حالت، کد نمونه مذکور شبیه این خواهد شد:
<pre class="js">jQuery.fn.faq = function(options) {
var settings = jQuery.extend({
terms: 'dt',
definitions: 'dd'
}, options);
//"this" is the current context; in this case, the elements we want to turn into faq layouts
$(this).find(settings.terms).hide().end().find(settings.definitions).click(function() {
$(this).next().slideToggle();
});
return this;
};</pre>
</p>
و چیزی که استفاده خواهید کرد:
</p>
<pre class="js">$('#faq').faq();</pre>
<p>
اما با کمی دقت در این شیوه و شیوه قبل، متوجه شباهت بالای آنهای خواهیم شد. با اینکه این تابع در محدوده اصلی فریم ورک (namespace) قرار ندارد ولی به سادگی می توان این کار را انجام داد (مترجم: واژه namespace به محدوده هایی اشاره دارد که متدها در آنها معتبر هستند. برای نمونه، در یک محیط، از دو متد همنام، متدی قابل اجراست که در محدوده namespace تعریف شده معتبر باشد. این محدوده ها معمولا قابل تعریف هستند). با الصاق این کدها به jQuery، ما می توانیم متدهای اصلی دیگر را همراه آن استفاده کنیم. حسن دیگر آن است که عبارت this در تابع به موقعیت فعلی که jQuery با آن روبروست اشاره دارد (مترجم: یعنی در بخش تعریف تابع، عبارت this به faq# اشاره دارد). با استفاده از این شیوه می توان کدها را به نحوی ایجاد کرد که گویی جزیی از ساختار jQuery هستند اما غیر از آن، این پلاگینها، در واقع توابع معمولی هستند که مرجع کنونی jQuery را دریافت می کنند، عملیاتی روی آن انجام می دهند و خود مرجع مورد اشاره را باز میگردانند. این حالت هیچ پیچیدگی ندارد و همه را قادر می سازد تا پلاگین تولید کنند زیرا همانطور که گفته شد، این پلاگینها در واقع همان توابع معمولی هستند که قابلیت دریافت مرجع مورد اشاره را دارند.
</p>
<p>
دقت کنید که با استفاده از دستورات و متدهای jQuery، امکان نگارش پلاگینهای پیچیده تر وجود دارد. این شیوه طراحی توسط پلاگین UI در jQuery پشتیبانی می شود و ساختار و مکانیسم مشابه آنچه ذکر شد ندارد. به جای آن ما یک شیء با همه متعلقاتش را به شیء jQuery وصل می کنیم (مانند ui.tabs.$). این یک راه کوتاه برای فراخوانی این شیء است (()selector).tabs)$) که می توان در آن اتصالات زنجیروار مانند پلاگین faq را هم داشت. اما به این علت که هیچ مرجعی بازگردانده نمی شود، شما مجبورید برای فراخوانی (invoke) متدهای شیء (در اینجا tab)، ابتدا انتخابگر (selector) را فراخوانی کنید تا متدها شناخته شوند. یعنی بجای (myTabInstance.add(url, label, index شما باید انتخابگر را اجرا کنید و نام متد را بصورت رشته به آن بدهید ;(selector).tabs('add', url, label, index)$ . این یعنی شما انتخابگر را دوبار اجرا کرده اید (حتی اگر آن را در یک متغیر ذخیره کرده باشید) و چون هیچ مرجعی برای اجرای متد add ندارید از امکاناتی مانند bind (تغییر مرجع) و delay (ایجاد وقفه) هم محرومید. این مقاله معطوف MooTools و jQuery است و با توجه به اینکه پلاگین UI بطور پیش فرض بر روی jQuery وجود ندارد، بیشتر از این بدان پرداخته نمی شود.
</p>
<a name="classes"></a>
<h2>استفاده چندباره ی کدها در MooTools</h2>
<p>
در MooTools زمانی که قصد ایجاد یک الگو را دارید، احتمالا از <em><a href="http://mootools.net/docs/core/Class/Class">Class</a></em> و یا واردسازی متد به اشیاء Native (محلی) مانند <em>String</em> استفاده می کنید.
</p>
<p>
همچنین او شیوه یا سینتکس تقریبا متفاوتی از جاوااسکریپت را هم ارائه می دهد. MooTools تلاش می کند تا حد وسطی بین سینتکس شخصی خود و سینتکس عمومی جاوااسکریپت داشته باشد. یکی از این راهها، توسعه اشیاء محلی در این زبان یا محیط DOM است این بدین معناست که اگر مثلا به متدی برای پاکسازی (trim) یک رشته نیاز دارید، MooTools شما را تشویق می کند تا این متد را مستقیما به خود شیء String اضافه کنید (البته باید دقت شود که شیء String در MooTools، بصورت پیشفرض دارای این متد به شکل <em><a href="http://mootools.net/docs/core/Native/String#String:trim">String.trim</a></em> می باشد):
</p>
<pre class="js">String.implement({
trim: function() {
return this.replace(/^\s+|\s+$/g, '');
}
});</pre>
<p>
این یعنی، اجرای متد trim بر روی یک جمله با فاصله های اضافی، نتیجه همان جمله بدون این فاصله هاست (مترجم: یعنی ما برای شیء String یک متد جدید ایجاد کردیم که در زمان اجرا کاملا مشابه متدهای معمولی استفاده می شود). برخی شاید عنوان کنند که اضافه کردن اجزای جدید به اشیاء محلی کار مناسبی نیست. به همین دلیل است که MooTools با <a href="http://www.prototypejs.org/">Prototype.js</a> سازگاری ندارد؛ در واقع همه فریم ورکهایی که بر روی اشیاء محلی تاثیر می گذارند، قابلیت سازگاری با هم را ندارند. اگر من <i>()String.prototype.foo</i> را تعریف کنم و فریم ورک دیگری هم آن را تعریف کند، متدی اجرا خواهد شد که دیرتر تعریف شده باشد مشابه همین حالت مشکلی است که ما با محدوده نام (namespace) سراسری window داریم و البته این شیوه کارکرد جاوااسکریپت است. این روشی است که <a href="https://developer.mozilla.org/En/New_in_JavaScript_1.8">جاوااسکریپت 1.8</a> امکانات جدیدی را از طریق افزودن prototypeها معرفی کرده.
</p>
<p>
توسعه دهندگان MooTools، فریم ورکی را طراحی کرده اند که گسترش آن برای شما آسان باشد با این قصد که کاربر فقط این فریم ورک را در صفحه وارد کند و نه فریم ورکهای دیگر را. این در واقع کمی گستاخانه خواهد بود که از کاربران خواسته شود تا مثلا دو فریم ورک را دریافت کنند. تنها دلیل این امر، نیاز به پلاگینهای موجود در هر دو فریم ورک است که توسعه دهندگان MooTools (از جمله خودم) پیشنهاد می کنیم تا زمانی را به انتقال پلاگینها با یک محیط واحد اختصاص دهید بجای اینکه از کاربران بخواهید دو فریم ورک را دریافت کنند.
</p>
<p>
زمانی که با نحوه کار جاوااسکریپت آشنا می شوید و امــکان توسعه اشیاء محلـــی را فرا می گیرید، دریچه جدیدی در برنامه نویسی را در مقابل خود خواهید دید. شما می توانید پلاگین بنویسید و مثلا در اشیاء Function، Element، Date و غیره تغییر ایجاد کنید. که البته شاید برخی معترض باشند ایـن شــیوه کدنویسی، شیوه شلوغ و نا به سامانی است و من در جواب خواهم گفت که این روش ماهیت اصلی استفاده از جاوااسکریپت است. این یک قابلیت طراحی در این زبان است. با اضافه کردن کدهای خود به اشیاء محلی، به آنها امکان کوتاه شدن و جزء جزء شدن را داده اید. jQuery هم، این چنین امکانی را دارد ولی با درنظر گرفتن محدودیتهایی در هسته اصلی خود.
</p>
<p>
در حالیکه می توانید به سادگی چندین متد از شیء jQuery را زنجیروار به هم وصل و اجرا کنید، برای اشیاء دیگر باید از روشهای عمومی بهره گیرید. برای مثال اگر بخواهیم در jQuery یک رشته را پاکسازی (trim) کنیم و بر اساس خطهای آن شمارش داشته باشیم، باید:
</p>
<pre class="js">$.each( $.trim( $('span.something').html() ).split("\n"), function(i, line){alert(line);});</pre>
<p>اما MooTools می تواند اشیاء را تغییر دهد:</p>
<pre class="js">$('span.something').get('html').trim().split("\n").each(function(line){alert(line);});</pre>
<p>
با نگاه دقیق به این مثالها می توان قدرت MooTools را در تغییر prototypeها مشاهده کرد. اتصال زنجیروار (Chaining) متدها، فقط برای DOM مفید نیستند. MooTools به شما امکان این نوع اتصال را بر روی هر نوع شیء می دهد حتی قابلیت اجرای همزمان یک متد بر روی چندین بخش، نیز با استفاده این ویژگی ایجاد شده.
</p>
<p>
کلید این ویژگی در قلب MooTools با این تئوری تعریف شده که کاربر بتواند هر آنچه مایل است را ایجاد کند. اگر این قابلیت بصورت تابع و خارج از هسته می بود، شما می توانستید با توسعه آن نیازهای خود را برطرف کنید اما وظیفه هسته ایجاد همه نوع تابع برای هر نوع نیازی نیست بلکه وظیفه آن این است که ابزار ایجاد هر چه لازم دارید را فراهم کند. بخش اعظم این مقصود با امکان ساده توسعه اشیاء محلی و استفاده از مدل ارث بری prototypal ایجاد شده. تمام این کارها با جاوااسکریپت معمولی قابل اجراست ولی MooTools آنها را بسیار ساده تر و لذتبخش تر کرده است.
</p>
<a name="mooinheritance"></a>
<h3>MooTools و "ارث بری"</h3>
<p>
تابع <em>Class</em> در MooTools علی رغم نامش، نه یک کلاس واقعی است و نه کلاسی را ایجاد می کند. این تابع شامل یک الگوی ظاهری شبیه به کلاس در زبانهای دیگر است و در اصل وسیله دسترسی به اشیاء و مدل ارث بری است (متاسفانه استفاده از کلمه "کلاس" مناسبترین کلمه برای تشریح این تابع است. بنابراین در این مقاله، منظور از "کلاس"، توابعیست که شیء برمی گردانند و آنهایی که "نمونه" معرفی می شوند، مشخصه های ارث برده شده(Inherit from prototype) هستند).
</p>
<p>
برای ساختن یک کلاس باید یک شیء را به متد سازنده(Constructor) تابع <em>Class</em> فرستاد (مترجم: متد سازنده، متدی است که در زمان نمونه گیری از کلاس، بصورت خودکار اجرا می گردد):
</p>
<pre class="js">var Human = new Class({
initialize: function(name, age) {
this.name = name;
this.age = age;
},
isAlive: true,
energy: 1,
eat: function() {
this.energy = this.energy + 1; //same as this.energy++
}
});</pre>
<p>
ما در اینجا یک شیء (شیء شامل اعضایی مثل “isAlive” و “eat” و غیره) را به <em>Class</em> رساندیم و این شیء تبدیل به شیء اصلی همه نمونه های این کلاس شده است. برای تعریف یک نمونه باید به روش زیر عمل کرد:
</p>
<pre class="js">var bob = new Human("bob", 20); //bob's name is "bob" and he's 20 years old.</pre>
<p>
حالا ما یک نمونه (Intstance) از Human داریم (مترجم: لازم به ذکر است که متد سازنده شیء Class، متد initialize است یعنی با نمونه گیری از هر Class، متد initialize آن خودبخود اجرا میگردد). شیء Bob مشخصه هایی که به نمونه گیری کلاس Human تنظیم شد را دریافت کرد. اما نکته مهم این است که bob از طریق ارث بری به همه مشخصه های کلاس دسترسی دارد. وقتی ارجاعی به مشخصه eat در bob داشته باشیم، این شیء دارای چنین مشخصه ای نیست. جاوااسکریپت در bob به جستجوی این متد می پردازد و آن را پیدا نمی کند پس جستجو را در ارتباطات موروثی bob که کلاس شامل شده از آن (Human) است، ادامه می دهد. این روش برای مشخصه energy هم صادق است. در نظر اول، این قابلیت جالبی به نظر نمی رسد زیرا ما علاقه نداریم مقداری که برای energy شیء bob ایجاد می کنیم، برای بقیه نمونه های Human بکار گرفته شود (مترجم: از آنجاییکه یک مشخصه از مرجع اصلی تغییر کرده، نمونه های دیگر هم که مشتق شده مرجع اصلی هستند، آن تغییر را احساس می کنند). نکته مهم این است که اولین باری که ما مقداری را برای energy در bob تعیین می کنیم، ما این مقدار را به خود bob داده ایم و نه به prototype آن (قابلیت ارث بری در اینجا، فقط برای تشخیص مشخصه ها که متعلق به کدام نمونه است، استفاده شده) پس اولین باری که متد eat اجرا می شود (مقدار energy در این متد تغییر می کند)، نتیجه مقدار تعریف شده برای خودش خواهد بود:
</p>
<pre class="js">bob.eat(); //bob.energy == 2</pre>
<p>
دقت کنید که مشخصه های name و age برای bob منحصر به فرد هستند. آنها در زمان نمونه گیری توسط متد خودکار تابع یعنی initialize تعریف شده اند.
</p>
<p>
چهره کلی این سبک شاید کمی برای شما ناآشنا به نظر برسد اما این همان مقادیری هستند که ما با آنها، نمونه های مجزا از یک کلاس را ایجاد می کنیم. هر نمونه (instance) موقعیت شخصی خود را دارد. اگر ما نمونه های دیگری ایجاد کنیم، هر کدام از بقیه مستقل هستند اما همه از یک منبع شامل می شوند:
</p>
<pre class="js">var Alice = new Human();
//alice.energy == 1
//bob.energy == 2</pre>
<p>
جالبترین قسمت این موضوع زمانی است که این شیوه توسعه یابد.
</p>
<a name="extension"></a>
<h3>توسعه و بکارگیری کلاسها</h3>
<p>
ابتدا نگاهی دوباره به پلاگین faq که برای jQuery ایجاد کردیم بیاندازیم. چه اتفاقی می افتد اگر بخواهیم امکانات بیشتری به آن اضافه کنیم یا چه می شود اگر بخواهیم پاسخ سوالات FAQ را توسط AJAX از سرور دریافت کنیم؟ تصور کنید که این پلاگین توسط شخص دیگری نوشته شده و ما می خواهیم بدون تغییرات اساسی در آن امکانات مورد نظرمان را اضافه کنیم (ما نمی خواهیم انسجام فعلی اش دچار اشکال شود).
</p>
<p>
تنها راههای موجود اینها است که یا منطق پلاگین faq را کپی کنیم (بخاطر بیاورد که کل منطق بصورت یک تابع بود) و تغییرات را در منطق آن اعمال کنیم و یا، آن را فراخوانی (Invoke) کنیم و وظایف جدید را به آن اضافه کنیم. گزینه دوم می تواند جلوی مشکلات زیادی را بگیرد. به این مثال توجه کنید:
</p>
<pre class="js">jQuery.fn.ajaxFaq = function(options) {
var settings = jQuery.extend({
//some ajax specific options like the url to request terms from
url: '/getfaq.php'
definitions: 'dd'
}, options);
//"this" is the current context; in this case, the elements we want to turn into faq layouts
$(this).find(settings.definitions).click(function() {
$(this).load(.....); //the logic to load the content from the term
});
this.faq(); //call our original faq plug-in
});</pre>
<p>
پلاگین جدید دارای نکاتی است. اول از همه اینکه پلاگین، انتخابگری که برای definition تعیین شده را تکرار می کند زیرا راهی برای ذخیره نتیجه و استفاده مجدد از آن نیست. دوم اینکه، امکان افزودن بخش مربوط به AJAX در قسمتی که ما اضافه کردیم (بخش پایینی) وجود ندارد و این کدها باید وارد منطق اصلی پلاگین شود. پلاگین اصلی از slideToggle که بخش definition را با افکت اسلاید نمایش می دهد، استفاده می کند و این، نکته ی مشکل ساز توسعه ماست زیرا، بخش definition در مدل ما توسط AJAX دریافت می شود. وقتی موردی از faq کلیک شود، افکت slideToggle بلافاصله فعال می گردد و definition را نمایش می دهد حتی اگر هنوز دریافت محتوای آن توسط AJAX به اتمام نرسیده باشد (به بیان دیگر، قاعده صحیح به این صورت است که با کلیک، AJAX فعال گردد و وقتی نتیجه AJAX آماده شد، افکت اسلاید برای نتیجه اعمال شود). پس این افکت باید حذف گردد چون متاسفانه هیچ راه حلی برای چنین مشکلی وجود ندارد مگر تکرار و کپی (duplicate) کل پلاگین.
<p>
حال به کلاس Human که تحت MooTools ایجاد کردیم دقت کنید. او مشخصه های مثل isAlive و energy، و متدی با نام eat دارد. برای اضافه کردن مشخصه های دیگر به این کلاس چه کار باید کرد؟ در MooTools ما کلاس را اینگونه توسعه (Extend) می دهیم:
</p>
<pre class="js">var Ninja = new Class({
Extends: Human,
initialize: function(name, age, side) {
this.side = side;
this.parent(name, age);
},
energy: 100,
attack: function(target) {
this.energy = this.energy - 5;
target.isAlive = false;
}
});</pre>
<p>
می بینید که ما به کلاس جدید وظایف زیادی اضافه کردیم. کلاس جدید همه مشخصه های موجود را برای خودش یعنی کلاس Ninja دارد. Ninja مقدار energy را با 100 آغاز می کند و مشخصه جدیدی به نام side هم دارد. همچنین او می تواند از طریق متد attack خود، Human های دیگر را نابود کند و در این راه مقداری انرژی از دست دهد.
</p>
<pre class="js">var bob = new Human('Bob', 25);
var blackNinja = new Ninja('Nin Tendo', 'unknown', 'evil');
//blackNinja.isAlive = true
//blackNinja.name = 'Nin Tendo'
blackNinja.attack(bob);
//bob never had a chance</pre>
<p>
جزییات جالب زیادی در این مثال وجود دارد. قابل توجه است که کلاس Ninja متد initialize مربوط به خود را دارد؛ این متد، متد مشابه در کلاس والد (اینجا Human) را رونویسی (overwrite) می کند ولی همچنان می توان از طریق this.parent، متد initialize کلاس والد را اجرا کرد. طبیعتا لازم است تا پارامترهای لازم برای اجرای متد initialize والد را در this.parent قرار داد. به علاوه می توانیم منطق کلاس را، قبل و بعد از فراخوانی parent کنترل کنیم. ما قادریم مقادیر جدیدی به مشخصه ها بدهیم (مثلا به energy) و وظایف جدید اضافه کنیم (قبل و بعد از اجرای this.parent). تصور کنید چقدر خوب می شد که می توانستیم این خاصیت را در پلاگین faq در jQuery وارد کنیم. حالا با این قابلیت می توانیم در این پلاگین، ابتدا محتوای AJAX را کامل دریافت کنیم و سپس افکت اسلاید را داشته باشیم.
</p>
<p>
MooTools یک الگوی دیگر با نام Mixin دارد. درحالیکه روش extend رابطه موروثی بین کلاس والد و فرزند ایجاد می کند، شما قادرید تا کلاسهایی تعریف کنید تا با کلاسهای دیگر ادغام شوند و مشخصه های خود را منتقل کنند. برای مثال:
</p>
<pre class="js">var Warrior = new Class({
energy: 100,
kills: 0,
attack: function(target) {
target.isAlive = false;
this.energy = this.energy - 5;
this.kills++;
}
});</pre>
<p>
اینجا ما صفات را تغییر دادیم تا کلاس Ninja را از کلاس Human متمایز کنیم و صفات را در کلاس خودشان قرار دهیم. این به ما امکان استفاده مجدد این کدها را، خارج از کلاس Ninja می دهد. حال ما می توانیم کلاس Ninja را با صفات Warrior ادغام کنیم. یعنی:
</p>
<pre class="js">var Ninja = new Class({
Extends: Human,
Implements: Warrior, //can be an array if you want to implement more than one
initialize: function(name, age, side) {
this.side = side;
this.parent(name, age);
}
});</pre>
<p>
تفاوتی در عملکرد Ninja بوجود نیامد فقط در این روش، ما Warrior را برای ایجاد خاصیت استفاده مجدد، اضافه کردیم.
</p>
<pre class="js">var Samurai = new Class({
Extends: Human,
Implements: Warrior,
side: 'good'
});</pre>
<p>
حالا ما یک کلاس Samurai و یک کلاس Ninja داریم اما به کوتاهی کدهایی که صرف تعریف این دو کلاس شده دقت کنید. هر دو از نظر داشتن صفات Human و Warrior مشترک هستند ولی Samurai همیشه دارای مقدار good برای مشخصه side است و Ninja اینطور نیست. با صرف زمان برای طراحی کلاسهای Human و Warrior، ما سه کلاس متفاوت بدون تکرار اضافی کد داریم که دارای قابلیت کنترل بصورت جزء جزء هستند؛ بطوریکه وقتی متدها فراخوانی می شوند این کلاسها با یکدیگر در ارتباط قرار می گیرند. هر نمونه (Instance) محدوده مختص به خود را دارد و کدها کاملا واضح و خوانا هستند.
</p>
<p>
در حال حاضر ما اطلاعاتی درباره اینکه کلاسهای MooTools چطور فعالیت می کنند داریم. اجازه بدهید تا به پلاگین faq که برای jQuery ایجاد کردیم و می خواستیم امکانات AJAX را به آن اضافه کنیم، بپردازیم و ببینیم که MooTools در ساختن نمونه مشابه چطور عمل می کند:
</p>
<pre class="js">
var FAQ = new Class({
//Options is another class provided by MooTools
Implements: Options,
//these are the default options
options: {
terms: 'dt',
definitions: 'dd'
},
initialize: function(container, options) {
//we store a reference to our container
this.container = $(container);
//setOptions is a method provided by the Options mixin
//it merges the options passed in with the defaults
this.setOptions(options);
//we store the terms and definitions
this.terms = this.container.getElements(this.options.terms);
this.definitions = this.container.getElements(this.options.definitions);
//we call our attach method
//by breaking this into its own method
//it makes our class easier to extend
this.attach();
},
attach: function(){
//loop through the terms
this.terms.each(function(term, index) {
//add a click event to each one
term.addEvent('click', function(){
//that calls our toggle method for
//the current index
this.toggle(index);
}, this);
}, this);
},
toggle: function(index){
//toggle open the definition for the given index
this.definitions[index].slide('toggle');
}
});
</pre>
<p>
باز هم مقدار کدها بیشتر از نمونه jQuery شد. اگر ما همه خطهای توضیحی (comment lines) را حذف کنیم باز هم این پلاگین حدود دوازده خط بیشتر دارد. البته من می توانم ثابت کنم که چنین پلاگینی را می توان با تقریبا همین اندازه برای jQuery ایجاد کرد ولی به هر حال چرا این روش طولانی تر است؟ پاسخ اینطور خواهد بود که این کلاس بسیار انعطاف پذیرتر است. برای استفاده از کلاس، کافیست متد سازنده آن اجرا شود:
</p>
<pre class="js">var myFAQ = new FAQ(myContainer);
//and now we can call methods on it if we want:
myFAQ.toggle(2); //toggle the 3rd element
</pre>
<p>
ما می توانیم به همه متدها و مشخصه ها دسترسی داشته باشیم اما درباره AJAX چه باید کرد؟ مشکل ما با AJAX در پلاگین jQuery این بود که نمی توانستیم، افکت اسلاید را بعد از اتمام عملیات AJAX اجرا کنیم ولی در پلاگین MooTools، چنین مشکلی نداریم:
</p>
<pre class="js">FAQ.Ajax = new Class({
//this class inherits the properties of FAQ
Extends: FAQ,
//it also gets a new option in addition to the other defaults
//this one for url, that we're going to append the index of the
//term to; in reality we might make this more robust, but for
//this example it serves the purpose
options: {
url: null;
},
//we're going to cache the results, so if a section is opened
//twice, we won't hit the server for the data
indexesLoaded: [],
toggle: function(index){
//if we've already loaded the definition
if (this.indexesLoaded[index]) {
//just call the previous version of toggle
this.parent(index);
} else {
//otherwise, request the data from the server
new Request.HTML({
update: this.definitions[index],
url: this.options.url + index,
//and when the data is loaded, expand the definition
onComplete: function(){
this.indexesLoaded[index] = true;
this.definitions[index].slide('toggle');
}.bind(this)
}).send();
}
}
});
</pre>
<p>
حالا ما نسخه ای از کلاس FAQ داریم که اطلاعات را از سرور دریافت می کند. دقت کنید در این روش امکان استفاده از اسلاید بعد از بارگذاری کامل فراهم شد (کاری که در jQuery ممکن نشد) همچنین مدنظر داشته باشید که امکان اضافه شده جدید (AJAX) با تغییرات کمی در منطق اصلی صورت گرفت. این مدل توسعه ای، امکان ایجاد مجموعه ای از پلاگینهای مرتبط به هم ولی متفاوت را به سادگی فراهم می کند. همچنین شما قادر می شوید تا با تغییر اندک (نه اساسی) پلاگین های آماده دیگر را برای نیاز خود شخصی کنید. این پاسخ به این ابهام است که چرا وقتی در جستجوی پلاگین هایی مثل date picker یا tab interface برای MooTools هستید، با نتایج کمی روبرو می شوید. علت این است که اکثر پلاگین های آماده یا مشکل شما را کامل حل خواهند کرد یا این منظور با کمی تغییر و توسعه حاصل می شود.
</p>
<p>
همانطور که قبلا تاکید کردم، طراحی مجموعه ای از ابزارها و امکانات توسط jQuery امکانپذیر است ولی اکثر کدهایی که برای این منظور نوشته می شوند، ارتباطی با DOM (بخش تسلط jQuery) ندارد و کدهای معمولی جاوااسکریپت خواهد بود. اما مدل jQuery، برای توسعه این نمونه ها به کلاسهای زیرمجموعه، و برای مدل Mixin که استفاده چندباره کدها را آسان می کند، روشی را معرفی نمی کند. و در آخر اینکه پلاگینهای jQuery همیشه برای اجزاء DOM کار می کنند و اگر لازم باشد تا پردازش بر روی چیزی خارج از DOM مثل یک URL انجام گیرد، باید کدهای آن را خودتان بنویسید.
</p>
<a name="conclusion"></a>
<h2>زمان انتخاب</h2>
<p>
jQuery بر روی قابل فهم بودن و سادگی و سرعت کدنویسی برای DOM تمرکز دارد و MooTools بر روی توسعه، ارث بری، خوانایی، قابلیت استفاده چندباره کدها و خصوصیت حمل بالا تاکید دارد (مترجم: خصوصیت حمل در برنامه نویسی، به امکان کار بر روی کدها – چه استفاده، چه توسعه – در محیطهای مختلف، با شرایط مختلف اطلاق می گردد). اگر این دو فریم ورک را در دو کفه ترازو قرار دهیم، کفه jQuery را می توان اینگونه معرفی کرد: قابلیت فراگیری آسان و مشاهده فوری نتایج اما (براساس تجربیات من) قابلیت کم چندبار مصرفی و عدم حمل بالا (البته این کاملا به شما بستگی دارد و فی نفسه مشکل jQuery محسوب نمی گردد) در حالیکه کفه MooTools بیانگر این خصوصیات است: یادگیری دشوارتر، صرف زمان و کدنویسی بیشتر برای حصول نتایج، قابلیت استفاده چندباره و حمل بالا.
<p>
به علاوه هسته MooTools همه قابلیتهایی که در تصور شماست یا در هسته jQuery موجود است را شامل نمی شود. هر دو فریم ورک ترجیح بر تولید پلاگینها و توسعه هایی دارند که توسط شما و سایر برنامه نویسان ایجاد می شود. وظیفه آنها فراهم کردن هر امکانی که شما نیاز دارید، نیست بلکه با ایجاد ابزاری برای تولید امکانات متفاوت، شما را به طراحی آنها ترغیب می کنند. بطورکلی این قدرت جاوااسکریپت و فریم ورکهای آن است که MooTools و jQuery در حصول آن تلاش می کنند. MooTools دسترسی کلی تری را فراهم کرده و ابزار نگارش هر قابلیتی را به شما می دهد حتی فراتر از محدوده DOM اما تلاش بیشتری را برای یادگــیری و تســـلط می طلبد. دید کلی و توسعه پذیری MooTools، سطح قابل توجهی از امکانات jQuery را تحت قلمرو خود قرار داده. اما jQuery تمرکز و فوکوس خود را معطوف توابع و APIهای جذاب DOM کرده اما در عین حال مثل MooTools شما را از توسعه اشیاء محلی و ارث بری در جاوااسکریپت منع نکرده است.
</p>
<p>
این دقیقا دلیل این گفته من است که هر کدام از آنها، به تنهایی گزینه کاملی هستند. تلاش من در این مقاله بیان تفاوتهای موجود در فلسفه کدهای آنها و نشان دادن مزایا و معایب این دو فریم ورک بود. من از موفقیت در دخیل نکردن سلیقه شخصی نزدیک به MooTools خود، در این مقاله مطمئن نیستم؛ اما امیدوارم که مقاله سودمندی بوده باشد. امیدوارم، صرفنظر از اینکه چه فریم ورکی را انتخاب می کنید، هر دوی آنها را بخوبی شناخته باشید. اگر وقت آزاد داریــد، من به شــدت توصیـــه می کنم تا سایتی را با هر یک از آنها ایجاد کنید. نقطه نظر شما از انجام یک پروژه با دو فریم ورک می تواند، نکته ای که من از قلم انداخته ام را به این مقاله بیافزاید.
</p>
<p>سابقه تغییرات این مقاله در <a href="http://github.com/anutron/jquery-vs-mootools/tree/master">github</a> قابل دسترسی است.</p>
<p>
<script type="text/javascript" src="http://w.sharethis.com/button/sharethis.js#publisher=c327065b-efa0-4e12-afbc-5717f5cf62f9&type=website&post_services=facebook%2Cdigg%2Cdelicious%2Ctwitter%2Creddit%2Cfriendfeed%2Cmyspace%2Cybuzz%2Cstumbleupon%2Ctechnorati%2Cmixx%2Cblogger%2Cwordpress%2Ctypepad%2Cgoogle_bmarks%2Cwindows_live%2Cfark%2Cbus_exchange%2Cpropeller%2Cnewsvine%2Clinkedin"></script>
</p>
<hr/>
<p class="about">
درباره من: من یکی از اعضای اصلی <a href="http://www.mootools.net">MooTools</a> هستم و در وبلاگ خود <a href="http://www.clientcide.com">Clientcide</a> درباره جاوااسکریپت و موارد دیگر مطلب می نویسم همچنین <a href="http://www.clientcide.com/js">پلاگین های بسیار زیادی برای MooTools</a> ایجاد کرده ام. من مؤلف کتاب <a href="http://www.amazon.com/gp/product/1430209836?ie=UTF8&tag=clientside-20&link_code=as3&camp=211189&creative=373489&creativeASIN=1430209836">MooTools Essentials</a> و <a href="http://www.mootorial.com">آموزش آنلاین MooTools</a> هستم. من در یک شرکت با نام <a href="http://www.cloudera.com">Cloudera</a> واقع در SF Bay Area فعالیت می کنم. و <a href="http://www.clientcide.com/shout-out">از اینجا قابل دسترسی هستم</a>.
</p>
<a name="discussion"></a>
<hr/>
<p class="about" style="color: #700"><strong>نکته ای برای ثبت دیدگاه</strong>: نظرات ثبت شده، همگی بررسی می گردند و هیچ نظری بدون تایید منتشر نمی شود. نظرات بی محتوا (جنجالی یا بی ادبانه و غیره) یا طرفدارانه مثل "فریم ورک X از فریم ورک Y بهتر است چون..." نیز منتشر نخواهند شد.
</p>
<div id="disqus_thread"></div>
<script>
var disqus_url = "http://jqueryvsmootools.com/";
</script>
<script type="text/javascript" src="http://disqus.com/forums/jqueryvsmootools/embed.js"></script>
</div>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-539314-11");
pageTracker._trackPageview();
} catch(err) {}</script>
<script type="text/javascript">
//<![CDATA[
(function() {
var links = document.getElementsByTagName('a');
var query = '?';
for(var i = 0; i < links.length; i++) {
if(links[i].href.indexOf('#disqus_thread') >= 0) {
query += 'url' + i + '=' + encodeURIComponent(links[i].href) + '&';
}
}
document.write('<script charset="utf-8" type="text/javascript" src="http://disqus.com/forums/jqueryvsmootools/get_num_replies.js' + query + '"></' + 'script>');
})();
//]]>
</script>
</body>
</html>