<script type="text/javascript"> var allCheckBoxSelector = '#<%=GridView_CashList.ClientID%> input[id*="CheckAll"]:checkbox'; var checkBoxSelector = '#<%=GridView_CashList.ClientID%> input[id*="CheckBox_Delete"]:checkbox'; function ToggleCheckUncheckAllOptionAsNeeded() { var totalCheckboxes = $(checkBoxSelector), checkedCheckboxes = totalCheckboxes.filter(":checked"), noCheckboxesAreChecked = (checkedCheckboxes.length === 0), allCheckboxesAreChecked = (totalCheckboxes.length === checkedCheckboxes.length); $(allCheckBoxSelector).attr('checked', allCheckboxesAreChecked); $('#<%=Button_Delete.ClientID%>').attr('disabled', noCheckboxesAreChecked); } $(document).ready(function () { $(allCheckBoxSelector).live('click', function () { $(checkBoxSelector).attr('checked', $(this).is(':checked')); ToggleCheckUncheckAllOptionAsNeeded(); }); $(checkBoxSelector).live('click', ToggleCheckUncheckAllOptionAsNeeded); ToggleCheckUncheckAllOptionAsNeeded(); }); </script>
ابتدا یک سرویس به نام BaseService ایجاد کنید:
angular.module('myApp').service('BaseService', function() { var BaseService = function(title) { this.title = title; }; BaseService.prototype.getMessage = function() { var self = this; return 'Hello ' + self.title; }; return BaseService; });
حال اگر ماژول و کنترلری جهت نمایش خروجی به صورت زیر ایجاد کنیم:
var app= angular.module('myApp', []); app.controller('myCtrl', function ($scope,BaseService) { var instance = new BaseService('Masoud'); $scope.title = instance.getMessage(); });
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" ng-app="myApp"> <head> <title></title> </head> <body ng-controller="myCtrl"> <div> {{title}} </div> </body> <script src="Scripts/jquery-2.1.1.min.js"></script> <script src="Scripts/angular.js"></script> <script src="App/app.js"></script> </html>
تا اینجای کار روال معمول تعاریف سرویس در انگولار بوده است. اما قصد داریم سرویس جدیدی را ایجاد نمایم تا خروجی سرویس قبلی را اندکی تغییر دهد. به جای اینکه سرویس قبلی را تغییر دهیم یا بدتر از آن سرویس جدیدی بسازیم و کدهای قبلی را در آن کپی کنیم کافیست به صورت زیر عمل نماییم:
app.service('ExtService', function(BaseService) { var ExtService = function() { BaseService.apply(this, arguments); }; ExtService.prototype = new BaseService(); ExtService.prototype.getMessage = function() { var self = this; return BaseService.prototype.getMessage.apply(this, arguments) + ' From Ext Service'; }; return ExtService; });
app.controller('myCtrl', function ($scope,BaseService , ExtService) { var baseInstance = new BaseService('Masoud'); var extInstance = new ExtService('Dotnettips'); $scope.title = baseInstance.getMessage() + ' and ' + extInstance.getMessage(); });
توابع سودمند
فراخوانی و استفاده از این توابع در ابتدا ممکن است کمی عجیب به نطر برسد. به مثال زیر دقت کنید که تابع سودمند () trim را فراخوانی کرده ایم.
$.trim(someString);
در صورتی که نوشتن علامت $ برای شما عجیب به نطر میرسد میتوانید شناسه دیگر با نام jQuery به کار ببرید. کد زیر دقیقا مانند بالا عمل میکند شاید درک آن راحتتر هم باشد.
jQuery.trim(someString);
بدیهی است که از jQuery یا $ تنها به عنوان فضای نامی که تابع ()trim در آن تعریف شده اند، استفاده شده باشد.
نکته: اگر چه در نوشتههای آنلاین jQuery، این عناصر به عنوان توابع سودمند در معرفی شده اند اما در حقیقت آنها متدهایی برای تابع ()$ میباشند.
عملکرد صفحه آماده (The document ready handler)
هنگامی که از Unobtrusive JavaScriptاستفاده میکنیم، رفتار از ساختار جدا میشود، بنابراین برای انجام عملیات روی عناصر صفحه باید منتظر بمانیم تا انها ایجاد شوند. برای رسیدن به این هدف، ما نیاز به راهی داریم که تا زمان ایجاد عناصر DOM روی صفحه منتظر بماند قبل از آن عملیات را اجرا کند.
به طور معمول از onload برای نمونههای window استفاده میشود، که پس از لود شدن کامل صفحه ، دستورها قابل اجرا میباشند. بنابراین ساختار کلی آن کدی مانند زیر خواهد بود:
window.onload = function() { $("table tr:nth-child(even)").addClass("even"); };
نوشتن کد به صورت بالا سبب میشود که کد پس از بارگذاری کامل صفحه اجرا شود. متاسفانه، مرورگرها تا بعد از ساخته شدن عناصر صفحه صبر نمیکنند، بلکه پس از ساخت درخت عناصر صفحه منتظر بارگذاری کامل منابع خارجی صفحه مانند تصاویر نیز میمانند و سپس آنها را در پنجره مرورگر نمایش میدهند. در نتیجه بازدید کننده زمان زیادی منتظر میماند تا رویداد onload تکمیل شود.
حتی بدتر از آن، زمانی است که اگر به طور مثال یکی از تصاویر با مشکل مواجه شود که زمان قابل توجهی صرف بارگذاری آن شود، کاربر باید تمام این مدت را صبر کند تا پس از آن بتواند با این صفحه کار کند. این نکته میتواند دلیلی برای استفاده نکردن از Unobtrusive JavaScriptبرای شروع کار باشد.
اما راه بهتری نیز وجود دارد، میتوانیم تنها زمانی که قسمت ساختار عناصر صفحه ترجمه شده و HTML به درخت عناصر تبدیل میشود، صبر کنیم . پس از آن کد مربوط به رفتارها را اجرا کنیم. رسیدن به این روش برای استفاده از Cross-Browser کمی مشکل است، اما به لطف jQuery و قدرت آن، این امر به سادگی امکان پذیر است و دیگر نیازی به منتظر ماندن برای بارگذاری منابع صفحه مانند تصاویر و ویدیوها نمیباشد. Syntax زیر نمونه ای از چنین حالتی است:
$(document).ready(function() { $("table tr:nth-child(even)").addClass("even"); });
ابتدا صفحه مورد نظر را به تابع ()$ ارسال کرده ایم، سپس هر زمان که آن صفحه آماده شد (Ready) ، تابع ارسال شده به آن اجرا خواهد شد. البته میتوان کد نوشته شده بالا را به شکل مختصرتری هم نوشت:
$(function() { $("table tr:nth-child(even)").addClass("even"); });
با ارسال تابع به ()$، ما مرورگر را مجبور میکنیم که برای اجرای کد تا زمانی که DOM کامل لود شود (فقط DOM لود شود) منتظر بماند. حتی بهتر از آن ما میتوانیم از این تکنیک چندین با در همان سند HTML استفاده کرده و مرورگر تمامی تابعهای مشخص شده توسط ما را به ترتیب اجرا خواهد کرد. (یعنی من در دیک صفحه میتوانم چنین بار تابع ()ready را فراخوانی کنم). در مقابل روش OnLoad پنجره فقط اجازه اجرای یکبار تابع را به ما میدهد.
این هم یکی دیگر از کارکردهای دیگر تابع ()$ میباشد. حال به یکی دیگر از امکاناتی که این تابع برای ما فراهم میکند دقت کنید.
ساختن اجزای DOM (ساختن عناصر صفحه)
یکی دیگر از کارهایی که تابع ()$ می تواند برای ما انجام دهد ایجاد کردن عناصر صفحه است. به این منظور ورودی تابع ()$ را یک رشته که حاوی دستور HTML مربوط به ساخت یک عنصر میباشد، قرار میدهیم. برای مثال دستور زیر یک تگ p ایجاد میکند:
$("<p>Hi there!</p>")
اما ایجاد یک عنصر DOM یا (سلسله مراتب عناصر DOM) برای ما به تنهایی سودمند نیست، و هدف ما چیز دیگری است. ایجاد اشیا صفحه توسط ()$ زمانی برای ما مفید خواهد بود که بخواهیم به هنگام ساخت، تابعی بروی آن اعمال کنیم یا به محض ساخت آن را به تابعی ارسال کنیم به کد زیر دقت کنید:
<html> <head> <title>Follow me!</title> <script type="text/javascript" src="../scripts/jquery-1.2.js"></script> <script type="text/javascript"> // در زمان Reday بودن صفحه عنصر مورد نظر ایجاد میشود $(function(){ $("<p>Hi there!</p>").insertAfter("#followMe"); }); </script> </head> <body> <p id="followMe">Follow me!</p> </body> </html>
در کد بالا زمانی که صفحه مورد نظر Ready شد تابع مورد نظر ما اجرا شده و در عناصر صفحه بعد از عنصری که id آن followMe میباشد یک عنصر p را ایجاد میکند. که خروجی آن شبیه تصویر زیر خواهد بود.
مزیت دیگر jQuery این است که در صورتی که امکانی را ندارد شما به آسانی میتوانید آن را توسعه داده و برای آن پلاگین طراحی کنید.
برای پایان دادن به این پست همانطور که دیدیم jQuery قادر به انجام کارهای زیر است:
- انتخاب عناصر و ایجاد مجموعه ای از آنها که آماده اعمال متدهای مختلف میباشند.
- استفاده به عنوان یک فضای نام برای توابع سودمند.
- ایجاد اشیا مختلف HTML بروی صفحه.
- اجرای کد به محض آماده شدن اشیای صفحه.
موفق وموید باشید
1. Attribute Routing
Config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{Controller}/{id}", defaults: new { id = RouteParameter.Optional } );
URI Pattern --> books/1/authors [Route("books/{bookId}/authors")] public IEnumerable<Author> GetAuthorByBook(int bookId) { ..... }
2. CORS - Cross Origin Resource Sharing
3. OWIN (Open Web Interface for .NET) self-hosting
OWIN یک اینترفیس استاندارد بین سرورهای دات نت و اپلیکیشنهای وب تعریف میکند. هدف این اینترفیس جداسازی (decoupling) سرور و اپلیکیشن است. تشویق به توسعه ماژولهای ساده برای توسعه اپلیکیشنهای وب دات نت. و بعنوان یک استاندارد باز (open standard) اکوسیستم نرم افزارهای متن باز را تحریک کند تا ابزار توسعه اپلیکیشنهای وب دات نت توسعه یابند.
4. IHttpActionResult
5. Web API OData
- expand$: بصورت نرمال، هنگام کوئری گرفتن از یک کالکشن OData، پاسخ سرور موجودیتهای مرتبط (related entities) را شامل نمیشود. با استفاده از expand$ میتوانیم موجودیتهای مرتبط را بصورت inline در پاسخ سرور دریافت کنیم.
- select$: از این متد برای انتخاب چند خاصیت بخصوص از پاسخ سرور استفاده میشود، بجای آنکه تمام خاصیتها بارگذاری شوند.
- value$: با این متد مقدار خام (raw) فیلدها را بدست میآورید، بجای دریافت آنها در فرمت OData.
چند مقاله خوب دیگر
MTOM در WCF
- Text(Xml) Message Encoder(به صورت پیش فرض در تمام Http-Base Bindingها از این Encoder استفاده میشود)
- Binary Message Encoder(به صورت پیش فرض در تمام Net* Bindingها از این encoder استفاده میشود که برای سرویسهای وب مناسب نیست)
- MTOM Message Encoder (در حالت استفاده از Http-Base Bindingها و انتقال اطلاعات به صورت باینری از این گزینه استفاده میشود که به صورت پیش فرض غیر فعال است)
»خاصیتی که نوع آن آرایه ای از بایتها است نباید دارای DataMemberAttribute باشد؛ بلکه به جای آن باید از MessageBodyMember استفاده نمایید.
»به جای []Byte میتوان از نوع Stream نیز استفاده کرد(الزامی نیست).
»مقدار خاصیت MessageEncoding در Binding استفاده شده باید MTOM تعیین شود.
ابتدا کلاس مورد نظر را به صورت زیر تهیه میکنیم:
[MessageContract] public class MyFile { [MessageHeader] public String Filename { get; set; } [MessageBodyMember] public Byte[] Contents { get; set; } }
- به جای DataContract از MessageContract استفاده میشود؛
- تمام خاصیت هایی که نوع آنها غیر از []Byte است باید دارای MessageHeader باشند؛
- خاصیتی که برای انتقال محتوای باینری تهیه شده است، باید از MessageBodyMember استفاده نماید؛
- مجاز به تعریف فیلد یا فیلد هایی که نوع آنها Primitive Type است نمیباشید.
تنظیمات مربوط به Binding نیز به صورت خواهد بود:
<bindings> <wsHttpBinding> <binding name="WsHttpMtomBinding" messageEncoding="Mtom" /> </wsHttpBinding> </bindings>
هدف از استفاده از MTOM برای افزایش کارایی انتقال دادههای باینری در حجم زیاد است. در زیر نتایج مقایسه بررسی انتقال اطلاعات به دو صورت MTOM و Text برای حجم دادههای متفاوت را مشاهده میکنید:
با دقت در نتایج بالا مشخص میشود که این روش در حجم دادههای پایین (مثل 100 بایت یا 1000 بایت) عملکرد مورد انتظار را نخواهد داشت. پس این نکته را نیز در هنگام پیاده سازی به این روش مد نظر داشته باشید.
<form action="/rest/login" method="POST"> <input name="username" required> <input type="password" name="password" required> </form>
محتوا یا content به معنای المانهایی هستند که درون یک المان قرار میگیرند. برای مثال در اینجا المان <form> دارای محتوایی متشکل از دو المان <input> است و دون المان <input> دارای محتوایی نیستند.
از ویژگیها و یا attributes، برای ارائهی اطلاعات بیشتر و یا تعیین حالت عناصر استفاده میشود. برای نمونه در اینجا المان <form> دارای دو ویژگی action و method است که برای ارائهی اطلاعاتی بیشتر جهت تعیین روش و محل ارسال اطلاعات به سرور از آنها استفاده میشود. همچنین میتوان ویژگیهای سفارشی را نیز توسط ویژگیهای شروع شدهی با -data نیز به المانها اضافه کرد که جزئی از استاندارد HTML 5 است. هرچند میتوان ویژگی کاملا غیرمتعارفی مانند myproject-uuid را نیز به یک المان اضافه کرد. این مورد مشکل خاصی را ایجاد نکرده و صفحه بدون مشکل رندر میشود؛ اما یک چنین صفحهای دیگر به عنوان یک صفحهی استاندارد HTML ارزیابی نخواهد شد؛ از این جهت که از ویژگی استفاده کردهاست که در هیچکدام از استانداردهای HTML ذکر نشدهاست.
آخرین نگارش HTML5 به همراه 4 ویژگی جدید دیگر نیز هست:
- Boolean attribute : مانند ویژگی required که به المانهای <input> قابل انتساب است. حضور این نوع ویژگیها بدون مقداری در یک المان
<input name=username required>
نمونهی دیگری از این نوع ویژگیها، ویژگی hidden است که به HTML 5.1 اضافه شدهاست و اگر به عنصری اضافه شود، آن المان رندر نخواهد شد.
- unquoted attribute: به این معنا که میتوان "" را از اطراف مقدار یک ویژگی حذف کرد:
<input name=username required>
- single-quoted and double-quoted attributes: که به معنای استفاده از "" و یا '' جهت تعیین مقدار یک ویژگی است.
تفاوت attributes با خواص المانها چیست؟
Attributes در تعریف تگ HTML یک عنصر ظاهر میشوند اما خواص، جزئی از تعریف شیء یک عنصر هستند.
<div class="bold">I'm a bold element</div>
<a href="http://www.site.com/blog/">Read the blog</a>
<script> document.querySelector('A').href = 'https://www.dntips.ir'; </script>
- برای مثال واژهی class در زبان جاوا اسکریپت یک واژهی کلیدی است. به همین جهت در اینجا اگر بخواهیم مقدار ویژگی class را تغییر دهیم باید از خاصیت className آن المان استفاده کنیم.
- مورد دوم ویژگی checked المانهای radio و checkbox است. این ویژگی فقط در ابتدای کار این المانها به آنها متصل میشود:
<input type="checkbox" checked> <script> // this does not remove the checked attribute document.querySelector('INPUT').checked = false; </script>
- تمام ویژگیهای غیراستانداردی که تعریف شوند، دارای خاصیت متناظری در آن المان نخواهند بود، اما به آنها expando properties گفته میشود.
یافتن المانها بر اساس ویژگیهای آنها
از آنجائیکه attribute selectors در استاندارد W3C CSS 2 معرفی شدهاند، امکان کار با آنها از زمان IE 8.0 میسر بودهاست و برای کار با آنها الزاما نیازی به استفاده از jQuery نیست!
یافتن المانها بر اساس نام ویژگیها
<form action="/submitHandler" method="POST"> <input name="first-name"> <input name="last-name" required> <input type="email" name="email" required> <button disabled>submit</button> </form>
var $result = $('[required], [disabled]');
var result = document.querySelectorAll('[required], [disabled]');
در اینجا باید دقت داشت که این جستجو صرفا بر اساس نام ویژگیها انجام میشود؛ حتی اگر این ویژگی دارای مقداری نباشد:
<div class="bold">I'm bold</div> <span class>I'm not</span>
var result = document.querySelectorAll('[class]');
یافتن المانها بر اساس نام و مقدار ویژگیها
<section> <h2>Sites</h2> <ul> <li> <a href="https://www.dntips.ir/">dotnettips</a> </li> <li> <a href="https://google.com/">Google</a> </li> </ul> </section>
var $result = $('A[href="https://www.dntips.ir/"]');
var result = document.querySelectorAll('A[href="https://www.dntips.ir/"]');
و یا اگر اینبار بخواهیم تمام ویژگیهای کلاسی که دارای مقدار هستند را انتخاب کنیم، روش آن با استفاده از exclusion selector به صورت زیر است:
var result = document.querySelectorAll('[class]:not([class=""]');
یافتن المانها بر اساس نام و قسمتی از مقدار ویژگیها
<a href="https://www.dntips.ir/">home page</a> <a href="https://www.dntips.ir/postsarchive">articles</a> <a href="https://www.dntips.ir/newsarchive">news</a>
var result = document.querySelectorAll('A[href*="www.dotnettips.info"]');
یافتن المانها بر اساس نام و کلمهای مشخص در مقدار ویژگیها
<div class="one two three">1 2 3</div> <div class="onetwothree">123</div>
var result = document.querySelectorAll('[class∼=two]');
در اینجا نوع دیگری از کوئری را هم میتوان مطرح کرد: آیا المانی مشخص، دارای کلاس two است؟
روش انجام آن در jQuery به صورت زیر است:
var hasTwoClass = $divEl.hasClass('two');
var hasTwoClass = divEl.classList.contains('two');
همچنین خاصیت classList به همراه متدهای استاندارد add و remove نیز هست که معادل متدهای addClass و removeClass جیکوئری هستند.
divEl.classList.remove('red'); divEl.classList.add('blue');
// removes "hide" class divEl.classList.toggle('hide'); // re-adds "hide" class divEl.classList.toggle('hide');
یافتن المانها بر اساس نام و شروع یا خاتمهی عبارتی مشخص در مقدار ویژگیها
<img id="cat" src="/images/cat.gif"> <img id="zebra" src="zebra.gif"> <a href="#zebra">watch the zebra</a> <a href="/logout">logout</a>
var result = document.querySelectorAll('A[href^="#"], [src$=".gif"]');
خواندن مقادیر ویژگیها
<input type="password" name="user-password" required>
// returns "password" $inputEl.attr('type'); // returns "true" $inputEl.is('[required]');
// returns "password" inputEl.getAttribute('type'); // returns "true" inputEl.hasAttribute('required');
تغییر مقدار ویژگیها
<input name="temp" required>
روش انجام اینکار در جیکوئری:
$inputEl .attr('type', 'email') // #1 .removeAttr('required') // #2 .attr('name', 'userEmail'); // #3
inputEl.setAttribute('type', 'email'); // #1 inputEl.removeAttribute('required'); // #2 inputEl.setAttribute('name', 'userEmail'); // #3
آموزش TypeScript #3
تعریف متغیرها و انواع داده
در TypeScript هنگام تعریف متغیرها باید نوع داده ای آنها را مشخص کنیم. در TypeScript پنج نوع داده ای وجود دارد که در زیر با ذکر مثال تعریف شده اند. مفاهیم ماژول، کلاس و تابع در پست بعدی به تشریح توضیح داده خواهند شد.
number : معادل نوع داده ای number در JavaScript است. برای ذخیره سازی اعداد صحیح و اعشاری استفاده میشود.
یک مثال:
class NumberTypeOfTypeScript { MyFunction() { var p: number; p = 1; var q = 2; var r = 3.33; alert("Value of P=" + p + " Value of q=" + q + " Value of r=" + r); } } window.onload = () =>{ var value = new NumberTypeOfTypeScript(); value.MyFunction(); }
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8" /> <title>TypeScript HTML App</title> <link rel="stylesheet" href="app.css" type="text/css" /> <script src="app.js"></script> </head> <body> <h1>Number Type in TypeScript</h1> <div id="content"/> </body> </html>
string : معادل نوع داده ای رشته ای است و برای ذخیره سازی مجموعه ای از کاراکترها از نوع UTF-16 استفاده میشود.
یک مثال:
class StringTypeOfTypeScript { Myfunction() { var s: string; s="TypeScript" var empty = ""; var abc = "abc"; alert("Value of s="+ s+" Empty string="+ empty+" Value of abc ="+abc) ; } } window.onload = () =>{ var value = new StringTypeOfTypeScript(); value.Myfunction(); }
var StringTypeOfTypeScript = (function () { function StringTypeOfTypeScript() { } StringTypeOfTypeScript.prototype.Myfunction = function () { var s; s = "TypeScript"; var empty = ""; var abc = "abc"; alert("Value of s=" + s + " Empty string=" + empty + " Value of abc =" + abc); }; return StringTypeOfTypeScript; })(); window.onload = function () { var value = new StringTypeOfTypeScript(); value.Myfunction(); };
boolean: برای ذخیره سازی مقادیر true یا false میباشد.
مثال:
class booleanTypeofTypeScript { MyFunction() { var lie: bool; lie = false; var a = 12; if (typeof (lie) == "boolean" && typeof (a) == "boolean") { alert("Both is boolean type"); } if (typeof (lie) == "boolean" && typeof (a) != "boolean") { alert("lie is boolean type and a is not!") } else { alert("a is boolean type and lie is not!"); } } } window.onload =()=> { var access = new booleanTypeofTypeScript(); access.MyFunction(); }
var booleanTypeofTypeScript = (function () { function booleanTypeofTypeScript() { } booleanTypeofTypeScript.prototype.MyFunction = function () { var lie; lie = false; var a = 12; if(typeof (lie) == "boolean" && typeof (a) == "boolean") { alert("Both is boolean type"); } if(typeof (lie) == "boolean" && typeof (a) != "boolean") { alert("lie is boolean type and a is not!"); } else { alert("a is boolean type and lie is not!"); } }; return booleanTypeofTypeScript; })(); window.onload = function () { var access = new booleanTypeofTypeScript(); access.MyFunction(); };
مثال:
class NullTypeinTypeScript { MyFunction() { var p: number = null; var x = null; if (p== null) { alert("p has null value!"); } else { alert("p has a value"); } } } window.onload = () =>{ var value = new NullTypeinTypeScript(); value.MyFunction(); }
var NullTypeinTypeScript = (function () { function NullTypeinTypeScript() { } NullTypeinTypeScript.prototype.MyFunction = function () { var p = null; var x = null; if(p == null) { alert("p has null value!"); } else { alert("p has a value"); } }; return NullTypeinTypeScript; })(); window.onload = function () { var value = new NullTypeinTypeScript(); value.MyFunction(); };
undefined:معادل نوع undefined در Javascript است. اگر به یک متغیر مقدار اختصاص ندهید مقدار آن undefined خواهد بود.
مثال:
class UndefinedTypeOfTypeScript { Myfunction() { var p: number; var x = undefined; if (p == undefined && x == undefined) { alert("p and x is undefined"); } else { alert("p and c cannot undefined"); } } } window.onload = () =>{ var value = new UndefinedTypeOfTypeScript(); value.Myfunction(); }
var UndefinedTypeOfTypeScript = (function () { function UndefinedTypeOfTypeScript() { } UndefinedTypeOfTypeScript.prototype.Myfunction = function () { var p; var x = undefined; if(p == undefined && x == undefined) { alert("p and x is undefined"); } else { alert("p and c cannot undefined"); } }; return UndefinedTypeOfTypeScript; })(); window.onload = function () { var value = new UndefinedTypeOfTypeScript(); value.Myfunction(); };
ادامه دارد...
- توابع خط فرمان - Command Line API
- توابع کنسول - Console API
<div id="first" class="content">Content1 with css class and id</div> <div class="content"> Content2 with css class <a class="links" href="#">Link1</a> <a href="#">Link2</a> </div> <div> Content3 without css class and id </div> <input type="button" onclick="myFunc()" value="Run myFunc" /> <input type="text" id="myInput" /> <script type="text/javascript"> function myFunc() { loop(1000); loop(50000); } function loop(number) { for (var i = 0; i < number; i++) { } } </script>
$$("div.content");
profile("myFunc Testing"); myFunc(); profileEnd();
- $(id)
معادل دستور document.getElementById است که یک المنت با id داده شده بر میگرداند .
$("first");
- $$(selector)
آرایه ای از المنتهای مطابق با selector داده شده بر میگرداند .
$$("div.content")
به تفاوت دو دستور توجه کنید . خروجی دستور اول ، یک المنت است و خروجی دستور دوم یک آرایه از المنت که بین [ و ] قرار گرفته اند .
برای آشنایی بیشتر با CSS Seletorها به این لینک مراجعه کنید : http://www.w3.org/TR/css3-selectors
- $x(xPathExpression)
آرایه ای از المنت هایی را بر میگرداند که با xPath داده شده مطابقت داشته باشند .
var objects = $x("html/body/div[2]/a") for(var i = 0; i < objects.length; i++) { console.log(objects[i]); }
برای آشنایی بیشتر با عبارات xPath به این لینک مراجعه کنید : http://www.w3schools.com/xpath
- dir(object)
تمام خصوصیات شیء ارسال شده را لیست میکند .
var objects = $x("html/body/div[2]/a") dir(objects);
- dirxml(node)
سورس یک المنت را بصورت درختواره ( tree ) پرینت میکند . همچنین با کلیک بروی هر node ، فایرباگ آن node را در تب html نمایش میدهد .
var node = $("first"); dirxml(node);
توجه کنید که این دستور فقط یک node دریافت میکند . برای همین اگر از دستور $$("#first") استفاده میکنید ، چون این دستور یک آرایه بر میگرداند ، باید اولین عضو آرایه را دریافت و ارسال کنید .
یعنی :
var node = $$("#first")[0]; dirxml(node);
- clear()
این دستور محیط console را خالی میکند . عملکرد این دستور معادل کلیک دکمهی Clear ( در بالا - چپ تب کنسول ) است .
- inspect(object[,tabName])
توسط این دستور میتوانید یک شیء را در مناسبترین تب فایرباگ یا یکی از تبهای مورد نظر خود ، Inspect کنید .
var node = $("first"); inspect(node); // inspect in html tab inspect(node,'dom'); // inspect in dom tab
- keys(object)
آرایه ای از "نام" تمام خصوصیات شیء ارسال شده بر میگرداند .
var obj = $("first"); keys(obj)
- values(object)
آرایه ای از "مقدار" تمام خصوصیات شیء ارسال شده بر میگرداند .
var obj = $("first"); values(obj)
- debug(fn) and undebug(fn)
این متدها یک BreakPoint در ابتدای تابع مشخص شده اضافه/حذف میکنند . ( در تب Script ) . به همین ترتیب هنگامی که تابع مورد نظر فراخوانی شود ، در نقطه ای که BreakPoint قرار داده شده توقف خواهد کرد .
البته میشود BreakPoint را دستی هم قرار داد . در اصل این تابع ، این عملیات را سادهتر میکند .
debug(myFunc); myFunc(); undebug(myFunc);
- monitor(fn) and unmonitor(fn)
این متدها برای فعال/غیرفعال کردن Logging فراخوانیهای یک تابع استفاده میشوند .
در حالت عادی برای پی بردن به اینکه یک تابع اجرا میشود یا نه ، در تابع مورد نظر یک alert قرار میدهیم و تست میکنیم . که این روش در برنامه برنامههای بزرگ صحیح نیست . زیرا در این حالت باید بین حجم زیادی کد به دنبال تابع مورد نظر بگردیم و سپس alert را قرار بدهیم و بعد اطمینان از صحت عملکرد تابع مجدد آن را حذف کرد ، که با اتلاف زمان و به خطر انداختن کدها همراه است .
اما با استفاده از این متدها ، تنها نیاز به داشتن اسم تابع داریم ( و نه مکان تابع در کدهای برنامه ) .
تست monitor :
monitor(myFunc); // now click on "Run myFunc" button
unmonitor(myFunc); // now click on "Run myFunc" button
- monitorEvents(object[, types]) and unmonitorEvents(object[, types])
این متدها عملیات Event Logging برای یک شیء را فعال/غیرفعال میکنند . در کنار شیء مورد نظر ، میتوان نوع رویداد را هم به متد ارسال کرد . در این صورت عملیات Logging فقط برای همان گروه رویداد/رویداد ، فعال/غیرفعال میشود .
منظور از گروه رویداد ، مجموعه رویدادهای یک شیء است . مثلا mousemove , moseover , mousedown , ... در گروه mouse قرار میگیرند . یعنی میتوانید با ارسال کلمهی mouse فقط رویدادهای mouse را تحت نظر بگیرید یا اینکه فقط یک رویداد را مشخص کنید ، مثل mousedown .
راه سادهتر فعال کردن Event Logging ، رفتن به تب Html ، راست کلیک کردن بروی المنت مورد نظر و فعال کردن گزینهی Log Events میباشد .
var obj = $("myInput"); monitorEvents(obj,'keypress');
نتیجه پس از فشردن چند دکمهی کیبورد در myInput :
توضیحات بیشتر : http://getfirebug.com/wiki/index.php/MonitorEvents - profile([title]) and profileEnd()
این متدها ، JavaScript Profiler را فعال/غیرفعال میکنند . هنگام فعال کردن میتوانید یک عنوان هم برای پروفایل مشخص کنید . در قسمت قبلی مقاله در مورد این قابلیت توضیحاتی ارائه شد .
سه را برای اجرای Profiler وجود دارد :
1 - کلیک بروی دکمهی Profiler در بالای تب کنسول .
2 - استفاده از کد console.profile("ProfileTitle") در کدهای جاوا اسکریپت .
3 - استفاده از متد profile("Profile Title") در خط فرمان .
profile("myFunc Testing"); myFunc(); profileEnd();
ستونهای Profiler :Function : نام تابع اجرا شده .
Calls : تعداد دفعات فراخوانی تابع .
Percent : زمان اجرای تابع در زمان کل ، به درصد .
Own Time : زمان اجرای تابع به تنهایی . برای مثال در کد ما ، زمان اجرای تابع myFunc به تنهایی تقریبا صفر است زیرا عمیاتی در خود انجام نمیدهد و زمان صرف شده در این تابع ، برای اجرای 2 با تابع loop است . این زمان ( Own Time ) زمان اجرای تابع ، منهای زمان صرف شده برای فراخوانی توابع دیگر است .
Time : زمان اجرای تابع از نقطهی آغاز تا پایان . مجموع زمان اجرای خود تابع به همراه زمان اجرای توابع فراخوانی شده . در کد ما ، این زمان ، مجموع زمان اجرای خود تابع به همراه دو بار فراخوانی تابع loop است .
Avg : میانگین زمان اجرای هربار تابع . فرمول : Avg = Time / Calls
Min & Max : حداقل و حداکثر زمان اجرای تابع .
File : نام فایل و شماره خطی که تابع در آن قرار دارد .
اجزای جاوا اسکریپتی بوت استرپ 3
پنلها و آکاردئونها
پنلهای آکاردئونی، بسیار شبیه به برگهها عمل میکنند. با کلیک بر روی یک سربرگ، محتوای مخفی شده آن نمایش داده میشود. این اعمال نیز توسط اجزای جاوا اسکریپتی بوت استرپ، به کمک jQuery عمل میکنند.
یک مثال:
<div class="container"> <h4 class="alert alert-info"> پنل آکاردئونی</h4> <div class="row"> <div class="panel-group" id="accordion"> <div class="panel panel-default"> <div class="panel-heading"> <h4 class="panel-title"> <a href="#vacc" class="accordion-toggle" data-toggle="collapse" data-parent="#accordion"> <span class="glyphicon glyphicon-pushpin"></span>اطلاعات یک</a> </h4> </div> <div id="vacc" class="panel-collapse collapse in"> <div class="panel-body"> <p> متن متن متن متن .......</p> <p> <a href="#" class="btn btn-info">بیشتر >></a></p> </div> </div> </div> <div class="panel panel-default"> <div class="panel-heading"> <h4 class="panel-title"> <a href="#checkups" class="accordion-toggle" data-toggle="collapse" data-parent="#accordion"> <span class="glyphicon glyphicon-ok"></span>اطلاعات 2</a> </h4> </div> <div id="checkups" class="panel-collapse collapse"> <div class="panel-body"> <p> متن متن متن متن .......</p> <p> <a href="#" class="btn btn-info">بیشتر >></a></p> </div> </div> </div> </div> <!-- end accordion --> </div> <!-- end row --> </div> <!-- /container -->
توضیحات:
- ابتدا کل ناحیه مدنظر باید در یک div با کلاس panel-group محصور شود؛ به همراه یک id دلخواه. از این id در ویژگیهای data-parent عنوانهای هر پنل این گروه استفاده میشود. به این ترتیب سیستم جاوا اسکریپتی آن متوجه خواهد شد که باید داخل چه ناحیهای از صفحه عمل کند.
- پس از مشخص سازی آغاز پنل گروهی مدنظر، هر گروه، داخل یک div با کلاس panel panel-default قرار خواهد گرفت. به این ترتیب اولین پنل آکاردئونی مثال، شکل میگیرد.
- سپس داخل هر پنل مجزا، باید توسط panel-heading مشخص کنیم که عنوان این پنل و محتوای خاص این عنوان کجا باید قرار گیرند. همچنین به کمک panel-collapse collapse in، محتوایی را که با کلیک بر روی عنوان هر پنل به صورت خودکار ظاهر خواهد شد را معرفی میکنیم.
در ادامه میتوان پنلهای بیشتری را به این مجموعه و گروه افزود.
- پنلی که قرار است در ابتدای کار باز باشد، دارای کلاس collapse in خواهد بود؛ مابقی فقط collapse دارند.
بررسی کامپوننت Carousels
بوت استرپ به همراه کامپوننت اسلایدشو توکاری است به نام Carousel که بدون نیاز به حتی یک سطر کدنویسی جاوا اسکریپت اضافی، یک اسلاید شو بسیار حرفهای را ارائه میدهد. مثالی را در این مورد در ادامه ملاحظه میکنید:
<div class="container"> <h4 class="alert alert-info"> اسلاید شو</h4> <div class="row"> <div id="myCarousel" class="carousel slide"> <ol class="carousel-indicators"> <li data-target="#myCarousel" data-slide-to="0" class="active"></li> <li data-target="#myCarousel" data-slide-to="1"></li> <li data-target="#myCarousel" data-slide-to="2"></li> </ol> <!-- carousel-indicators --> <section class="carousel-inner"> <div class="active item"> <img src="images/01.jpg" alt="Photo 1"></div> <div class="item"> <img src="images/02.png" alt="Photo 2"></div> <div class="item"> <img src="images/03.jpg" alt="Photo 3"></div> </section><!-- carousel-inner --> <a href="#myCarousel" class="left carousel-control" data-slide="prev"><span class="glyphicon glyphicon-chevron-left"> </span></a><a href="#myCarousel" class="right carousel-control" data-slide="next"><span class="glyphicon glyphicon-chevron-right"></span></a> </div> <!-- myCarousel --> </div> <!-- end row --> </div>
توضیحات:
- در قسمت carousel-inner این کامپوننت، لیست تک تک تصاویر مورد نیاز قرار خواهند گرفت. تصویر آغازین دارای div ایی محصور کننده با کلاس active item است و مابقی کلاس item دارند.
- مرحله بعد، کار افزودن سیستم راهبری و حرکت بین تصاویر اضافه شده است. این سیستم چیزی نیست جز چند لینک مزین شده با کلاسهای left carousel-control و همچنین right carousel-control. ویژگیهای data-slide این لینکها نیز مشخص کننده اعمالی هستند که کامپوننت جاوا اسکریپتی carousel قرار است انجام دهد. برای مثال حرکت به قبل یا بعد. همچنین باید دقت داشت که href این لینکها به id مرتبط با div اصلی دربرگیرنده این قسمت از صفحه اشاره میکند. از یک سری گلیف آیکن نیز برای نمایش فلش رو به چپ و راست نیز در اینجا استفاده شده است.
- قسمت لیست مرتبط دارای کلاس carousel-indicators، در حقیقت مشخص کننده سه دایره کوچکی است که در تصویر فوق ملاحظه میکنید. به ازای هر تصویر، یک مورد را باید افزود. در اینجا data-target هر آیتم به id مرتبط با div محصور کننده کل اسلایدشو اشاره میکند. data-slide-toها به شماره تصویر متناظر هر آیتم متصل خواهند شد. ایندکس آغازین این آیتمها از صفر شروع میشود.
بررسی کامپوننت Scroll spy
اگر به مستندات رسمی بوت استرپ مراجعه کنید، منوی کنار صفحه با لغزش صفحه به سمت پایین ثابت است؛ اما به ازای هر سرفصل جدیدی در صفحه، آیتم فعال این منو نیز به صورت خودکار تغییر میکند. این قابلیت توسط کامپوننت Scroll spy ایجاد شده است. یک مثال:
<body id="articles" data-spy="scroll" data-target=".scrollspy"> <div class="container"> <h4 class="alert alert-info"> Scroll spy</h4> <div id="articlesindex" class="row"> <section class="scrollspy clearfix col col-lg-3 hidden-sm"> <ul class="nav nav-list affix"> <li><a href="#item1"><span class="glyphicon glyphicon-user"></span>Item 1</a></li> <li><a href="#item2"><span class="glyphicon glyphicon-user"></span>Item 2</a></li> <li><a href="#item3"><span class="glyphicon glyphicon-user"></span>Item 3</a></li> </ul> <!-- nav-list --> </section><!-- scrollspy --> <section class="col col-lg-9"> <article id="item1" class="media"> <h2> item1</h2> <div class="media-body"> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> </div> </article> <article id="item2" class="media"> <h2> item2</h2> <div class="media-body"> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> </div> </article> <article id="item3" class="media"> <h2> item3</h2> <div class="media-body"> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> <p> متن متن متن ............متن متن متن ............متن متن متن .............</p> </div> </article> </section><!-- artistinfo --> </div> <!-- end row --> </div> <!-- /container --> <script type="text/javascript" src="Scripts/jquery-1.10.2.min.js"></script> <script type="text/javascript" src="Scripts/bootstrap-rtl.js"></script> </body>
توضیحات:
- کار با ایجاد یک section جدید که حاوی منوی ثابت کنار صفحه است، شروع میشود. این section دارای کلاس scrollspy میباشد. داخل این section لیست عناوین منو قرار میگیرند که ul آن دارای کلاس nav nav-list affix خواهد بود. affix سبب میشود تا این لیست در کنار صفحه ثابت نمایش داده شود و همواره نمایان باشد.
- نکته مهم لیست آیتمهای منو، مقادیر href لینکهای آن است. این مقادیر باید به id محتوای متناظر اشاره کنند. این محتواها را در ادامهی کار ملاحظه میکنید.
- به علاوه اگر به تگ body در ابتدای کار دقت کرده باشید، ویژگیهای data-spy و هدفی که قرار است تحت نظر قرار گیرد به آن اضافه شدهاست.
- تا اینجا این سیستم کار میکند؛ اما اگر صفحه را به بالا و پایین حرکت دهید، پس زمینه آیتم فعال، تغییر رنگ نمیدهد. برای این منظور نیاز است، به CSS سفارشی خود، چند سطر ذیل را اضافه کرد:
.scrollspy .nav > li.active{ background: lightgray; }
فایلهای نهایی این قسمت را از اینجا نیز میتوانید دریافت کنید:
bs3-sample04.zip
در بعضی از سایتها با استفاده از جاوا اسکریپت تاریخ و ساعت جاری سیستم کلاینت به او نشان داه میشود.
این روش یک مزیت دارد: اول اینکه این کدها سمت کلاینت اجرا میشن و برای سرور بار اضافی ایجاد نمیکنن.
و یک عیب هم دارد: در صورتی که ساعت و تاریخ روی سیستم کلاینت تنظیم نباشد، همین ساعت و تاریخ نادرست برای او نمایش داده میشود. همین عیب میتواند باعث افت کیفیت وب سایت شود.
اما راهی هست که تاریخ و ساعت سیستم سرور برای کاربر نشان داده شود و آن هم استفاده از JQuery Ajax هست. به صورتی که هر ثانیه درخواستی برای یک handler فرستاده میشود و آن handler نیز ساعت و تاریخ روی سرور را باز میگرداند و این مقدار بازگشته شده را میتوان در تگی از صفحه وب نمایش داد.
مثال: ابتدا یک صفحه aspx میسازیم و تگ زیر را در آن قرار میدهیم:
<p id="datetime"></p>
سپس کدهای اسکریپت زیر را مینویسیم:
var auto_referesh = setInterval ( function() { $.post ( "GetDateTime.ashx", function (result) { $('#datetime').html(result); } ); }, 1000
);
کد استفاده شده در handler هم به این صورت است:
<%@ WebHandler Language="C#" Class="GetDateTime" %> using System; using System.Web; public class GetDateTime : IHttpHandler { public void ProcessRequest (HttpContext context) { context.Response.ContentType = "text/plain"; context.Response.Write(DateTime.Now.ToString()); } public bool IsReusable { get { return false; } } }
AjaxDateTime.zip