٧.٨ الأحداث — الجزء الثاني¶
سنستخدم مستند HTML التالي في هذا الدرس:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>The website</title>
<style>
section{
margin: 2rem 0;
padding: 2rem 0;
border-bottom: 0.3rem solid CadetBlue;
}
#box-1{
width: 25rem;
height: 25rem;
background: lightblue;
}
#box-2{
width: 20rem;
height: 20rem;
background: Olive;
}
#box-3{
width: 15rem;
height: 15rem;
background: tomato;
}
#box-4{
width: 10rem;
height: 10rem;
background: yellow;
}
</style>
</head>
<body>
<header>
<h1>Welcome to our website</h1>
</header>
<section id="container">
<div id="box-1">
<div id="box-2">
<div id="box-3">
<div id="box-4"></div>
</div>
</div>
</div>
</section>
<script src="script.js"></script>
</body>
</html>
الكلمة this¶
التمرين 1: إذا نقر المستخدم الصندوق الأول، تصبح حدوده 0.3rem #000 dotted.
let el = document.getElementById("box-1");
el.onclick = function(e){
e.preventDefault();
el.style.border = "0.3rem #000 dotted";
}
قد يصل حدث النقر إلى العنصر عند النقر عليه أو على أحد أبنائه، بفضل انتشار الحدث.
التمرين 2: ارجع إلى التمرين 1؛ ما هدف حدث النقر؟
let el = document.getElementById("box-1");
el.onclick = function(e){
e.preventDefault();
console.log(e.target);
}
قد تختلف النتيجة:
//if the user clicks on the first box, the target is:
<div id="box-1"></div>
//if the user clicks on the second box, the target is:
<div id="box-2"></div>
//if the user clicks on the third box, the target is:
<div id="box-3"></div>
//if the user clicks on the fourth box, the target is:
<div id="box-4"></div>
التمرين 3: ارجع إلى التمرين 1؛ استبدل el.style.border = "0.3rem #000 dotted" بـ this.style.border = "0.3rem #000 dotted" `
let el = document.getElementById("box-1");
el.onclick = function(e){
e.preventDefault();
this.style.border = "0.3rem #000 dotted";
}
التمرين 4: ارجع إلى التمرين 3؛ اطبع this في وحدة التحكم.
let el = document.getElementById("box-1");
el.onclick = function(e){
e.preventDefault();
this.style.border = "0.3rem #000 dotted";
console.log(this);
}
النتيجة هي: <div id="box-1"></div>
this
في التمرين السابق، تشير this إلى العنصر الذي ربطنا به دالة المعالجة العادية.
دالة معالجة الحدث
في التمرين 4; function(e){//code} تُسمّى دالة معالجة للحدث.
التمرين 5: إذا نقر المستخدم الصندوق الثالث، فغيّر خلفيته إلى black.
let el = document.getElementById("box-3");
el.onclick = function(e){
e.preventDefault();
this.style.backgroundColor = "#000";
}
لاحظ أن نقر الصندوق الثالث أو أحد أبنائه يغيّر خلفية الصندوق الثالث.
addEventListener()¶
التمرين 6: إذا نقر المستخدم الصندوق الرابع، فغيّر خلفيته إلى Gainsboro.
let el = document.getElementById("box-4");
el.onclick = function(e){
e.preventDefault();
this.style.backgroundColor = "Gainsboro";
}
التمرين 7: ارجع إلى التمرين 6؛ أضف أيضًا حدًا للصندوق الرابع عند النقر عليه. 0.4rem LemonChiffon double.
let el = document.getElementById("box-4");
el.onclick = function(e){
e.preventDefault();
this.style.backgroundColor = "Gainsboro";
this.style.border = "0.4rem LemonChiffon double";
}
التمرين 8: أنشئ دالة تغيّر لون خلفية عنصر إلى SpringGreen.
function changeBgColor(){
this.style.backgroundColor = "SpringGreen";
}
التمرين 9: أنشئ دالة تضيف حدًا من نوع 1rem CadetBlue dotted إلى عنصر.
function addBorder(){
this.style.border = "1rem CadetBlue dotted";
}
التمرين 10: اربط دوال المعالجة في التمرين 8 و التمرين 9 بحدث النقر على الصندوق الثالث.
let el = document.getElementById("box-3");
el.onclick = function(e){
e.preventDefault();
this.style.backgroundColor = "SpringGreen";
}
el.onclick = function(e){
e.preventDefault();
this.style.border = "1rem CadetBlue dotted";
}
في التمرين 10؛ حلّ المعالج الثاني محل الأول، لذلك لم يعد النقر يغيّر الخلفية.
التمرين 11: ادرس المثال التالي.
let el = document.getElementById("box-3");
function changeBgColor(){
this.style.backgroundColor = "SpringGreen";
}
function addBorder(){
this.style.border = "1rem CadetBlue dotted";
}
el.addEventListener("click", changeBgColor);
el.addEventListener("click", addBorder);
addEventListener()
العامل el.addEventListener(event, funcName) تربط دالة معالجة بحدث على عنصر، وتسمح بإضافة عدة معالجات.
التمرين 12 أنشئ دالة تضيف النص "this is a text" إلى عنصر.
function addText(){
this.appendChild(document.createTextNode("this is a text"));
}
التمرين 13: اربط دالة المعالجة في التمرين 12 بالعنصر في التمرين 11 عند وقوع حدث النقر.
let el = document.getElementById("box-3");
function changeBgColor(){
this.style.backgroundColor = "SpringGreen";
}
function addBorder(){
this.style.border = "1rem CadetBlue dotted";
}
function addText(){
this.appendChild(document.createTextNode("this is a text"));
}
el.addEventListener("click", changeBgColor);
el.addEventListener("click", addBorder);
el.addEventListener("click", addText);
التمرين 14 أنشئ دالة تغيّر لون عنصر إلى red.
function changeColor(){
this.style.color = "red";
}
التمرين 15: اربط دالة المعالجة في التمرين 14 بالعنصر في التمرين 13 عند وقوع حدث النقر.
let el = document.getElementById("box-3");
function changeBgColor(){
this.style.backgroundColor = "SpringGreen";
}
function addBorder(){
this.style.border = "1rem CadetBlue dotted";
}
function addText(){
this.appendChild(document.createTextNode("this is a text"));
}
function changeColor(){
this.style.color = "red";
}
el.addEventListener("click", changeBgColor);
el.addEventListener("click", addBorder);
el.addEventListener("click", addText);
el.addEventListener("click", changeColor);
التمرين 16 أنشئ دالة تغيّر حجم خط نص العنصر إلى 1.5rem.
function changeFontSize(){
this.style.fontSize = "1.5rem";
}
التمرين 17: اربط دالة المعالجة في التمرين 16 بالعنصر في التمرين 15 عند وقوع حدث النقر.
let el = document.getElementById("box-3");
function changeBgColor(){
this.style.backgroundColor = "SpringGreen";
}
function addBorder(){
this.style.border = "1rem CadetBlue dotted";
}
function addText(){
this.appendChild(document.createTextNode("this is a text"));
}
function changeColor(){
this.style.color = "red";
}
function changeFontSize(){
this.style.fontSize = "1.5rem";
}
el.addEventListener("click", changeBgColor);
el.addEventListener("click", addBorder);
el.addEventListener("click", addText);
el.addEventListener("click", changeColor);
el.addEventListener("click", changeFontSize);
عند استخدام addEventListener، اكتب اسم الحدث دون البادئة on. مثلًا، اكتب click بدلًا من onclick.
removeEventListener()¶
التمرين 18: ارجع إلى التمرين 17؛ أزل ربط changeColor معالجًا للحدث من العنصر. تلميح: استخدم el.removeEventListener('click', 'changeColor').
let el = document.getElementById("box-3");
function changeBgColor(){
this.style.backgroundColor = "SpringGreen";
}
function addBorder(){
this.style.border = "1rem CadetBlue dotted";
}
function addText(){
this.appendChild(document.createTextNode("this is a text"));
}
function changeColor(){
this.style.color = "red";
}
function changeFontSize(){
this.style.fontSize = "1.5rem";
}
el.addEventListener("click", changeBgColor);
el.addEventListener("click", addBorder);
el.addEventListener("click", addText);
el.addEventListener("click", changeColor);
el.addEventListener("click", changeFontSize);
el.removeEventListener('click', changeColor);
removeEventListener()
العامل el.removeEventListener(event, funcName) تزيل ربط دالة معالجة بالعنصر والحدث المحدّدين.
التمرين 19: ارجع إلى التمرين 18؛ أزل ربط addBorder معالجًا للحدث من العنصر.
let el = document.getElementById("box-3");
function changeBgColor(){
this.style.backgroundColor = "SpringGreen";
}
function addBorder(){
this.style.border = "1rem CadetBlue dotted";
}
function addText(){
this.appendChild(document.createTextNode("this is a text"));
}
function changeColor(){
this.style.color = "red";
}
function changeFontSize(){
this.style.fontSize = "1.5rem";
}
el.addEventListener("click", changeBgColor);
el.addEventListener("click", addBorder);
el.addEventListener("click", addText);
el.addEventListener("click", changeColor);
el.addEventListener("click", changeFontSize);
el.removeEventListener('click', changeColor);
el.removeEventListener('click', addBorder);
التمرين 20: ارجع إلى التمرين 19؛ أزل ربط changeFontSize معالجًا للحدث من العنصر.
let el = document.getElementById("box-3");
function changeBgColor(){
this.style.backgroundColor = "SpringGreen";
}
function addBorder(){
this.style.border = "1rem CadetBlue dotted";
}
function addText(){
this.appendChild(document.createTextNode("this is a text"));
}
function changeColor(){
this.style.color = "red";
}
function changeFontSize(){
this.style.fontSize = "1.5rem";
}
el.addEventListener("click", changeBgColor);
el.addEventListener("click", addBorder);
el.addEventListener("click", addText);
el.addEventListener("click", changeColor);
el.addEventListener("click", changeFontSize);
el.removeEventListener('click', changeColor);
el.removeEventListener('click', addBorder);
el.removeEventListener('click', changeFontSize);
انتشار الأحداث والتقاطها¶
التمرين 21: اختر box 1، واربط به دالة المعالجة التالية box1Clicked لحدث النقر.
function box1Clicked(){
console.log("Box 1 is clicked");
}
let box1 = document.getElementById("box-1");
box1.addEventListener('click', box1Clicked);
النتيجة هي: Box 1 is clicked
التمرين 22: ارجع إلى التمرين 21؛ اختر box 2، واربط به دالة المعالجة التالية addBox2Text لحدث النقر.
function box1Clicked(){
console.log("Box 1 is clicked");
}
let box1 = document.getElementById("box-1");
box1.addEventListener('click', box1Clicked);
function box2Clicked(){
console.log("Box 2 is clicked");
}
let box2 = document.getElementById("box-2");
box2.addEventListener('click', box2Clicked);
النتيجة كما يلي:
Box 2 is clicked
Box 1 is clicked
التمرين 23: ارجع إلى التمرين 22؛ اختر box 3، واربط به دالة المعالجة التالية addBox3Text لحدث النقر.
function box1Clicked(){
console.log("Box 1 is clicked");
}
let box1 = document.getElementById("box-1");
box1.addEventListener('click', box1Clicked);
function box2Clicked(){
console.log("Box 2 is clicked");
}
let box2 = document.getElementById("box-2");
box2.addEventListener('click', box2Clicked);
function box3Clicked(){
console.log("Box 3 is clicked");
}
let box3 = document.getElementById("box-3");
box3.addEventListener('click', box3Clicked);
النتيجة كما يلي:
Box 3 is clicked
Box 2 is clicked
Box 1 is clicked
التمرين 24: ارجع إلى التمرين 23؛ اختر box 4، واربط به دالة المعالجة التالية box4Clicked لحدث النقر.
function box1Clicked(){
console.log("Box 1 is clicked");
}
let box1 = document.getElementById("box-1");
box1.addEventListener('click', box1Clicked);
function box2Clicked(){
console.log("Box 2 is clicked");
}
let box2 = document.getElementById("box-2");
box2.addEventListener('click', box2Clicked);
function box3Clicked(){
console.log("Box 3 is clicked");
}
let box3 = document.getElementById("box-3");
box3.addEventListener('click', box3Clicked);
function box4Clicked(){
console.log("Box 4 is clicked");
}
let box4 = document.getElementById("box-4");
box4.addEventListener('click', box4Clicked);
النتيجة كما يلي:
Box 4 is clicked
Box 3 is clicked
Box 2 is clicked
Box 1 is clicked
ترتيب تنفيذ معالجات الأحداث
عندما تتداخل العناصر ولكل منها معالج للحدث، بأي ترتيب تُنفّذ؟ في مرحلة الانتشار يبدأ الحدث من الهدف الداخلي ثم يصعد إلى العناصر الآباء تباعًا. يُسمّى ذلك event bubbling.
إذا أردت تنفيذ المعالج في مرحلة الالتقاط من الخارج إلى الداخل، فأضف true على addEventListener. مثلًا: el.addEventListener(event, func, true).
التمرين 25: ارجع إلى التمرين 22؛ غيّر ترتيب التنفيذ ليكون من العنصر الخارجي إلى الداخلي.
function box1Clicked(){
console.log("Box 1 is clicked");
}
let box1 = document.getElementById("box-1");
box1.addEventListener('click', box1Clicked, true);
function box2Clicked(){
console.log("Box 2 is clicked");
}
let box2 = document.getElementById("box-2");
box2.addEventListener('click', box2Clicked, true);
النتيجة كما يلي:
Box 1 is clicked
Box 2 is clicked
التمرين 26: ارجع إلى التمرين 23؛ غيّر ترتيب التنفيذ ليكون من العنصر الخارجي إلى الداخلي.
function box1Clicked(){
console.log("Box 1 is clicked");
}
let box1 = document.getElementById("box-1");
box1.addEventListener('click', box1Clicked, true);
function box2Clicked(){
console.log("Box 2 is clicked");
}
let box2 = document.getElementById("box-2");
box2.addEventListener('click', box2Clicked, true);
function box3Clicked(){
console.log("Box 3 is clicked");
}
let box3 = document.getElementById("box-3");
box3.addEventListener('click', box3Clicked, true);
النتيجة كما يلي:
Box 1 is clicked
Box 2 is clicked
Box 3 is clicked
التمرين 27: ارجع إلى التمرين 24؛ غيّر ترتيب التنفيذ ليكون من العنصر الخارجي إلى الداخلي.
function box1Clicked(){
console.log("Box 1 is clicked");
}
let box1 = document.getElementById("box-1");
box1.addEventListener('click', box1Clicked, true);
function box2Clicked(){
console.log("Box 2 is clicked");
}
let box2 = document.getElementById("box-2");
box2.addEventListener('click', box2Clicked, true);
function box3Clicked(){
console.log("Box 3 is clicked");
}
let box3 = document.getElementById("box-3");
box3.addEventListener('click', box3Clicked, true);
function box4Clicked(){
console.log("Box 4 is clicked");
}
let box4 = document.getElementById("box-4");
box4.addEventListener('click', box4Clicked, true);
النتيجة كما يلي:
Box 1 is clicked
Box 2 is clicked
Box 3 is clicked
Box 4 is clicked