هل يمكنك أن تجعلني أفهم كائنات الأحداث الديناميكية والمجردة بسهولة؟

StackOverflow https://stackoverflow.com/questions/471144

  •  19-08-2019
  •  | 
  •  

سؤال

لقد قمت بكتابة تطبيقات تعتمد على الأحداث C++ باستخدام MFC لأزرار واجهة المستخدم الرسومية، وأستخدم أحداث HTML مثل onmousedown لتشغيل بعض Javascript في صفحة ويب.تعتبر فكرة البرمجة المبنية على الأحداث بديهية عند استخدام الواجهة وتكون الأحداث مشفرة بشكل ثابت.

أعرف كيفية استخدام مؤشر دالة في لغة C، وأرى كيف يستخدمها Windows لتشغيل حلقة حدث.يمكنني كتابة تعليمات برمجية لاستدعاء وظيفة مختلفة ديناميكيًا.

مشكلتي هي الابتعاد عن وقت الترجمة وإلى وقت التشغيل.أنا أتحدث بأي لغة هنا، ولكن إذا كنت بحاجة إلى لغة، فاختر Javascript أو PHP حيث أستخدمهما كثيرًا هذه الأيام.ليس لدي فهم على الإطلاق لكيفية استخدام كائن الحدث الخاص بي لإنجاز شيء ما.إنه ليس مجرد مفهوم أحصل عليه.وبما أنني لا أستخدمها، فلا أعرف ما هو استخدامها العملي.

على سبيل المثال، أفترض أنني إذا أردت إنشاء لعبة مخصصة تعتمد على الأدوار، فقد أستخدم كائنات الحدث لتمثيل تأثير بعض قدرة قطع اللعبة التي تحتاج فقط إلى "الحدوث".

هل يمكن لأي شخص أن يقدم لي استخدامًا بسيطًا للأحداث المخصصة؟أو المواقف التي يكون فيها ذلك مفيدًا أو عمليًا؟هل يعتمد الأمر بشكل كبير على اللغة والبيئة وكيفية التعامل مع الأحداث؟قد تكون إجابة جافا سكريبت جيدة، لكنني أقرأ العديد من اللغات.

آسف، فأنا ناقص في هذا الصدد وأحتاج إلى بعض الأفكار العملية المتقدمة (المتوسطة؟).إنها مثل المؤشرات في C.لقد "أحصل" على المؤشرات وكيف أنهم صديقك.ولكن كان هناك وقت لم أفعل فيه ذلك، وما زال الكثير من الأشخاص الذين أعرفهم لا يفعلون ذلك.الأمر بسيط بمجرد حصولك عليه، فأنا لا أحصل على الأحداث الديناميكية المخصصة بهذه الطريقة.

هل كانت مفيدة؟

المحلول

عندما نتحدث عن البرمجة الموجهة للحدث، فإننا نتحدث عادة عن واحد أو أكثر من تطبيقات نمط تصميم المراقب.وأحد أهداف نمط تصميم المراقب هو تحقيقه اقتران فضفاض بين الكائنات.

ربما لا يعني هذا الكثير بدون قدوة جيدة، ومن المؤكد أن هناك الكثير من الأمثلة الجيدة؛أشك في أن فريقي سيكون الأفضل منهم، لكنني سأضربه رغم ذلك.تخيل شيئين.يريد أحد الكائنات معرفة متى يحدث شيء ما مع الكائن الآخر، حتى يتمكن من فعل شيء بنفسه - ربما يريد كلب العائلة، روفر، الترحيب بأبي عند الباب عندما يعود إلى المنزل من العمل.هناك طريقتان يمكنك من خلالهما برمجة هذا السيناريو، أليس كذلك؟

  • تأكد من أن أبي لديه إشارة إلى Rover، وعندما يعود إلى المنزل، اتصل بطريقة Rover's GreetingDatAtTheDoor()، أو

  • امنح روفر إشارة إلى أبي ، واستمع إلى حدث أبي أونارفيهوم ، وعندما يطلق النار ، اتصل بالترحيدداتور () داخليًا.

ظاهريًا، قد لا يبدو أن هناك فرقًا كبيرًا بين الاثنين، لكن في الواقع، لقد أحرق أبي بعضًا من تنفيذ روفر في ذهنه؛إذا كان لا بد من تغيير تطبيق Rover لسبب ما، فسيتعين علينا إجراء تغييرات في مكانين:مرة في روفر، ثم مرة أخرى في أبي.ربما ليست صفقة كبيرة، لكنها لا تزال ليست مثالية.

الآن تخيل أن أمي تريد تحية أبي أيضًا.والقط يا سيدييريد Bigglesworth، الذي لا يحب أبي كثيرًا، التأكد من عدم وجوده، لذلك يفضل الخروج.ويريد أحد الجيران، جو، أن يعرف متى سيعود أبي إلى المنزل، حتى يتمكن من إزعاجه بشأن العشرين دولارًا التي يدين له بها أبي.كيف نأخذ في الاعتبار كل هذه السيناريوهات، والسيناريوهات الإضافية التي ستظهر حتماً؟إن وضع إشارات إلى طريقة GreetingHusband () الخاصة بأمي، وطريقة getOutNow () الخاصة بالقطة، وطريقة GreetingDadAtTheDoor () الخاصة بالكلب، وطريقة goGetMyMoney () الخاصة بـ Joe في تعريف فئة الأب من شأنه أن يفسد الأمور بسرعة بالنسبة لأبي - وبدون سبب وجيه، نظرًا لأن كل شيء يحتاج أبي حقًا إلى القيام بنفسه بالعودة إلى المنزل.تريد الأم والكلب والقطة والجار فقط أن يتم إعلامهم عند حدوث ذلك، حتى يتمكنوا من القيام بكل ما تتطلبه تطبيقاتهم الداخلية.

تتعامل اللغات مع تفاصيل هذه الأشياء بطرق مختلفة ، ولكن كما سترى عندما تبدأ في التجول ، فإن النمط عادة ما يتضمن وجود صفيف ، أو بنية تشبه الصفيف ، في الحدث "المرسل" (في هذه الحالة ، أبي - أي الكائن الذي يهتم به أي شخص آخر) ، و "المشتركين" (على سبيل المثال ، أمي ، القط ، روفر ، وجو) جميعهم "تسجيل" من خلال استدعاء طريقة مكشوفة علنًا على المرسل والتمرير في الإشارات إلى أنفسهم - المراجع التي تنتهي ، في شكل ما ، في مجموعة أبي من "المشتركين". ثم ، عندما يعود أبي إلى المنزل ، "يرسل" حدثًا - "أنا في المنزل!" الحدث ، على سبيل المثال - وهي وظيفة في الأساس تحلق على كل من مشتركيه ويستدعيهم بطريقة يمكن الوصول إليها للجمهور من تلقاء نفسها - إنها طريقة لا يعرفها أبيها ، لأنها لا يجب أن يعرفها ، لأنها قدمها المستمع عندما اجتازه/هي/هو.

نظرًا لأنني أقوم ببرمجة ActionScript في الغالب هذه الأيام، فإليك كيف قد يبدو الأمر في عالمي - على سبيل المثال، كما تم الإعلان عنه من داخل صف أمي:

var dad:Dad = new Dad();
dad.addEventListener(DadEvent.ARRIVED_HOME, greetHusbandAtDoor);

private function greetHusbandAtDoor(event:DadEvent):void
{
   // Go greet my husband
}

في أبي، إذن، كل ما علي فعله، عندما أعود إلى المنزل، هو:

dispatchEvent(new DadEvent(DadEvent.ARRIVED_HOME));

...ولأن Flash يتعامل مع إرسال الحدث وتفاصيل الإشعارات نيابةً عني (مرة أخرى، كل شخص يفعل ذلك بشكل مختلف قليلاً، ولكن داخليًا، يتبع Flash النموذج المفاهيمي الذي وصفته)، يعود والدي إلى المنزل، ويقوم كل فرد من أفراد الأسرة بما وقع عليه ما يصل إلى القيام به تلقائيا.

نأمل أن يفسر هذا بعض الشيء - كيف يبدو التفكير في الحدث، وماذا يعني الاقتران السائب، ولماذا هو مهم، وما إلى ذلك.حظا سعيدا!

نصائح أخرى

في لالناطقة المترجمة، تكتب حلقة الأحداث الخاصة بك. بلغة وقت التشغيل، انها تنفذ من قبل البيئة المضيفة بالفعل، ومبرمج يحصل سوى واجهة المستخرجة إلى نظام الأحداث. أنت لا ترى في حال حلقة.

وهناك وجهين لبناء وظيفة مع الأحداث. الأول هو تحديد الظروف التي حدث سوف اطلاق النار. في جافا سكريبت في المتصفح، وليس هناك واحد "mousedown" الحدث. هناك في الواقع واحدة لكل عنصر على الصفحة. في هذه الحالة، شرط عند أي منهم سوف النار يستند على حد سواء على موقع مؤشر الماوس، وعما إذا كان زر الماوس تحولت للتو من الدولة يصل إلى حالة أسفل. قد يؤدي هذا الشرط أحداث متعددة لاطلاق النار. (في المستعرض، هناك شيء يسمى الحدث "السطح" وهذا ما المتعلقة بذلك. ولكن هذا خارج النطاق هنا).

وهذا وجه من وجوه أخرى غير معالج الحدث. حدث يحدث بغض النظر عن ما إذا كان هناك معالج لذلك أم لا. توفير معالج متروك لكم. في جافا سكريبت، وظائف هي قيم من الدرجة الأولى. الحصول على تعريفها في وقت التشغيل، وليس في تجميع زمنيا لذلك ليس هناك حاجة للمؤشرات أو القفز الجداول. يمكنك إنشاء وظيفة جديدة في وقت التشغيل، وتعيين ذلك إلى خاصية خاصة أن بيئة المضيف تبدو حتى عندما حرائق حدث معين.

وهكذا تجاوز المكدس، سوف يكون هناك معالج حدث على كل الأحداث السهم إلى الأسفل ل"عند _ النقر"، الأمر الذي يجعل السهم الأحمر، التناقصات عدد، يتحقق بعض المتغيرات الأخرى وبشروط يظهر إعلام. ثم عندما يعود، معالج فهو يعيد السيطرة على موضوع لمتصفح، وسبحان الله يمكن للمستخدم التفاعل مع المتصفح مرة أخرى. (جميع التفاعلات تتوقف في حين يتم التعامل مع هذا الحدث، لذلك كنت جعله أفضل سريع). وهنا مثال باستخدام مكتبة مسج.

jQuery("a .downarrow")
.click(function(e){ e.target.style.color="red" /* ... do other things */ });

وأو في جافا سكريبت الخام (الإصدار 1.6) قد يكون

Array.prototype.slice.apply(document.getElementsByTagName("a"))
.filter(function(o){ return !!(/downarrow/).exec(o.className)})
.forEach(function(o){ 
    o.onclick= function(e){ 
        e.target.style.color="red" /* ...do other things * / 
    }
 });

وانها حقا بهذه البساطة. السبب الرئيسي الذي من شأنه أن تفعل شيئا من هذا القبيل هو أنه يتيح التفاعل غير المتزامن. لا تقدم تطبيق واجهة المستخدم الرسومية في خط مستقيم، خطوة خطوة. لديها للرد حيوي لإدخال المستخدم. الأحداث هي وسيلة لنوع وهمية مظهر تطبيق مؤشرات. ويمكن أن ننظر للمستخدم أن أشياء كثيرة تحدث في وقت واحد دون مقاطعة بعضنا البعض.

هل يمكن استخدام المكتبة لتحديد حدث مخصص. ربما هذا من شأنه أن ترميز بعض النطاقات حدث معين. على سبيل المثال: لديك لعبة الشطرنج التي يتم التفكير في الخطوة التالية. عملية للبحث عن هذه الخطوة نفاد الوقت. لعبة الشطرنج ويمكن اطلاق النار على "onComputerMove" الحدث. هل يمكن التعامل مع هذا الحدث مع وظيفة أن الاستيلاء على المواصفات لهذه الخطوة، وتحديث التمثيل البصري للرقعة الشطرنج، ودفعها رسالة للمستخدم، والمخارج. ثم عندما يتحرك لاعب يمكنك إطلاق حدث "onPlayerMove"، الذي يقوم بالكثير من نفس الشيء.

أروع ما في الأحداث هو تقليل الاقتران الصريح ثنائي الاتجاه بين وحدتين أو فئتين.

لنفترض أن لدي فئتين:الطفل والأم


بدون أحداث، أرى تقريبًا طريقتين للسماح للأم بإطعام طفلها:

  • الأم تدعو baby.pokeBelly() طريقة على الطفل كل نصف ساعة لمعرفة ما إذا كان عليك الاتصال به baby.fillWith(milk).
    المشكلة هي أن خيط الأم يجب أن ينتظر طوال اليوم بعد ولادة الطفل في حلقة زمنية
  • يعرف الطفل أمه المرتبطة به ويتصل بـ أ mommy.feed(me) الطريقة، والتي بدورها تدعو baby.fillWith(milk).
    المشكلة إذن هي أن تطلب من طفل بسيط أن يطلب من أمه المناسبة أن تملأ بطنه.
    الأطفال لا يفعلون ذلك، إذ ينبغي عليهم أن يظلوا بسيطين.

مع الأحداث، يمكنك ربط أ Mommy.OnBabyCries(baby) إلى طفلها baby.Cry حدث:

void Mommy.OnBabyCries(baby) {
    baby.fillWith(milk)
}

بعد ذلك، إذا أراد الطفل أن يأكل، كل ما عليه فعله هو إثارة حدث البكاء.

ويبقى المنطق في الأم، أو حتى في وقت لاحق في أي جليسة أطفال، ويبقى الطفل سعيدا، دون الحاجة إلى القلق.

وأنا لا أعرف ما إذا كنت أفهم تماما سؤالك ولكن فئة مع حدث هو تماما مثل واجهة المستخدم الرسومية مع زر واحدة. مجرد التفكير في ذلك مثل homonculus ... داخل كل فئة مع حدث هناك القليل من شخص مع زر الظاهري الضغط على الخصم. انه لا يعرف ماذا سيفعل زر، لكنه يعرف متى تضغط عليه. أعتقد الآن من فئة ذات الصلة مع شخص آخر يذكر في ذلك. هذا الشخص يعرف أنه عندما يسمع الرسالة التي تم الضغط على زر، كان من المفترض أن تفعل شيئا.

وفي أي وقت تريد الرجل الثاني لمعرفة ما فعل الرجل الأول، يمكنك الاتصال لوحة مفاتيح بين الدرجة الأولى والدرجة الثانية (اشترك في الحدث). عندما يضغط الرجل الأول على زر (حرائق الحدث)، الرجل الثاني يفعل كل ما يعلم أنه من المفترض أن تفعل ...

وأنا لا أعرف إذا كان ذلك يساعد أو أنا فقط على التفكير رحلة حمض الناس صغيرة قليلا في برامج بلدي ...

في StackOverflow, ، عندما تقوم بالتصويت بالرفض، تنخفض سمعتك ويتحول سهمك لأسفل إلى اللون الأحمر.

عادة، تكتب واحدة onclick, ، وقم بتحديث جميع العناصر الموجودة فيه، وحاول ألا تنسى تغييره في كل مرة يتغير فيها تخطيط الصفحة.

بدلا من ذلك، يمكنك أن تعلن onVoteDown الحدث، أطلق النار عليه onclick والاشتراك في هذا الحدث:

  • سمعتك div
  • سهمك img
  • لك XmlHTTPRequest الذي يرسل صوتك إلى الخادم.

لست متأكدًا تمامًا من نوع الإجابة التي تبحث عنها، لذا أعتذر إذا لم تكن هذه الإجابة قريبة.;)


بواسطة مخصص, ، هل تعني الإجراءات المخصصة, مشغلات مخصصة, ، أو حقا الأحداث المخصصة?

على سبيل المثال:أ عمل مخصص سوف يستجيب لحدث محدد مسبقًا (على سبيل المثال، النقر بالماوس)، أ الزناد المخصص سيكون تزوير النقر بالماوس عبر البرنامج النصي، و حدث مخصص سيكون مستمعًا لا تحدده اللغة أو غير متاح بسهولة.

إذا كنت تبحث عن الأحداث المخصصة, ، لا أستطيع مساعدتك حقًا.رغم ذلك، لا أعتقد أن هناك دعمًا كبيرًا لهم في JavaScript.


لتعريف ان فعل...

يتم إنشاء الأحداث عادةً عبر خصائص محددة مسبقًا لكائن ما، على سبيل المثال window.onload.بشكل افتراضي، كلهم ​​متساوون undefined أو null.لذا، لاستخدامها، عليك تعيينها على قيمة دالة.

يمكنك استخدام وظيفة "مجهولة":

window.onload = function (eventObject) {
    /* ... */
};

أو قم بتعيينها إلى مرجع دالة (ليست هي نفسها، ولكنها تشبه المؤشر):

function handleOnload(eventObject) {
    /* ... */
}

window.onload = handleOnload; /* note the lack of parenthesis */

عندما يتم تشغيل الحدث، يتم استدعاء الدالة.لذلك، في أي من الإعدادين، عندما تنتهي الصفحة من التحميل، يتم وضع الكود بدلاً من ذلك /* ... */ سيتم تنفيذه.

هناك أيضًا طرق أكثر رسمية متاحة لإنشاء الأحداث.يحدد W3C addEventListener بينما يستخدم IE attachEvent. مزيد من المعلومات.

هناك الكثير من المراجع المتاحة لمعرفة قائمة الأحداث المتاحة.إليك 2 من المفترض أن يمنحك قاعدة جيدة:


يتعامل المتصفح عادةً مع تشغيل الأحداث - إما لأحداث المتصفح (onload) أو أحداث المستخدم (onclick).تهدف الخاصية والوظيفة إلى الاستجابة.

اثار الحدث الخاص بك ليس أسهل شيء يمكن تحقيقه.لتحديد تماما Event الكائن يأخذ بعض العمل - و يختلف بين المتصفحات.

على الرغم من ذلك، إذا لم تكن بحاجة إلى Event الكائن، يمكنك ببساطة استدعاء الحدث:

window.onload();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top