- استفاده از شبیه سازها مانند Virtual Box یا VMWare
- استفاده از نسخه دستکاری شده که بتوانید بر روی سیستم سخت افزاری خود نصب کنید
- استفاده از فایل ISO همانند ویندوز
- استفاده از فایل VMDK آماده
- ایجاد ایمیج از روی فایل DMG
در مراحل مختلف، سوالات متعددی برای آماده سازی ماشین مجازی از شما پرسیده خواهد شد. نام آن را Mac قرار دهید. از کادر انتخابی Type، گزینه Mac OS را انتخاب کرده و نسخه 10.13 High Sierra را انتخاب کنید.
در صفحه بعدی شما میزان RAM ای را که به سیستم عامل میهمان اختصاص میدهید، باید مشخص کنید. حداقل 4 گیگابایت رم به سیستم عامل میهمان اختصاص دهید. دقت داشته باشید که میزان آن 50 الی 65 درصد از کل رم سیستم تان باشد.
در مرحله بعدی شما باید تنظیمات مربوط به هارد دیسک را انجام دهید. گزینه “use an existing virtual hard disk file” را انتخاب کنید. سپس فایلی را که در مرحله قبلی با پسوند VMDK دانلود کردهاید، انتخاب کنید.
نهایتا بر روی Finish کلیک کنید تا ماشین میهمان ساخته شود.
مرحله چهارم: ویرایش تنظیمات مربوط به ماشین مجازی
ماشین مجازی را که در مرحله قبلی ایجاد کردهاید، باز کنید و بر روی دکمهی Setting کلیک کنید. در دسته بندی System بر روی تب Motherboard کلیک کنید. گزینه انتخابی Enable EFI را فعال کنید و Chipset را به IHC9 و یا PIIX3 تغییر دهید.
در تب Processor گزینه Enable PAE/NX را فعال کرده و Coreها را به نصف Coreهای سیستم فعلی خود ارتقاء دهید.
در دسته Display، گزینه Video Memory را به 128 مگابایت ارتقا دهید.
شما میتوانید سایر گزینهها را نیز بسته به نیاز خود تغییر دهید.
بر روی تب Storage کلیک کرده و گزینه Use Host I/O Cache را فعال کنید.
مرحله پنجم: استفاده از خط فرمان برای اضافه کردن دستورات خاص
خط فرمان (CMD) را به عنوان Administrator باز کنید.
دستورات زیر را وارد کنید. دقت داشته باشید که بجای Your VM Name؛ نام ماشین مجازی خود را وارد کنید؛ در مثال ما Mac
cd "C:\Program Files\Oracle\VirtualBox\" VBoxManage.exe modifyvm "Your VM Name" --cpuidset 00000001 000106e5 00100800 0098e3fd bfebfbff VBoxManage setextradata "Your VM Name" "VBoxInternal/Devices/efi/0/Config/DmiSystemProduct" "iMac11,3" VBoxManage setextradata "Your VM Name" "VBoxInternal/Devices/efi/0/Config/DmiSystemVersion" "1.0" VBoxManage setextradata "Your VM Name" "VBoxInternal/Devices/efi/0/Config/DmiBoardProduct" "Iloveapple" VBoxManage setextradata "Your VM Name" "VBoxInternal/Devices/smc/0/Config/DeviceKey" "ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc" VBoxManage setextradata "Your VM Name" "VBoxInternal/Devices/smc/0/Config/GetKeyFromRealSMC" 1
VirtualBox را قبل از اجزای این دستورات ببندید و سپس این دستورات را اجرا کنید.
مرحله ششم: اجرای سیستم عامل مک نسخه 10.14 بر روی Virtual Box
ماشین مجازی را که ایجاد کرده اید، باز کنید و بر روی start کلیک کنید:
صفحه فوق را باید مشاهده کنید. در صورت بروز هر گونه مشکلی، سوال خود را ذیل این مطلب مطرح کنید.
تنظیمات اولیه و نام کاربری سیستم عامل را وارد کنید و تمام!
دقت داشته باشید که استفاده از این روش ممکن است با تجربه کاری یک مک بر روی سخت افزار اصلی به کلی متفاوت باشد. ما از این روش برای جبران محدودیت خود برای توسعه استفاده میکنیم.
خوشبختانه برای کار با Xamarin.iOS شما مجبور به کد نویسی بر روی مک نخواهید بود و تنها پروسه بیلد پروژه بر روی آن انجام خواهد شد. لذا مشکلات کارآیی آن بر روی روند کار شما تاثیر چندانی نخواهد داشت. البته برای نصب این سیستم عامل به صورت مجازی توصیه میشود از هارد SSD استفاده کنید.
نحوهی رفع مشکلات سخت افزاری و درایوری
در صورتیکه در مراحل نصب و یا پس از نصب سیستم عامل، کیبرد و یا ماوس کار نمیکنند، میتوانید مراحل زیر را انجام دهید:
به سایت VirtualBox.org رفته و آخرین نسخهی Extension Pack را دانلود کنید.
سپس VirtualBox را باز کنید و از منوی فایل، گزینهی Preferences را انتخاب کنید:
بر روی برگهی Extensions کلیک کرده و گزینهی Add را انتخاب کنید:
در مرورگر فایل باز شده، فایلی را که دانلود کردهاید، انتخاب کنید. سپس بر روی Install کلیک کنید. در صفحهی توافقنامه نمایش داده شده، به پایین متن اسکرول کنید و I Agree را انتخاب کنید.
در صورتی که بعد از اعمال تغییرات فوق، مشکل همچنان باقی بود، میتوانید در تنظیمات VM خود در تب USB، گزینهی USB 3.0 (xHCI) Controller. را انتخاب کنید.
در صورتیکه مشکلات دیگری نظیر شناسایی درایورها و یا سایر موارد را داشتید، میتوانید زیر همین مطلب، سؤالات خود و یا بازخورد خود در رابطه با این مقاله را مطرح کنید.
اگر پس از ارسال کدها در بلاگر فاصلههای عجیبی را بین سطرهای رندر شده مشاهده کردید، مشکل از قرار دادن تک BR به صورت خودکار است!
برای حل این مشکل به آدرس زیر مراجعه کنید:
Dashboard -> Settings -> Formatting -> Convert line breaks -> change to No
یا در قسمت کنترل پنل فارسی : تنظیمات ، قسمت قالب بندی و سپس گزینهی «برعکس کردن شکست خط» را خیر کنید.
Roslyn #1
سکوی کامپایلر دات نت یا Roslyn (با تلفظ «رازلین») بازنویسی مجدد کامپایلرهای VB.NET و #C توسط همین زبانها است. این سکوی کامپایلر به همراه یک سری کتابخانه و اسمبلی ارائه میشود که امکان آنالیز زبانهای مدیریت شده را به صورت مستقل و یا یکپارچهی با ویژوال استودیو، فراهم میکنند. برای نمونه در VS.NET 2015 تمام سرویسهای زبانهای موجود، با Roslyn API جایگزین و بازنویسی شدهاند. نمونههایی از این سرویسهای زبانها، شامل Intellisense و مرور کدها مانند go to references and definitions، به همراه امکانات Refactoring میشوند. به علاوه به کمک Roslyn میتوان یک کامپایلر و ابزارهای مرتبط با آن، مانند FxCop را تولید کرد و یا در نهایت یک فایل اسمبلی نهایی را از آن تحویل گرفت.
چرا مایکروسافت Roslyn را تولید کرد؟
پیش از پروژهی Roslyn، کامپایلرهای VB.NET و #C با زبان ++C نوشته شده بودند؛ از این جهت که در اواخر دههی 90 که کار تولید سکوی دات نت در حال انجام بود، هنوز امکانات کافی برای نوشتن این کامپایلرها با زبانهای مدیریت شده وجود نداشت و همچنین زبان محبوب کامپایلر نویسی در آن دوران نیز ++C بود. این انتخاب در دراز مدت مشکلاتی مانند کاهش انعطاف پذیری و productivity تیم کامپایلر نویس را با افزایش تعداد سطرهای کامپایلر نوشته شده به همراه داشت و افزودن ویژگیهای جدید را به زبانهای VB.NET و #C سختتر و سختتر کرده بود. همچنین در اینجا برنامه نویسهای تیم کامپایلر مدام مجبور بودند که بین زبانهای مدیریت شده و مدیریت نشده سوئیچ کنند و امکان استفادهی همزمان از زبانهایی را که در حال توسعهی آن هستند، نداشتند.
این مسایل سبب شدند تا در طی بیش از یک دهه، چندین نوع کامپایلر از صفر نوشته شوند:
- کامپایلرهای خط فرمانی مانند csc.exe و vbc.exe
- کامپایلر پشت صحنهی ویژوال استودیو (برای مثال کشیدن یک خط قرمز زیر مشکلات دستوری موجود)
- کامپایلر snippetها در immediate window ویژوال استودیو
هر کدام از این کامپایلرها هم برای حل مسایلی خاص طراحی شدهاند. کامپایلرهای خط فرمانی، با چندین فایل ورودی، به همراه ارائهی تعدادی زیادی خطا و اخطار کار میکنند. کامپایلر پشت صحنهی ویژوال استودیوهای تا پیش از نسخهی 2015، تنها با یک تک فایل در حال استفاده، کار میکند و همچنین باید به خطاهای رخ داده نیز مقاوم باشد و بیش از اندازه گزارش خطا ندهد. برای مثال زمانیکه کاربر در حالت تایپ یک سطر است، بدیهی است تا اتمام کار، این سطر فاقد ارزش دستوری صحیحی است و کامپایلر باید به این مساله دقت داشته باشد و یا کامپایلر snippetها تنها جهت ارزیابی یک تک سطر از دستورات وارد شده، طراحی شدهاست.
با توجه به این مسایل، مایکروسافت از بازنویسی سکوی کامپایلر دات نت این اهداف را دنبال میکند:
- بالا بردن سرعت افزودن قابلیتهای جدید به زبانهای موجود
- سبک کردن حجم کاری کامپایلر نویسی و کاهش تعداد آنها به یک مورد
- بالا بردن دسترسی پذیری به API کامپایلرها
برای مثال اکنون برنامه نویسها بجای اینکه یک فایل cs را به کامپایلر csc.exe ارائه کنند و یک خروجی باینری دریافت کنند، امکان دسترسی به syntax trees، semantic analysis و تمام مسایل پشت صحنهی یک کامپایلر را دارند.
- ساده سازی تولید افزونههای مرتبط با زبانهای مدیریت شده.
اکنون برای تولید یک آنالیز کنندهی سفارشی، نیازی نیست هر توسعه دهندهای شروع به نوشتن امکانات پایهای یک کامپایلر کند. این امکانات به صورت یک API عمومی در دسترس برنامه نویسها قرار گرفتهاند.
- آموزش مسایل درونی یک کامپایلر و همچنین ایجاد اکوسیستمی از برنامه نویسهای علاقمند در اطراف آن.
همانطور که اطلاع دارید، Roslyn به صورت سورس باز در GitHub در دسترس عموم است.
تفاوت Roslyn با کامپایلرهای سنتی
اکثر کامپایلرهای موجود به صورت یک جعبهی سیاه عمل میکنند. به این معنا که تعدادی فایل ورودی را دریافت کرده و در نهایت یک خروجی باینری را تولید میکنند. اینکه در این میان چه اتفاقاتی رخ میدهد، از دید استفاده کننده مخفی است.
نمونهای از این کامپایلرهای جعبه سیاه را در تصویر فوق مشاهده میکنید. در اینجا شاید این سؤال مطرح شود که در داخل جعبهی سیاه کامپایلر سیشارپ، چه اتفاقاتی رخ میدهد؟
خلاصهی مراحل رخ داده در کامپایلر سیشارپ را در تصویر فوق ملاحظه میکنید. در اینجا ابتدا کار parse اطلاعات متنی دریافتی شروع میشود و از روی آن syntax tree تولید میشود. در مرحلهی بعد مواردی مانند ارجاعاتی به mscorlib و امثال آن پردازش میشوند. در مرحلهی binder کار پردازش حوزهی دید متغیرها، اشیاء و اتصال آنها به هم انجام میشود. در مرحلهی آخر، کار تولید کدهای IL و اسمبلی باینری نهایی صورت میگیرد.
با معرفی Roslyn، این جعبهی سیاه، به صورت یک API عمومی در دسترس برنامه نویسها قرار گرفتهاست:
همانطور که مشاهده میکنید، هر مرحلهی کامپایل جعبهی سیاه، به یک API عمومی Roslyn نگاشت شدهاست. برای مثال Parser به Syntax tree API نگاشت شدهاست. به علاوه این API صرفا به موارد فوق خلاصه نمیشود و همانطور که پیشتر نیز ذکر شد، برای اینکه بتواند جایگزین سه نوع کامپایلر موجود شود، به همراه Workspace API نیز میباشد:
Roslyn امکان کار با یک Solution و فایلهای آن را دارد و شامل سرویسهای زبانهای مورد نیاز در ویژوال استودیو نیز میشود. برفراز Workspace API، یک مجموعه API دیگر به نام Diagnostics API تدارک دیده شدهاست تا برنامه نویسها بتوانند امکانات Refactoring جانبی را توسعه داده و یا در جهت بهبود کیفیت کدهای نوشته شده، اخطارهایی را به برنامه نویسها تحت عنوان Code fixes و آنالیز کنندهها، ارائه دهند.
- «با HttpHandler بیشتر آشنا شوید»
یکی از بزرگترین تغییرات ASP.NET Core نسبت به نگارشهای قبلی آن، مدیریت HTTP pipeline آن است. به عنوان یک توسعه دهندهی ASP.NET به طور قطع با مفاهیمی مانند HttpHandler و HttpModules آشنایی دارید و ... هر دوی اینها با نگارش جدید ASP.NET حذف و با مفهوم جدیدی به نام Middleware جایگزین شدهاند.
- HttpHandlerها عموما مبتنی بر پسوندهای فایلها عمل میکنند. برای نمونه، رایجترین آنها ASP.NET page handler است که هرگاه درخواستی، ختم شدهی به پسوند aspx، به موتور ASP.NET Web forms وارد شد، به این page handler، جهت پردازش نهایی هدایت میشود. محل تنظیم آنها نیز در فایل web.config است.
- HttpModuleها مبتنی بر رخدادها عمل میکنند. HttpModuleها به عنوان جزئی از request pipeline عمل کرده و دسترسی کاملی دارند به رخدادهای طول عمر درخواست رسیده. آنها را میتوان توسط فایلهای global.asax و یا web.config تنظیم کرد.
- MiddleWareها را که جزئی از طراحی OWIN نیز هستند، میتوان به عنوان کامپوننتهای کوچکی از برنامه که قابلیت یکپارچه شدن با HTTP request pipeline را دارند، درنظر گرفت. عملکرد آنها ترکیبی است از هر دوی HttpHandler و HttpModuleها که در نگارشهای قبلی ASP.NET مورد استفاده بودند. از MiddleWareها میتوان برای پیاده سازی اعمال مختلفی جهت پردازش درخواستهای رسیده مانند اعتبارسنجی، کار با سشنها، ثبت وقایع سیستم، مسیریابی و غیره استفاده کرد. OWIN یا Open Web Interface for .NET به توسعه دهندهها امکان غیروابسته کردن برنامهی ASP.NET خود را از وب سرور مورد استفاده میدهد. به علاوه OWIN امکان پلاگین نویسی اجزای مختلف برنامه را بدون وابسته کردن آنها به یکدیگر فراهم میکند. برای مثال میتوان یک پلاگین logger را تهیه کرد تا اطلاعات مختلفی را از درخواستهای رسیده ثبت کند.
مواردی که با ارائهی ASP.NET Core 1.0 حذف شدهاند
- System.Web: یکی از اهداف اصلی OWIN، مستقل کردن برنامهی وب، از هاست آن است تا بتوان از وب سرورهای بیشتری استفاده کرد. System.Web انحصارا برای IIS طراحی شده بود و در این نگارش دیگر وجود خارجی ندارد.
- HttpModules: با Middlewareها جایگزین شدهاند.
- HttpHandlers: البته HttpHandlers از زمان ارائهی اولین نگارش ASP.NET MVC، در چندین سال قبل منسوخ شدند. زیرا پردازش صفحات وب در ASP.NET MVC برخلاف وب فرمها، از فایلهایی با پسوندهای خاص شروع نمیشوند و نقطهی آغازین آنها، اکشن متدهای کنترلرها است.
- فایل global.asax: با حذف شدن HttpModules، دیگر ضرورتی به وجود این فایل نیست.
شباهتهای بینMiddleware و HttpModuleها
همانند HttpModuleها، Middlewareها نیز به ازای هر درخواست رسیده اجرا میشوند و از هر دو میتوان جهت تولید response ایی خاص استفاده کرد.
تفاوتهای بینMiddleware و HttpModuleها
- عموما HttpModule از طریق web.config و یا فایل global.asax تنظیم میشوند. اما Middlewareها تنها از طریق کد و در فایل Startup.cs برنامههای ASP.NET Core 1.0 قابل معرفی هستند.
- به عنوان یک توسعه دهنده، کنترلی را بر روی ترتیب اجرای انواع و اقسام HttpModuleها نداریم. این مشکل در Middlewareها برطرف شده و اکنون ترتیب اجرای آنها، دقیقا مطابق ترتیب افزوده شدن و تعریف آنها در فایل Startup.cs است.
- ترتیب اجرای HttpModuleها هرچه که باشد، برای حالتهای request و response یکی است. اما ترتیب اجرای Middlewareهای مخصوص response، عکس ترتیب اجرای Middlewareهای مخصوص request هستند (تصویر ذیل).
- HttpModuleها را صرفا جهت اتصال کدهایی به رخدادهای طول عمر برنامه میتوان طراحی کرد؛ اما Middleware مستقل هستند از این رخدادها.
- HttpModuleها به System.Web وابستهاند؛ برخلاف Middlewareها که وابستگی به هاست خود ندارند.
Middlewareهای توکار ASP.NET Core 1.0
ASP.NET Core 1.0 به همراه تعدادی Middleware توکار است؛ مانند:
- Authentication: جهت پشتیبانی از اعتبارسنجی
- CORS: برای فعال سازی Cross-Origin Resource Sharing
- Routing: جهت تعریف و محدود سازی مسیریابیهای برنامه
- Session: برای پشتیبانی و مدیریت سشنهای کاربران
- Diagnostics: پشتیبانی از صفحات خطا و اطلاعات زمان اجرای برنامه
و مواردی دیگر که برای توزیع فایلهای استاتیک و یا مرور محتویات پوشهها و امثال آنها طراحی شدهاند که در طی این مطلب و همچنین مطالب آتی، آنها را بررسی خواهیم کرد.
یک مثال: اگر یک پروژهی خالی ASP.NET Core 1.0 را در ویژوال استودیو ایجاد کنید، این پروژه قادر نیست حتی فایلهای استاتیک مانند تصاویر، فایلهای پیش فرض مانند index.html و یا قابلیت مرور سادهی فایلهای موجود در یک پوشه را ارائه دهد (حتی اگر به آنها نیازی نداشته باشید).
طراحی این نگارش از ASP.NET، مبتنی است بر سبک وزن بودن و ماژولار بودن. هر قابلیتی را که نیاز دارید، باید middleware آنرا نیز خودتان به صورت صریح اضافه کنید و یا در غیر اینصورت فعال نیست. برخلاف نگارشهای قبلی ASP.NET که HTTP Moduleهای از سشن گرفته تا اعتبارسنجی و غیره، همگی به صورت پیش فرض در فایل Web.Config فعال بودند؛ مگر اینکه آنها را به صورت دستی حذف میکردید.
ثبت و فعال سازی اولین Middleware
در ادامهی تکمیل و معرفی برنامهی خالی ASP.NET Core 1.0، قصد داریم یک Middleware توکار را به نام Welcome Page، بجای نمایش سطر Hello world پیش فرض این برنامه، ثبت و فعال سازی کنیم. این Middleware ویژه، در اسمبلی به نام Microsoft.AspNetCore.Diagnostics قرار دارد. اگر فایل project.json پیش فرض این پروژه را باز کنید، این اسمبلی به صورت پیش فرض در آن ثبت و معرفی شدهاست:
{ "dependencies": { "Microsoft.NETCore.App": { "version": "1.0.0", "type": "platform" }, "Microsoft.AspNetCore.Diagnostics": "1.0.0", "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", "Microsoft.AspNetCore.Server.Kestrel": "1.0.0", "Microsoft.Extensions.Logging.Console": "1.0.0" },
پس از اطمینان حاصل کردن از نصب بستهی نیوگت Microsoft.AspNetCore.Diagnostics، اکنون جهت معرفی Middleware توکار Welcome Page ، فایل Startup.cs را گشوده و کدهای آنرا به نحو ذیل تغییر دهید:
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; namespace Core1RtmEmptyTest { public class Startup { public void ConfigureServices(IServiceCollection services) { } public void Configure(IApplicationBuilder app) { app.UseWelcomePage(); app.Run(async (context) => { await context.Response.WriteAsync("Hello DNT!"); }); } } }
به علاوه middleware دومی را نیز با متد الحاقی Run مشاهده میکنید. به این نوع middlewareهای خاص، اصطلاحا terminal middleware میگویند. از این جهت که درخواستی را دریافت و یک response را تولید میکنند و کار همینجا خاتمه مییابد و زنجیرهی پردازشی middlewareها ادامه نخواهد یافت. در اینجا پارامتر context آن از نوع HttpContext است و باید دقت داشت، زمانیکه کار نوشتن در Response، در اینجا انجام شد، اگر پس از متد Run یک Middleware دیگر را ثبت کنید، هیچگاه اجرا نخواهد شد.
در این حالت اگر برنامه را اجرا کنید، خروجی ذیل را مشاهده خواهید کرد:
welcome page نیز یک terminal middleware است. به همین جهت middleware بعدی ثبت شدهی در اینجا یا همان متد Run، دیگر اجرا نخواهد شد.
در قسمتهای بعدی، تعداد بیشتری از Middlewareهای توکار ASP.NET Core 1.0 را بررسی خواهیم کرد.
<link href="Styles/bootstrap.min.css" rel="stylesheet" /> //برای نمایش و استفاده از جعبهی رنگ در بوت استراپ <link href="Styles/bootstrap-colorpalette.css" rel="stylesheet" /> <script src="Scripts/jquery-1.8.2.js"></script> <script type="text/javascript" src='Scripts/jquery.signalR-1.1.3.js'></script> <script src="Scripts/bootstrap.min.js"></script> <script src="Scripts/bootstrap-colorpalette.js"></script> <script type="text/javascript" src='<%: ResolveClientUrl("~/signalr/hubs") %>'></script> //حاوی متدهایی برای رسم خط با استفاده از HTML5 <script src="Scripts/draw.js" type="text/javascript"></script> //تعریف کلاینتهای متصل به هاب <script src="Scripts/Whiteboard.js"></script>
تعریف کلاس Hub برنامه :
using Microsoft.AspNet.SignalR; using Microsoft.AspNet.SignalR.Hubs; using OnlineSignalRWhiteboard.Model; namespace OnlineSignalRWhiteboard.Hubs { [HubName("onWhiteboard")] public class Whiteboard : Hub { public void OnDrawPen(Point prev, Point current, string color, int width) { Clients.All.drawPen(prev, current, color, width); } public void ClearBoard() { Clients.All.clear(); } } }
کدهای کلاینتهای متصل به هاب در فایل Whiteboard.js :
$(function () { $.connection.hub.logging = true; var whiteboard = $.connection.onWhiteboard; $("#clear").click(function () { //پاک کردن صفحه نمایش whiteboard.server.clearBoard(); }); var color = function (colors) { //تغییر رنگ قلم draw.colour = colors; }; $(".size").click(function () { //تغییر سایز قلم draw.lineWidth = $(this).height(); $('#size').css('height', $(this).height()); }); $.connection.hub.start().done(function () { }) .fail(function () { alert("Could not Connect!"); }); draw.onDraw = function (prev, current, color, width) { //ارسال پارامترها به سمت سرور تا سرور بتواند دادهها را به سمت سایر کلاینتها نیز ارسال کند whiteboard.server.onDrawPen(prev, current, color, width); }; whiteboard.client.drawPen = function (prev, current, color, width) { draw.drawPen(prev, current, color, width); }; whiteboard.client.clear = function () { draw.clear(); }; $('#colorpalette3').colorPalette() .on('selectColor', function (e) { $('#color').css('background-color', e.color); color(e.color); }); var canvas = document.getElementById('draw'); //تغییر سایر کانواس متناسب با پنجرهی مرورگر window.addEventListener('resize', resizeCanvas, false); function resizeCanvas() { canvas.width = window.innerWidth - 20; canvas.height = window.innerHeight - 70; } resizeCanvas(); });
کدهای کامل سمت کلاینت :
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <link href="Styles/bootstrap.min.css" rel="stylesheet" /> <link href="Styles/bootstrap-colorpalette.css" rel="stylesheet" /> <script src="Scripts/jquery-1.8.2.js"></script> <script type="text/javascript" src='Scripts/jquery.signalR-1.1.3.js'></script> <script src="Scripts/bootstrap.min.js"></script> <script src="Scripts/bootstrap-colorpalette.js"></script> <script type="text/javascript" src='<%: ResolveClientUrl("~/signalr/hubs") %>'></script> <script src="Scripts/draw.js" type="text/javascript"></script> <script src="Scripts/Whiteboard.js"></script> </head> <body> <form id="form1" runat="server"> <div> <div style="position: static;"> <div> <div> <a data-toggle="collapse" data-target=".navbar-inverse-collapse"> <span></span> <span></span> <span></span> </a> <a href="#">تخته وایت برد آنلاین توسط SignalR و HTML5</a> <div> <ul> <li> <div> <a id="selected-color2" data-toggle="dropdown"> <div style="width: 20px; height: 20px; background: black" id="color"> </div> </a> <ul style="width:293px;"> <li style="display:inline-block;"> <div>رنگ پس زمینه</div> <div id="colorpalette3"></div> </li> </ul> </div> </li> <li></li> <li> <div> <a data-toggle="dropdown" style="width: 120px; height: 20px" href="#"> <hr style="width: 120px; height: 1px; background-color: black;margin: 0px; display: table-cell" id="size"> </a> <ul style="width: 120px"> <li><hr style="width: 140px; height: 1px; background-color: black"></li> <li></li> <li><hr style="width: 140px; height: 3px; background-color: black"></li> <li></li> <li><hr style="width: 140px; height: 7px; background-color: black"></li> <li></li> <li><hr style="width: 140px; height: 10px; background-color: black"></li> <li></li> <li><hr style="width: 140px; height: 20px; background-color: black"></li> </ul> </div> </li> <li></li> <li> <div> <a href="#" id="clear"><i></i>جدید</a> </div> </li> </ul> </div><!-- /.nav-collapse --> </div> </div><!-- /navbar-inner --> </div> </div> <div> <div> <canvas id="draw" style="cursor: crosshair;border: 1px solid black;"></canvas> </div> </div> </form> </body> </html>
سپاس از لطف شما
توابع سودمند
فراخوانی و استفاده از این توابع در ابتدا ممکن است کمی عجیب به نطر برسد. به مثال زیر دقت کنید که تابع سودمند () 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 بروی صفحه.
- اجرای کد به محض آماده شدن اشیای صفحه.
موفق وموید باشید