اذهب إلى المحتوى

سامح أشرف

الأعضاء
  • المساهمات

    2934
  • تاريخ الانضمام

  • تاريخ آخر زيارة

  • عدد الأيام التي تصدر بها

    56

كل منشورات العضو سامح أشرف

  1. هل يمكنك توضيح المشكلة بمزيد من التفاصيل؟ هل تظهر لديك أي أخطاء في سطر الأوامر؟
  2. بالفعل، فالخطافات hooks من أهم المواضيع في React ولا يخلو أي مشروع حتى ولو كان بسيط منها، لذلك يجب تعلمها جيدًا لكي تستطيع إستعمالها بشكل سليم.
  3. الكائن localStorage عبارة عن كائن JavaScript عادي، ويمكنك إستخدامه في أي موقع بدون أي مشكلة وبغض النظر عن إطار العمل الذي تستعمله. حاول أن تستعمل localStorage في الخطاف useEffect أو useState لكي لا يتم إستخدامه في كل عملية render للمكون component، بالشكل التالي: import React, { useState } from "react"; const MyInput = () => { const [value, setValue] = useState(localStorage.getItem("key") || ""); const onChange = (e) => { setValue(e.target.value); localStorage.setItem("key", e.target.value); }; return <input value={value} onChange={onChange} />; }; export default function App() { return ( <div className="App"> <MyInput /> </div> ); } في المثال السابق، يتم عمل input وأي شيء سوف يتم كتابته فيه سيتم تخزينه في localStorage مباشرة يمكنك الإطلاع على المزيد عن localStorage من خلال هذه المقالات:
  4. يمكنك أيضًا إستعمال الكائن Q للقيام بالإستعلامات المتعددة الشروط على النحو التالي: from django.db.models import Q first_condition = Q(title__contains="automation") second_condition = Q(title__contains="python") posts = Post.objects.filter(first_condition & second_condition) بهذا الشكل يمكنك عمل أي عدد من الشروط وربطها معًا من خلال المعامل & في التابع filter أيضًا يمكنك إستخدام المعامل OR في لغة SQL بنفس الطريقة من خلال إستبدال المعامل & في المثال السابق بالمعامل | كالتالي: from django.db.models import Q first_condition = Q(title__contains="automation") second_condition = Q(title__contains="python") posts = Post.objects.filter(first_condition | second_condition) # first_condition OR second_condition
  5. بالطبع يمكن إستخدام التابع os.rename لنقل ملف ما، ولكن لكي يعمل هذا التابع يجب أن يكون الملف الأصلي والمسار الذي سيتم نقله إليه في نفس نظام الملفات File System (على نفس القرص Partition) الخطأ Invalid cross-device link ليس مشكلة في جانغو Django بل ناجم عن نقل ملف من نظام ملفات مختلف File System، حيث أن التابع os.rename يعمل فقط في حالة كان الملف موجود في نظام ملفات معين وتريد نقله إلى مكان آخر ضمن نفس نظام الملفات، بينما في حالتك فإن نقل ملف من نظام ملفات إلى نظام ملفات مختلف (من قرص Partition إلى قرص آخر USB) لا يمكن أن يتم بإستخدام التابع os.rename. >>> import os >>> os.getcwd() # المسار الحالي، في القرص D: '/mnt/d/temp' >>> os.rename('test.txt', '/mnt/e/test.txt') # لا يمكن نقل الملف إلى القرص E: Traceback (most recent call last): File "<stdin>", line 1, in <module> OSError: [Errno 18] Invalid cross-device link: 'test.txt' -> '/mnt/e/test.txt' >>> os.rename('test.txt', '/mnt/d/test.txt') # بينما سيعمل الكود إذا نقلنا الملف إلى مكان آخر ضمن نفس نظام الملفات >>> يمكنك أن تستعمل التابع shutil.move لهذه العملية، على النحو التالي: >>> import os, shutil >>> os.getcwd() '/mnt/d/temp' >>> shutil.move('test.txt', '/mnt/e/test.txt') '/mnt/e/test.txt' >>> ملاحظة: التابع shutil.move سوف يُظهر نفس الخطأ كذلك إن كنت تستعمل Python 2، بينما إذا كنت تستعمل Python 3 فسوف يعمل كل شيء على ما يرام، ولحل المشكلة بالنسبة لـ Python 2 فيمكنك نسخ الملف عبر التابع shutil.copy ثم حذف الملف الأصلي عبر التابع os.remove
  6. لكي يتم طباعة أي قيمة في console فإنك بحاجة إلى الضغط على أي زر في الصفحة، وذلك لأنك حددت مسبقًا كل الأزرار buttons وأضفت حدث event لتنفيذ الدالة btnAction عند الضغط على أي زر، أيضًا يجب أن يحتوي الزر الذي تضغط عليه الخاصية data-cookie لكي يتم طباعة قيمتها. إن أستمرت المشكلة لديك، فأرجو منك أن ترفق كود HTML كذلك.
  7. الخطأ بسبب إستدعاء الدالة btnAction في نهاية الكود، حيث لم تقم بتمرير أي حدث إليها وبالتالي فإن المعامل e غير معرف undefined، وبالتالي يحدث خطأ عند محاولة الوصول إلى الخاصية target ضمن المعامل e كل ما عليك لحل المشكلة أن تقوم بحذف آخر إستدعاء للدالة btnAction من الكود: const btns = document.querySelectorAll("button") btns.forEach(btn =>{ btn.addEventListener('click', btnAction) }) function btnAction(e) { let description = e.target.getAttribute("data-cookie") console.log(description); } // هذا السطر هو سبب المشكلة // btnAction()
  8. يمكنك التحكم في مدة عرض الإعلان من خلال إضافة خاصية جديد في كل عنصر video خاص بالإعلانات وليكن اسمها data-duration، بالشكل التالي: <video class="add1 one" id="add1" src="video/ad.mp4" data-duration="5"></video> <video class="add2 one" id="add2" src="video/ad2.mp4" data-duration="7"></video> <video class="add3 one" id="add3" src="video/ad3.mp4" data-duration="10"></video> ثم في كود JavaScript نقوم بتغير قيمة العداد بحسب القيمة الموجودة في الخاصية data-duration في الإعلان الذي تم إختياره عشوائيًا: let ads = document.querySelectorAll('.one'); let adsLength = ads.length; let randomAdIndex = Math.floor(Math.random() * adsLength) let randomAd = ads[randomAdIndex]; // نقوم بجلب القيمة الموجودة في العنصر video ونحولها إلى رقم // parseInt عبارة عن دالة تحول النص إلى رقم // "10" => 10 const adDuration = parseInt(randomAd.getAttribute('data-duration')); document.getElementById('counter1').innerHTML = adDuration ثم نستخدم قيمة الخاصية data-duration كذلك في حساب مدة عرض الإعلان وعرض العداد: if (mainTimer == 180) { counterTitle1.style.display = 'none'; counterTitle2.style.display = 'block'; counterTitle2.style.zIndex = '20'; counter1html.style.display = 'block'; counter1html.style.zIndex = '20'; counter1html.innerHTML = adDuration; // نغير قيمة العداد في كل ثانية mainVideo.pause(); randomAd.style.display = 'block'; randomAd.play(); } // إخفاء الإعلان عند إنتهاء المدة if (mainTimer == (180 - adDuration)) { randomAd.pause(); counterTitle2.style.display = 'none'; counter1html.style.display = 'none'; randomAd.style.display = 'none'; mainVideo.play(); } بهذا الشكل سوف يظهر في كل مرة إعلان عشوائي ونستطيع التحكم في مدة عرض كل إعلان من خلال تغير قيمة الخاصية data-duration
  9. الحدث DOMContentLoaded مقصود به عند الإنتهاء من تحميل الصفحة Document Content Loaded، يمكنك الإطلاع على مزيد من التفاصيل عن هذا الحدث من خلال هذه المقالة:
  10. بالنسبة لمشكلة أن العداد counter يُسرع ويتخطى بعض الثواني، فالسبب هو أنك تضيف الحدث setInterval جديد في كل مرة يعمل فيها الفيديو، فعلى سبيل المثال إذا قمت بتشغيل الفيديو في أول مرة ولم تقم بإيقافه على يدويًا فسوف تجد أن العداد يعمل بشكل سليم، ولكن إذا قمت بإيقاف الفيديو وقمت بتشغيله أكثر من مرة فسوف تجد أن العداد يُسرع أكثر وأكثر، والسبب هو أنك تجعل الدالة counter1 تعلم أكثر من مرة، حيث أنك أضفت الكود التالي: // في كل مرة يعمل الفيديو (أو يكمل التشغيل بعد إيقافه) سوف يعمل الكود التالي بالكامل // وبالتي سوف يتم تشغيل أكثر من دالة setInterval بالتوازي mainVideo.onplay = function () { function counter1() { // ... } setInterval(counter1, 1000) } لحل هذه المشكلة يمكن أن تقوم بتشغيل الدالة setInterval عند تحميل الصفحة وتُخرج الدالة counter1 خارج الحدث onplay بالشكل التالي: function counter1() { // ... } document.addEventListener('DOMContentLoaded', () => setInterval(counter1, 1000)) أما لتحديد إعلان عشوائي من بين الإعلانات الموجودة في الصفحة، فيجب أن تقوم بإستخدام الأصناف classes وليس المعرفات IDs بالشكل التالي: let ads = document.querySelectorAll('.one'); let adsLength = ads.length; let randomAdIndex = Math.floor(Math.random() * adsLength) let randomAd = ads[randomAdIndex]; ولكي تجعل العداد يتوقف عند إيقاف الفيديو الرئيسي عليك تعديل الدالة counter1 لكي تعمل فقط عندما يكون الفيديو يعمل، على النحو التالي: function counter1() { let mainTimer = document.getElementById('mainTimer').innerText; // نوقف الدالة عندما يكون الفيديو متوقف ولا يوجد إعلان يعمل const adNotEnded = randomAd.currentTime !== randomAd.duration; if (mainVideo.paused && randomAd.paused && adNotEnded) { return } document.getElementById('mainTimer').innerText -= 1 // .. } وبالتالي يصبح الكود بالكامل بالشكل التالي: let ads = document.querySelectorAll('.one'); // نحدد كل الفيديوهات let adsLength = ads.length; let randomAdIndex = Math.floor(Math.random() * adsLength) let randomAd = ads[randomAdIndex]; // فيدفيو عشوائي function counter1() { let mainTimer = document.getElementById('mainTimer').innerText; // نوقف الدالة إذا كان الفيديو الرئيسي متوقف والإعلان متوقف (في حالة لم ينتهي الإعلان) const adNotEnded = randomAd.currentTime !== randomAd.duration; if (mainVideo.paused && randomAd.paused && adNotEnded) { return } document.getElementById('mainTimer').innerText -= 1 document.getElementById('counter1').innerText -= 1; if (mainTimer == 190) { counter1html.style.display = 'block'; counter1html.innerHTML = 10; counterTitle1.style.display = 'block'; } if (mainTimer == 180) { counterTitle1.style.display = 'none'; counterTitle2.style.display = 'block'; counterTitle2.style.zIndex = '20'; counter1html.style.display = 'block'; counter1html.style.zIndex = '20'; counter1html.innerHTML = 10; mainVideo.pause(); randomAd.style.display = 'block'; randomAd.play(); } if (mainTimer == 170) { randomAd.pause(); counterTitle2.style.display = 'none'; counter1html.style.display = 'none'; randomAd.style.display = 'none'; mainVideo.play(); } } document.addEventListener('DOMContentLoaded', () => setInterval(counter1, 1000));
  11. يمكنك إضافة المعامل resource إلى الأمر make:controller ليتم كتابة كل التوابع الأساسية مثل index و show و store .. إلخ بشكل تلقائي في المتحكم controller: php artisan make:controller PhotoController --resource كما تستطيع إضافة المعامل model لربط نموذج معين (أو إنشائه في حالة عدم وجوده) مباشرة: php artisan make:controller PhotoController --model=Photo --resource ويمكن إضافة المعامل requests كذلك لعمل ملف requests تلقائيًا php artisan make:controller PhotoController --model=Photo --resource --requests بهذا الشكل سوف يتم عمل كل هذه الملف وسيتم تجهيز محتواها الأساسي بشكل تلقائي. تم شرح كل هذه الأمور وغيرها بشكل مفصل في موسوعة حسوب في هذه الصفحة (وحدات التحكّم (Controllers) في Laravel).
  12. هل يمكنك إضافة كود HTML كذلك لأن هناك بعض العناصر لا يتضح معنها من مجرد قراءة id الخاص بها فقط
  13. المشكلة لديك هي تحديد قيمة صغيرة للغاية للمتغير successRateحيث أن القيمة 0.5 ستكون أصغر من أي قيمة للمتغير random_rate (ماعدا القيمة 0 بالطبع)، لذلك عليك أن تقوم بتغير قيمة المتغير successRate لتكون قيمة أكبر مثل 50 على سبيل المثال: أيضًا عليك أن تقوم بنقل جملة طباعة الجملة Congrats for خارج جملة if لكي يتم طباعة الجملة في كل دورة وليس في آخر دورة فقط، بالشكل التالي: <?php function successfulCompaines($names_array, $rate) { $new_names = []; $index = null; $min = null; foreach ($names_array as $i => $name) { $random_rate = rand(0, 100); if ($min == null) { $index = 0; $min = $random_rate; } if ($random_rate <= $rate) { array_push($new_names, $name); } if ($random_rate < $min) { $index = $i; $min = $random_rate; } } return count($new_names) == 0 ? [$names_array[$index]] : $new_names; } $compaines = array("Lenovo", "Huawei", "Apple", "Amazon", "Microsoft", "Abb", "Netflex", "Siemens", "Samsung", "Adidas", "Uber", "Dell", "Hp", "Walmart", "Tesla", "Google", "Volvo", "Toyota", "Ibm", "Shell"); // نرفع قيمة المتغير التالي $successRate = 50; while (true) { $compaines = successfulCompaines($compaines, $successRate); // ننقل جملة الطباعة إلى هنا echo 'Congrats for ' . $compaines[0]; echo "<br>"; if (count($compaines) == 1) { break; } $successRate /= 2; }
  14. لا يجب أن تستخدم المعامل == عند المقارنة في PHP خصوصًا عند مقارنة النصوص حيث ستحصل على نتيجة مختلفة عما تتوقعه، فعلى سبيل المثال كل العمليات التالية سوف تُعيد True: <?php echo "hi" == 0; // True echo 1 == '1'; // True echo '80000' == '8e4'; // True وذلك لأن PHP تقوم بتحويل أنواع القيم، ومن الأفضل إستخدام المعامل === بدلًا من == عند المقارنة بين قيمتين: <?php echo "hi" === 0; // False echo 1 === '1'; // False echo '80000' === '8e4'; // False
  15. إن كان لديك عنوان URL مُخزن في متغير، فيمكنك تحليله وإستخراج query منه من خلال الدالة parse_url و parse_str بالشكل التالي: <?php $url = "https://www.example.com/search.php?q=myquery&abc=123"; // نستخرج الـ query من العنوان $query = parse_url($url, PHP_URL_QUERY); // q=myquery&abc=123 // نقوم بتحويل النص السابق إلى مصفوفة ترابطية key-value $queries = array(); parse_str($query, $queries); // يمكن إستخدام المصفوفة أو أحد المفاتيح منها بالشكل التالي echo $queries['abc']; // 123 echo $queries['q']; // myquery ملاحظة: بدءًا من الإصدار PHP 7.2 لا يُفضل استخدام الدالة parse_str()‎ بدون المعامل الثاني لها، لأنها ستقوم في هذه الحالة بتحويل المفاتيح keys إلى متغيرات (q$ و abc$) ، وقد يقوم بعض المخترقين Hackers بإستغلال هذا الأمر في صالحهم ومحاولة إختراق الموقع. يمكنك الإطلاع على هذه المقالة لمزيد من المعلومات عن كلا الدالتين: أو من خلال موسوعة حسوب: الدالة parse_str()‎ في PHP
  16. لا يوجد رقم محدد، ويختلف الأمر من شركة إلى أخرى، وأيضًا يجب أن تحدد ما هي الوظيفة التي ستعمل بها بالتحديد (ما هو المسمى الوظيفي)، هل ستعمل مطور وجهات أمامية أم مطور وجهات خلفية أم مطور تطبيقات للجوال .. إلخ، يمكنك الإطلاع على الإجابة الكاملة من هنا: هنا بعض المساهات التي قد تفيدك: رواتب المبرمجين في الوطن العربي كم رواتب مبرمجي المواقع في الوطن العربي؟ (المتدرب، الـ Junior، الـ Senior، الـ TeamLeader، الـ ProjectManager) مرتبات المبرمجين ملاحظة: بعض المساهمات هنا قديمة نوعًا ما لكنها ماتزال صالحة أيضًا.
  17. لا يوجد رقم ثابت فالأمر يختلف من مسمى وظيفي لآخر (مطور واجهات أمامية Frontend، مطور تطبيقات، مطور وجهات خلفية Backend .. إلخ) كما أن الدخل الشهري للمبرمج يعتمد على الشركة التي يعمل بها أو المجهود الذي يقوم به (إذا كان يعمل كمستقل في أحد مواقع العمل الحر مثل خمسات أو مستقل) ويختلف هذا الأمر من دولة لآخر كذلك، على سبيل المثال قد يكون هناك شركة تدفع للمبرمج X دولار، وشركة أخرى تدفع الضعف لنفس المبرمج. أيضًا تُعد المميزات التي تقدمها الشركة للمبرمج عاملًا مهمًا في تحديد المرتب، فعلى سبيل المثال قد تحصل على مرتب كبير نسبيًا من أحد الشركات ولكن لا تحصل على أي تأمينات أو قد تعمل في بيئة سيئة نوعًا ما مما يجعل العمل في هذه الشركة صعبًا وغير مريح، وقد تقوم شركة أخرى بدفع مرتب متوسط لنفس المبرمج مع الحصول على بعض الإمتيازات الوظيفية مما يجعل العمل في هذه الشركة مريح ومربح للمبرمج كذلك في نفس الوقت، لذلك فإن الراتب الشهري ليس العامل الوحيد الذي يجب أن يُأخذ في الحسبان. هناك طريقة بسيطة يمكنك إستخدامها لحساب متوسط الدخل الشهري (في مواقع العمل الحر)، قم بالذهاب إلى أحد مواقع العمل الحر مثل مستقل على سبيل المثال، وقم بقراءة المشاريع المطلوبة ومتوسط العرض وميزانية كل مشروع، وقم بحساب عدد المشاريع التي يمكنك أن تقوم بها شهريًا، ومن خلال هذه الأرقام تستطيع تحديد متوسط الدخل الذي يمكنك الحصول عليه إن عملت كمستقل. وعندما تنهي أحد دورات حسوب سوف تحصل على العديد من النصائح والمساعدة أثناء فترة بحثك عن عمل، وأنا أقتبس هنا من صفحة الأسئلة الشائعة: الأمر الآخر هو أن أكاديمية حسوب تضمن لك استرداد استثمارك خلال 6 أشهر إن لم تحصل على عمل بعد إتمام الدورة: إن أردت العمل كمستقل، فستجد في قسم العمل الحر الكثير من المقالات المفيدة والنصائح والإرشادات التي ستمكنك من العمل كمستقل بشكل إحترافي
  18. في مثل هذه الحالة يمكنك إستعمال الدالة explode والدالة implode، على النحو التالي: <?php $string = "https://www.example.com"; // تقسيم النص بإستخدام نقطة $s = explode(".", $string); // نحذف الجزء الأول من النص unset($s[0]); // نجمع باقي النص بنقطة بين كل جزء $s = implode(".", $s); echo $s; // "example.com" يمكنك الإطلاع على توثيق الدالة explode والدالة implode من خلال موسوعة حسوب.
  19. وعليكم السلام ورحمة الله وبركاته دورة تطوير واجهات المستخدم Frontend الخاصة بأكديمية حسوب هي دورة متخخص في تطوير واجهات المواقع من الصفر، أي أنك لا تحتاج إي خبرة برمجية سابقة لكي تبدأ في الدورة، وفيها يتم شرح كل الأساسيات والكثير من الأمور المتقدمة من خلال عمل العديد من المشاريع الكبيرة. في هذه الدورة يتم شرح الأساسيات مثل HTML و CSS و JavaScript و jQuery و Bootstrap وتقنيات أخرى مثل Webpack و Git و GitHub و غيرها من تقنيات، وفي كل مسار يتم عمل مشروع كامل من الصفر، وهنا بعض الأمثلة: تطوير واجهة موقع سبيه باليوتيوب تطوير صفحات هبوط Landing Page تطوير متجر إلكتروني كامل ومتعدد الصفحات تطوير لوحة تحكم Dashboard كاملة تطوير موقع شركة وغيرها من المشاريع وكل المشاريع والتطبيقات التي يتم عملها في هذه الدورة يتم كتابتها من الصفر بدون إستخدام أي برامج مساعدة، حيث أن الطالب سيكون بعد إنهائه لهذه الدورة قادرًا على تطوير أي واجهة يرغب بها بنفسه ومن الصفر، وذلك لأن هذه الدورة تحتوي على 54 ساعة فيديو من المحتوى التعليمي العملي ستتمكن من تعلّم تطوير واجهات المستخدم خطوة بخطوة اعتمادًا على التجربة العملية والمادة العلمية التي يقدمها مدربون محترفون. يمكنك معرفة المزيد عن هذه الدورة من خلال الصفحة الخاصة بها من هنا (دورة تطوير واجهات المستخدم).
  20. في المصفوفات Arrays يتم ترتيب العناصر كما تم إدخالها إلى المصفوفة، فعلى سبيل المثال يمكننا أن نقوم بعمل مصفوفة بالشكل التالي: const myArr = ['zoom', 'hello', 'hi', 'world', 'app'] console.log(myArr); // ['zoom', 'hello', 'hi', 'world', 'app'] وبالتأكيد فإن الترتيب مهم في المصفوفات، وذلك لأننا نصل إلى أحد القيم في المصفوفة من خلال الفهرس index، وبالتالي إذا كان الترتيب غير مهم فكيف سنصل إلى أحد العناصر في المصفوفة؟! console.log(myArr[0]) // zoom console.log(myArr[3]) // world أما بالنسبة للكائنات Objects فإننا نستخدم المفاتيح keys للوصول إلى القيم، لذلك لا يهم الترتيب على الإطلاق في هذه الحالة: const myObj = {zoom: true, hello: 'some value', app: 'downloaded'} console.log(myObj.zoom); // true console.log(myObj.app); // 'downloaded'
  21. نعم يمكنك عمل ذلك من خلال إستعمال SQL التالي: SELECT * FROM `countries` WHERE name != "saudi arabia"; بهذا الشكل سوف يتم تحديد كل الدول ما عدا السعودية. وإذا كنت تريد تحديد كل الدول ما عدا السعودية ومصر على سبيل المثال فيمكنك أن تستخدم المعامل NOT IN: SELECT * FROM `countries` WHERE name NOT IN ("saudi arabia", "egypt"); بالتأكيد يمكنك أن تقوم بإضافة قدر ما تشاء من دول إلى الإستعلام السابق، وسوف يتم تحديد باقي الدول فقط.
  22. برنامج الفوتوشوب Adobe Photoshop يُستخدم لتعديل الصور (وإنشهاء من الصفر في بعض الأحيان)، ويستخدمه المصممين Designers، أم البرمجة فهي مجال مختلف بالكامل، وبها الكثير من الفروع (برمجة المواقع، والتطبيقات وبرامج سطح المكتب .. إلخ)، وكلاهما له الكثير من الفرص في سوق العمل العربي والأجنبي، ويمكنك التأكد من هذا الأمر من خلال تصفح مواقع العمل الحر مثل مستقل وخمسات. يمكنك الإطلاع على هذه المقالة لمعرفة مجالات البرمجة الرئيسية ومتطلبات كل مجال: أيضًا تستطيع الإطلاع على قسم التصميم للوصول إلى العشرات من المقالات الخاصة بالتصميم (يشمل العديد من البرامج غير Photoshop) لكي تُحدد المجال الذي تريد العمل به عليك أن تقوم بتجربة كلاهما وتختار المجال المناسب لك، فلن يستطيع أحد أن يخبرك ما هو المجال الأنسب لك أكثر من نفسك.
  23. يمكنك تخزين الدالة setInterval في متغير وحذفه عندما يتم الضغط على زر ما بالشكل التالي: var log = setInterval(function () { console.log(Date.now()); }, 1000); document.addEventListener("click", function () { clearInterval(log); }); عند تشغيل الكود سوف يتم طباعة الوقت الحالي كل ثانية، ولكن بمجرد الضغط في أي مكان في الصفحة سوف يتم إيقاف الدالة. أيضًا يمكنك جعل الكود يعمل مرة أخرى عند الضغط لمرة ثانية على الصفحة من خلال الكود التالي: let intervalRemoved = false; const myFunc = function () { console.log(Date.now()); } let log = setInterval(myFunc, 1000); document.addEventListener("click", function () { if (intervalRemoved) { log = setInterval(myFunc, 1000); } else { clearInterval(log); } intervalRemoved = !intervalRemoved; });
  24. يوجد مشكلة في المستودع الذي يحتوي على الحزم والبرمجيات، حاول تغير المستودع من خلال الأمر termux-change-repo ثم اختر Main Repository (في الغالب سيكون هذا الخيار فقط هو المتاح)، بعد ذلك قمت بإختيار Default repositories with cloudflare (الإختيار الأول في الغالب). بعد ذلك قم بإتباع خطوات التثبيت من البداية مرة أخرى.
  25. من الجيد أنك حددت ما تريد فعله، الآن عليك تحديد التقنيات التي تريد أن تستعملها، ولكن في البداية هل ستقوم بعمل تطبيقات للأندرويد أم iOS أم كلاهما؟ تحديد هذا الأمر سيسهل عليك إختيار التقنيات التي سوف تستخدمها تطبيقات الجوال تنقسم إلى نوعين أساسين، تطبيقات هجينة Hybrid Apps وتطبيقات أصيلة Native Apps، هنا فيديو يوضح الفرق بينهما ومميزات وعيوب كلًا منهما: بعد تحديد نوع التطبيقات التي سوف تقوم بعملها، عليك تحديد ما لغة البرمجة التي سوف تستخدمها، في هذه المقالة يتم شرح كل ما هو مطلوب لتعمل البرمجة ويوجد قسم يشرح التقنيات المستخدمة في تطوير تطبيقات الجوال: إن أخترت عمل التطبيقات الأصلية Native Apps فأمامك بعض الإختيارات مثل: لغة Java و Kotlin لتطوير تطبيقات الأندرويد لغة Swift و Object-C لتطوير تطبيقات iOS أما إن أخترت عمل تطبيقات هجينة فتوجد خيارات أكثر: React Native Flutter Xamarin Cordova وتستطيع الإطلاع على هذا السؤال:
×
×
  • أضف...