動態產生呼叫 modal


Posted by tzutzu858 on 2020-10-03

卡了一天多,但這樣下去會耽誤太多,所以先記錄一下趕快繼續往下走

需求:

在訂單頁面放了 Modal · Bootstrap ,想要在按商品刪除跳出這個 modal,按確定就是確定刪除這條商品,按取消則是不會刪除這條商品,但由於商品列是從首頁取資料再動態產生,所以 javascript 都是使用監聽事件,e.target 來抓

狀況一

如果整個 model 是放在 forEach 裡面,並且 target 是跳出 model 的確認鍵

if (target.classList.contains('btn-primary'))
我把它放在跟刪除同一層
cart.jsp 檔案

 <div class="goods">
            <c:forEach var="row" items="${cart}">
                <div class="row order_list">
                    <div class="col-5 center-vertical justify-content-start">
                        <img class="order_goods_img" src="/img/${row.goodsimg}"/>
                        <p class="order_goods_name">${row.goodsname}</p>
                    </div>
                    <div class="col center-vertical">
                        <span id="price_${row.goodsid}">${row.price}</span>
                    </div>
                    <div class="col center-vertical">
                        <div class="center-vertical amount">
                            <button class="amount_btn minus_btn" type="button">-</button>
                            <div class="order_amount" name="quantity_${row.goodsid}"
                                 onblur="calc(${row.goodsid}, this)">${row.quantity}</div>
                            <button class="amount_btn add_btn" type="button">+</button>
                        </div>
                    </div>
                    <div class="col center-vertical">
                        <span class="order_price_total" id="subtotal_${row.goodsid}">${row.price * row.quantity}</span>
                    </div>
                    <div class="col center-vertical">
                        <button class="del_btn" type="button" data-toggle="modal" data-target="#staticBackdrop">刪除
                        </button>
                        <!-- 跳出刪除 alert -->
                        <div class="modal fade" id="staticBackdrop" data-backdrop="static" data-keyboard="false" tabindex="-1"
                             aria-labelledby="staticBackdropLabel" aria-hidden="true">
                            <div class="modal-dialog">
                                <div class="modal-content">
                                    <div class="modal-header">
                                        <h5 class="modal-title" id="staticBackdropLabel">確定刪除 ? </h5>
                                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                                            <span aria-hidden="true">&times;</span>
                                        </button>
                                    </div>
                                    <div class="modal-body">
                                        確定要將此商品刪除 ?
                                    </div>
                                    <div class="modal-footer">
                                        <button type="button" id="cel" class="btn btn-secondary" data-dismiss="modal">取消</button>
                                        <button type="button" id="delDetermine" class="btn btn-primary" data-dismiss="modal">確定刪除</button>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </c:forEach>

        </div>

order.js 檔案

document.querySelector('.container').addEventListener('click', (e) => {
    const {target} = e;
    total = document.getElementById("total").innerText;

    /*  -----------------刪除商品項目-----------------------*/
    if (target.classList.contains('btn-primary')) {
        const totalDel = target.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.children[3].children[0].innerText
        console.log(totalDel)
        document.getElementById('total').innerText = parseInt(total) - parseInt(totalDel);
        target.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.remove();
    }

    /*  -----------------改變商品數量-----------------------*/
    if (target.classList.contains('add_btn')) {
        var count = target.parentNode.children[1].innerText;
        var price = target.parentNode.parentNode.parentNode.children[1].innerText;
        target.parentNode.children[1].innerText = ++count;
        var subtotle1 = target.parentNode.children[1].innerText
        target.parentNode.parentNode.parentNode.children[3].children[0].innerText = subtotle1 * price;
        total = parseInt(total) + parseInt(price);
        document.getElementById('total').innerText = total;
    }

    if (target.classList.contains('minus_btn')) {
        var count = target.parentNode.children[1].innerText;
        var price = target.parentNode.parentNode.parentNode.children[1].innerText;

        if (count > 0) {
            target.parentNode.children[1].innerText = --count;
            var subtotle1 = target.parentNode.children[1].innerText;
            target.parentNode.parentNode.parentNode.children[3].children[0].innerText = subtotle1 * price;
            total = parseInt(total) - parseInt(price);
            document.getElementById('total').innerText = total;

        }
    }
});


不管按哪一條商品的刪除,都只會刪除第一項商品列
也沒辦法這樣寫

if (target.classList.contains('del_btn')) {
        const totalDel = target.parentNode.parentNode.children[3].children[0].innerText
        if (target.classList.contains('btn-primary')) {
            document.getElementById('total').innerText = parseInt(total) - parseInt(totalDel);
            target.parentNode.parentNode.remove();
        }
    }

因為當按下 del_btn ,自然是不會同時按下 btn-primary ,所以裡面的 if 判斷都是 false ,因此無法執行裡面的程式

狀況二

在('btn-primary') 再多設監聽,並且整個 model 是放在 forEach 外面

不過 model 是放在 forEach 外或內好像影響不大
cart.jsp 檔案

<form action="controller" method="post">
    <!-- 跳出結帳 alert -->
    <div class="modal fade" id="checkAccounts" data-backdrop="static" data-keyboard="false" tabindex="-1"
         aria-labelledby="staticBackdropLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="staticBackdropLabel">結帳</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    確定將訂單結帳 ?
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
                    <button type="button" class="btn btn-primary delCommodity">確定</button>
                </div>
            </div>
        </div>
    </div>

    <div class="container">
        <div class="row order_list center-vertical">

            <div class="col-5 justify-content-start">
                商品
            </div>
            <div class="col center-vertical">
                單價
            </div>
            <div class="col center-vertical">
                數量
            </div>
            <div class="col center-vertical">
                總計
            </div>
            <div class="col center-vertical">
                操作
            </div>
        </div>
        <div class="goods">
            <c:forEach var="row" items="${cart}">
                <div class="row order_list">
                    <div class="col-5 center-vertical justify-content-start">
                        <img class="order_goods_img" src="/img/${row.goodsimg}"/>
                        <p class="order_goods_name">${row.goodsname}</p>
                    </div>
                    <div class="col center-vertical">
                        <span id="price_${row.goodsid}">${row.price}</span>
                    </div>
                    <div class="col center-vertical">
                        <div class="center-vertical amount">
                            <button class="amount_btn minus_btn" type="button">-</button>
                            <div class="order_amount" name="quantity_${row.goodsid}"
                                 onblur="calc(${row.goodsid}, this)">${row.quantity}</div>
                            <button class="amount_btn add_btn" type="button">+</button>
                        </div>
                    </div>
                    <div class="col center-vertical">
                        <span class="order_price_total" id="subtotal_${row.goodsid}">${row.price * row.quantity}</span>
                    </div>
                    <div class="col center-vertical">
                        <button class="del_btn" type="button" data-toggle="modal" data-target="#staticBackdrop">刪除
                        </button>
                        <!-- 跳出刪除 alert -->
                        <div class="modal fade" id="staticBackdrop" data-backdrop="static" data-keyboard="false"
                             tabindex="-1"
                             aria-labelledby="staticBackdropLabel" aria-hidden="true">
                            <div class="modal-dialog">
                                <div class="modal-content">
                                    <div class="modal-header">
                                        <h5 class="modal-title" id="staticBackdropLabel">確定刪除 ? </h5>
                                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                                            <span aria-hidden="true">&times;</span>
                                        </button>
                                    </div>
                                    <div class="modal-body">
                                        確定要將此商品刪除 ?
                                    </div>
                                    <div class="modal-footer">
                                        <button type="button" id="cel" class="btn btn-secondary" data-dismiss="modal">
                                            取消
                                        </button>
                                        <button type="button" id="delDetermine" class="btn btn-primary"
                                                data-dismiss="modal">確定刪除
                                        </button>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </c:forEach>

        </div>
    </div>
    <footer class="footer_block">
        <div class="settle_accounts_block">

            <div class="sub_total">
                <div>商品總金額</div>
                <span class="total_price" id="total">${total}</span>
                <input class="settle_accounts_btn" type="button" value="結帳" data-toggle="modal"
                       data-target="#checkAccounts">
            </div>
        </div>

    </footer>

</form>

order.js 檔案

document.querySelector('.container').addEventListener('click', (e) => {
    const {target} = e;
    total = document.getElementById("total").innerText;

    /*  -----------------刪除商品項目-----------------------*/
    if (target.classList.contains('del_btn')) {
        const totalDel = target.parentNode.parentNode.children[3].children[0].innerText

        document.querySelector('#delDetermine').addEventListener('click', (e) => {
            document.getElementById('total').innerText = parseInt(total) - parseInt(totalDel);
            target.parentNode.parentNode.remove();
            console.log(target.parentNode.parentNode)
        });
    }
    ......後面不貼了

按確認都是沒問題的,因為總金額重新計算,節點也刪除
但問題在於,如果按了取消,當下的確就取消沒再動作,但當我按了其他商品列的刪除+確認,會連帶之前取消的商品也一併跟著刪除,所以也就是只要我按了刪除鍵,target 都是被記錄下來,

原先三項商品,按了三次取消鍵
第四次按另外一項商品的刪除確認鍵

原本預計是跑一次 console.log(target.parentNode.parentNode)
Orz


阻止事件傳遞

如果加上 e.stopImmediatePropagation() 連帶 Modal · Bootstrap 都會被擋掉一些,但的確監聽只剩一次,後面不會繼續聽下去,但是他先執行刪除的也是第一個 target (也就是剛剛按取消的那個),而我要的卻是最後面的 target

e.stopPropagation() 沒用,因為都是同一層,事件還是會被執行。


原本想說既然都會被記錄下來,那我選擇最後一次 target 做刪除,前面有多少個就不管她,結果不知道記錄在那邊,也不是 event 的父節點,所以沒辦法用索引子來選取

也想過點完後就移除監聽事件,也是失敗

document.querySelector('.del_btn').removeEventListener('onmouseup', (e) => {
    console.log('ok')
});









Related Posts

F2E合作社|按鈕元件|Bootstrap 5網頁框架開發入門

F2E合作社|按鈕元件|Bootstrap 5網頁框架開發入門

Inside look at modern web browser

Inside look at modern web browser

用 Nest.js 開發 API 吧 (七) - Entity

用 Nest.js 開發 API 吧 (七) - Entity


Comments