تفاوت event bubling و event capturing

تفاوت event bubling  و event capturing

در این مقاله کوتاه قصد داریم تفاوت event bubling و event capturing را در مبحث جاوا اسکریپت با ذکر یک مثال مورد بررسی قرار دهیم.

برای درک این مفهوم باید ابتدا بدانیم که در حال یادگیری مبحث propagation در جاوااسکریپت هستیم.

فرض کنید یک المان بعنوان parent داریم که درون خود المانی دیگر بعنوان child دارد. این را هم در نظر بگیرید که روی والد و فرزند هر کدام جداگانه به تابع ست شده است.

در حالت عادی وقتی روی المان فرزند کلیک کنیم، ابتدا فانکشن مربوط به فرزند فراخوانی شده و سپس فانکشن مربوط به والد فراخوانی میشود. به این ساختار event bubling گفته میشود که بصورت دیفالت فعال است.

اما اگر المان سوم در addEventListener را از false به true تغییر دهید، به حالت event Capturing خواهیم رسید.

یعنی ابتدا فانکشن والد و سپس فانکشن فرزند فراخوانی میشود.

مانند کد زیر:


<div id="parent" class="col-4 border bg-primary" style="height: 500px">
    <div id="child" class="col-4 bg-dark" style="height: 200px"></div>
</div>

<script>
    document.getElementById('parent').addEventListener('click', function () {
        alert('parent clicked!')
    }, true)
    document.getElementById('child').addEventListener('click', function () {
        alert('child clicked!')
    }, true)
</script>

اما یک حالت بسیار کاربردی بنام stopPropagation و یا cancleBuble وجود دارد که اگر به event هر کدام از children ها اختصاص پیدا کند، میتواند این زنجیره را پاره کرده و دیگر اجازه فراخوانی فانکشن های والد خود را ندهد.

مانند کد زیر:


<body>
    <div id="parent" class="col-4 border bg-primary" style="height: 500px">
        <div id="child" class="col-4 bg-dark" style="height: 200px"></div>
    </div>

    <script>
        document.getElementById('parent').addEventListener('click', function () {
            alert('parent clicked!')
        }, false)
        document.getElementById('child').addEventListener('click', function (event) {
            alert('child clicked!')
            // event.stopImmediatePropagation()
            // event.stopPropagation()
            event.cancelBubble = true
        }, false)
    </script>
    

در انتهای این مقاله کوتاه تفاوت event bubling و event capturing یک مثال عملی از موضوع stopPropagation آورده شده است.

در این مثال به ازای هر کلیک بروی LI یک SPAN در داخل آن ایجاد میکنیم و بعد از کلیک روی خود SPAN میخواهیم فقط خودش حذف شود و تاثیری بروی والد خود نداشته باشد.

همانطور که در د زیر میبینید، با استفاده از stopPropagation توانستیم زنجیره و توالی انجام فانکشن والد را قطع کرده و از ایجاد بینهایت Span جلوگیری کنیم.

<body>
    <ul>
        <li data-status="off">menu</li>
        <li data-status="off">menu</li>
        <li data-status="off">menu</li>
        <li data-status="off">menu</li>
        <li data-status="off">menu</li>
    </ul>
</body>

<script>
    let _li = document.querySelectorAll('ul>li')
    _li.forEach((val) => {
        val.addEventListener('click', () => {
            if (val.getAttribute('data-status') == 'off') {
                val.innerHTML = val.innerHTML + '<span onclick="del(this, event)"> *delete</span>'
                val.setAttribute('data-status', 'on')
            }
        })
    })
    function del(x, e) {
        // console.log(x)
        e.stopPropagation()
        x.parentElement.setAttribute('data-status', 'off')
        x.style.color='red'
        x.remove()
    }
</script>

امیدواریم از این مقاله نهایت استفاده را برده باشید و آن را با دوستانتان به اشتراک بگذارید. تیم تولید محتوای مدرسه اینترنتی پرنیان این مقاله را تهیه کرده است.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *