About Java Script's DOM operation classList.toggle() in vue.js switching use and unswitchable problems, and its thinking and solutions

Table of contents

The first big problem (ordering of CSS inline style sheets)

The second big problem (separating the display property):

All complete exercise source code is as follows


A little experience of personal practice, the switching of classList.toggle() in vue.js and the order of CSS style inline tables

First, let me explain the topic of a small exercise in school:

This requires a little DOM knowledge and knowledge of JS and Vue for beginners to understand

<!--

practise:

① There is a shopping cart function, which needs to calculate the quantity and total price of the goods in real time and display them on the page. Please complete the following tasks:

②Create a Vue component that contains a list of products, each product contains information such as name, quantity, price, and an area that displays the quantity and total price of the product.

③ Use the computed attribute to calculate the quantity and total price of the product and display it on the page.

④Use watch to monitor changes in product quantity and price, and update product quantity and total price when changes occur.

⑤ Realize the function of adding and deleting commodities, including modifying the quantity and price, and automatically calculating the quantity and total price of commodities after updating the commodity information.

⑥ Add a watch listener in the created life cycle hook function of the component, and cancel the listener in the beforeUnmount life cycle hook function

-->

The classList.toggle() attribute to be used is to solve the function of "adding products". What I want to achieve is to click a button in an interface and switch the display style in css to realize a Added the appearance and disappearance of the form of the product.

First define an array in js to store the product information that needs to be added

Then define a method addPageDisplay() in methods to control the appearance of added information

and another method addComdy() to submit information

<script type="module">

        let id='2500100';//id作用起始id,通过自增来依次赋值
    
        const shopping=Vue.createApp({
            data(){
                return{
                    //定义一个新的对象模板来依次赋值
                    addNew_arr: {comdy_id:'',comdy_name:'',comdy_number:'',comdy_price:'',comdy_decr:''}

                }
            } ,
            methods :{
            addPageDisplay(){},
            addComdy(){}      

            }

      
        });
    
        shopping.mount('#shopping')

    </script>

Then you need to define a <div> in the body

    <div id="shopping">
        <button type="button"  @click="addPageDisplay">添加商品</button>
        <div class="submitForm" >
            <form action="">
                    <table>
                    <!--通过直接读取数组里的comdy_name属性,再通过v-model来动态绑定数组里的信息-->
                        <tr>商品名称: <input type="text" v-model="addNew_arr.comdy_name"></tr>
                        <tr>商品数量: <input type="text" v-model="addNew_arr.comdy_number"></tr>
                        <tr>商品价格: <input type="text" v-model="addNew_arr.comdy_price"></tr>
                        <tr>商品描述: <input type="text" v-model="addNew_arr.comdy_decr"></tr>
                        <tr><button type="button"  @click="addComdy">提交</button></tr>  
                    </table>                                          
                
            </form>
        </div>        
    </div>

At this time, we need to define css styles, one of which is submiForm, and the other is hidden.

When we click the "Add Product" button, the style of submiForm will be switched to the hidden style, and the css format is:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>测试toggle的问题</title>
    <script src="cdn.staticfile.org_vue_3.0.5_vue.global.js"></script>
    <style>
         
        .block{
           display: block; /*设置为显示*/
        }
        
        
         .submitForm{ 
            display:none;     /*设置隐藏其显示*/               
            top: 10px;
            width: 60%;
            height: 60%;
            justify-content: center;
            align-items: center;
        }

    </style>
</head>

 Pay attention to the above order, where the .hidden style is set as the first item, and .submitForm is the second item, because html is deconstructed sequentially, and the files will be read from top to bottom

At this time, you only need to set and click the "method of adding products" to change the display property of .submitForm from display: none to display: block. Therefore:

addPageDisplay(){
                    //通过DOM的document.querySelector找寻上下文里所有的名为'.submitForm'的类,被将其赋值给新定义的常量const submitForm
                    const submitForm = document.querySelector('.submitForm');            
                    //随后通过调用DOM里的classList属性里的toggle方法,实现属性的切换
                    //如果属性存在,则删除原本的属性,如果属性不存在,则添加属性
                    //即,原先submitForm中存在display:none的属性
                        submitForm.classList.toggle('block');              
    
                },

Method application of classList

The first big problem (ordering of CSS inline style sheets)

Then the first question comes. After implementing the above method, can the form be displayed and hidden through the "Add Product" button of the button?

The answer is wrong, and it cannot be achieved, because the order of CSS inline style sheets was reversed when it was first defined.

 When it is deconstructed, the html file will first read the first .block and then the second .submitForm

That is to say, the later ones will overwrite the previous ones, the css of the second item will overwrite the css of the first item, and the priority of the second item is higher than that of the first item

In other words, the priority of the display of the second item will override the first item

At this time, we need to adjust the first item to the second item, and the second item to the first item, so that the priority of .submitForm is higher than that of .block. At this time, we can use the "add button to switch"

Right now:

After adjusting the position, it can be realized

The second big problem (separating the display property):

Although the first problem is solved, the second problem is that I want to trigger the click event to close the form at the moment the action of submitting the form is completed, so that the display: block of the form changes again because of the first step. Return display: none to hide the table again. But if you use the method in the first time again, you will find that because the priority of .block is higher than that of .submitForm at this time, if you switch again at this time, you will not be able to switch back.

Corresponding to the following submit operation

So the directive is needed, but can no longer be read back to the original style because of priority issues


                    const submitForm = document.querySelector('.submitForm');            

                        submitForm.classList.toggle('submitForm');              
                      //无法再重新读取回原来的样式

So at this time, you need to define another class style, which is specially used for hiding, which is .hidden

But even so, the purpose cannot be achieved, because the priority of .hidden is still lower than that of .block, which is equivalent to taking display: none from .submitForm separately.

So a double switch is required at this point:

First of all, we need to add the separated display:none attribute back to the class in the div, so that <div> has two attributes at the same time

Right now:

<div id="shopping">
        <button type="button"  @click="addPageDisplay">添加商品</button>
        <!--注意这里的class里多了个hidden-->
        <div class="submitForm hidden" >
            <form action="">
                    <table>
                        <tr>商品名称: <input type="text" v-model="addNew_arr.comdy_name"></tr>
                        <tr>商品数量: <input type="text" v-model="addNew_arr.comdy_number"></tr>
                        <tr>商品价格: <input type="text" v-model="addNew_arr.comdy_price"></tr>
                        <tr>商品描述: <input type="text" v-model="addNew_arr.comdy_decr"></tr>
                        <tr><button type="button"  @click="addComdy">提交</button></tr>  
                    </table>                                          
                
            </form>
        </div>        
    </div>

**At the same time, note that if multiple class names are defined in a class, there will be no priority conflicts. They all act on the same div at the same time, so whether it is named class="submitForm hidden" or named class=" hidden submitForm" will not be affected, and the order of naming will not affect its priority, but the order of CSS inline style sheets will still be affected, just like before, although the class here is not affected by the order of naming, but if in the style If submitForm is in front of hidden in the table, then submitForm will overwrite the same attribute in hidden, and vice versa**

At the same time, you need to change the code in the original methods method:

The following events happen when we first click:

addPageDisplay(){
                    //第一次点击时:第一步通过DOM的querySelector获取对应的类,如果是id的话就用getElementById,效果一样的
                    const submitForm = document.querySelector('.submitForm');              
                    //第一次点击时:第二步,通过toggle切换css样式,根据原则“如果有则删除,如果没有则添加,如果不一样则修改”,原先的submitForm里有hidden的display:none,所以这里就先删除了submitForm里的display属性
                        submitForm.classList.toggle('hidden'); 
                    //第一次点击时:第三步,因为.block的优先级最大,且第二步的时候删除了display:none属性,所以第三步就会往原本的.submitForm里添加display:block属性,就会从隐藏变为显示了
                        submitForm.classList.toggle('block');              
    
                },

 Then when we click a second time the following event happens:

addPageDisplay(){
                    //第一次点击时:第一步通过DOM的querySelector获取对应的类,如果是id的话就用getElementById,效果一样的

                    //当第二次点击时,同样第一步先获取DOM对象
                    const submitForm = document.querySelector('.submitForm');              
                    //第一次点击时:第二步,通过toggle切换css样式,根据原则“如果有则删除,如果没有则添加,如果不一样则修改”,原先的submitForm里有hidden的display:none,所以这里就先删除了submitForm里的display属性

                    //当第二次点击时:因为第一次点击时最后一步的残留影响,效果为.block的display:block,所以此时如果要切换为hidden的话,根据内联样式表的顺序,.hidden的优先级小于.block,所以会添加上hidden但不能覆盖.blcok
                        submitForm.classList.toggle('hidden'); 

                    //第一次点击时:第三步,因为.block的优先级最大,且第二步的时候删除了display:none属性,所以第三步就会往原本的.submitForm里添加display:block属性,就会从隐藏变为显示了

                    //当第二次点击时:因为CSS样式为display:block,还是原本的样式,根据原则“如果有则删除,如果没有则添加,如果不一样则修改”,会删除掉.block的样式,只会留下.submitForm和.hidden的,所以这时候又会被隐藏起来了
                        submitForm.classList.toggle('block');              
    
                },
    
                addComdy(){
                    this.addNew_arr.comdy_id=id++;
                    const submitForm = document.querySelector('.submitForm')  ;             
                    submitForm.classList.toggle('block');
                    submitForm.classList.toggle('hidden');
                    this.addNew_arr={comdy_id:id++,comdy_name:'',comdy_number:'',comdy_price:'',comdy_decr:''}
                    alert('提交成功!');
                } 

 Accordingly, the personal analysis is completed. There is a method of addComdy in it, without comments, you can analyze it for yourself, like an exercise~

All complete exercise source code is as follows

Those who are interested can take a look at:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>测试toggle的问题</title>
    <script src="cdn.staticfile.org_vue_3.0.5_vue.global.js"></script>
    <style>

        .submitForm{  
           /*
                display:none  ?
                display:block ?
            */            
            top: 10px;
            width: 60%;
            height: 60%;
            justify-content: center;
            align-items: center;
        }

        
        .hidden{
           display: none;
        }

        .block{
            display: block;
        }
        
        

    </style>
</head>
<body>

    <div id="shopping">
        <button type="button"  @click="addPageDisplay">添加商品</button>
        <div class="submitForm hidden" >
            <form action="">
                    <table>
                        <tr>商品名称: <input type="text" v-model="addNew_arr.comdy_name"></tr>
                        <tr>商品数量: <input type="text" v-model="addNew_arr.comdy_number"></tr>
                        <tr>商品价格: <input type="text" v-model="addNew_arr.comdy_price"></tr>
                        <tr>商品描述: <input type="text" v-model="addNew_arr.comdy_decr"></tr>
                        <tr><button type="button"  @click="addComdy">提交</button></tr>  
                    </table>                                          
                
            </form>
        </div>        
    </div>

    <script type="module">

        let id='2500100';
    
    
        const shopping=Vue.createApp({
            data(){
                return{
                    
                    addNew_arr: {comdy_id:'',comdy_name:'',comdy_number:'',comdy_price:'',comdy_decr:''},
 
                }
            },   
    
            methods:{   
                addPageDisplay(){
                    //第一次点击时:第一步通过DOM的querySelector获取对应的类,如果是id的话就用getElementById,效果一样的

                    //当第二次点击时,同样第一步先获取DOM对象
                    const submitForm = document.querySelector('.submitForm');              
                    //第一次点击时:第二步,通过toggle切换css样式,根据原则“如果有则删除,如果没有则添加,如果不一样则修改”,原先的submitForm里有hidden的display:none,所以这里就先删除了submitForm里的display属性

                    //当第二次点击时:因为第一次点击时最后一步的残留影响,效果为.block的display:block,所以此时如果要切换为hidden的话,根据内联样式表的顺序,.hidden的优先级小于.block,所以会添加上hidden但不能覆盖.blcok
                        submitForm.classList.toggle('hidden'); 

                    //第一次点击时:第三步,因为.block的优先级最大,且第二步的时候删除了display:none属性,所以第三步就会往原本的.submitForm里添加display:block属性,就会从隐藏变为显示了

                    //当第二次点击时:因为CSS样式为display:block,还是原本的样式,根据原则“如果有则删除,如果没有则添加,如果不一样则修改”,会删除掉.block的样式,只会留下.submitForm和.hidden的,所以这时候又会被隐藏起来了
                        submitForm.classList.toggle('block');              
    
                },
    
                addComdy(){
                    this.addNew_arr.comdy_id=id++;
                    const submitForm = document.querySelector('.submitForm')  ;             
                    submitForm.classList.toggle('block');
                    submitForm.classList.toggle('hidden');
                    this.addNew_arr={comdy_id:id++,comdy_name:'',comdy_number:'',comdy_price:'',comdy_decr:''}
                    alert('提交成功!');
                }  
            }   
        });
    
        shopping.mount('#shopping')

    </script>


<!-- 
    结论:submitForm作为主类的话,其中的display会被覆盖,为最高优先级,无法被toggle通过其它类去改变修改,解决方法只能定义两个类
    用其他类作为辅助属性,并在style中设定顺序,其顺序决定了它们的优先级问题
 -->
    
</body>
</html>

Test toggle's question

Guess you like

Origin blog.csdn.net/m0_72159389/article/details/130657647
Recommended