第九周第三天筆記

事件

1 事件流

  • 冒泡:從該元素開始由里向外觸發(fā)一類事件揉忘,事件對(duì)象中的事件源為該元素,觸發(fā)同一類事件翅楼,在子級(jí)父級(jí)祖級(jí)中拿到的事件源一樣乎赴,均為被觸發(fā)元素忍法;

    • 阻止冒泡:e.stopPropagation?e.stopPropagation():e.cancelBubble=true;
    • 關(guān)于冒泡的運(yùn)用:典型的是事件委托
      • 事件委托:將事件添加到最高級(jí)元素上,事件中獲取事件源的屬性榕吼,當(dāng)觸發(fā)某元素上的事件時(shí)饿序,就會(huì)在最高級(jí)中獲取事件源,也就是該元素羹蚣;
    • 實(shí)例1:在多層嵌套的div中原探,點(diǎn)擊哪個(gè)元素,就彈出哪個(gè)元素的class名顽素;
      • 方法:
        • 1)遍歷div咽弦,給每個(gè)元素添加點(diǎn)擊事件,然后彈出class名戈抄,但是會(huì)出現(xiàn)冒泡事件,所以必須阻止冒泡事件
        • 2)事件委托
       <!DOCTYPE html>
       <html lang="en">
       <head>
           <meta charset="UTF-8">
           <title>冒泡與阻止冒泡</title>
           <style>
               div{
                   padding: 100px;
                   font-size: 50px;
               }
               .div1{
                   background-color: red;
               }
               .div2{
                   background-color: blue;
               }
               .div3{
                   background-color: green;
               }
           </style>
       </head>
       <body>
       <div class="div1">div1
           <div class="div2">div2
               <div class="div3">div3</div>
           </div>
       </div>
       <script>
           //需求:點(diǎn)擊誰后专,彈出誰的class名
           var oDiv1=document.getElementsByTagName("div")[0];
           var aDiv=document.getElementsByTagName("div");
           //第一種方法:遍歷div划鸽,給每個(gè)元素添加點(diǎn)擊事件,然后彈出class名戚哎,要阻止冒泡事件
           for(var i=0; i<aDiv.length; i++){
               aDiv[i].onclick=function (e) {
                   alert(this.className);
                   //會(huì)存在冒泡事件裸诽,所以要阻止冒泡
                   e.stopPropagation? e.stopPropagation():e.cancelBubble=true;
               }
           }
           //第二種方法:事件委托,委托給最高級(jí)型凳,通過事件源獲取
           //由于事件存在冒泡特性丈冬,所以在觸發(fā)某元素的事件時(shí),同時(shí)會(huì)觸發(fā)其父級(jí)和祖級(jí)的該類事件甘畅,都傳入同一個(gè)事件對(duì)象埂蕊,里面的事件源都是觸發(fā)的某元素,所以只要在最高級(jí)上添加點(diǎn)擊事件疏唾,里面獲取事件源的class名即可
           oDiv1.onclick=function (e) {
               e=e||window.event;
               e.target=e.target||e.srcElement;
               alert(e.target.className);
           }
       </script>
       </body>
       </html>
      
    • 實(shí)例2:在body元素中有多個(gè)div元素蓄氧,在點(diǎn)擊里面的a鏈接后,就刪除該a元素的父級(jí)div槐脏;
      • 方法:事件委托給最高級(jí)body元素喉童,給body添加點(diǎn)擊事件,然后在事件匿名函數(shù)中獲取事件源顿天,然后刪除事件源的父級(jí)div;
       <!DOCTYPE html>
       <html lang="en">
       <head>
           <meta charset="UTF-8">
           <title>事件委托</title>
           <style>
               div{
                   width: 100px;
                   height: 100px;
                   background-color: lightseagreen;
                   float: left;
                   margin: 5px;
               }
               div a{
                   color: red;
                   text-decoration: none;
                   font-weight: bold;
               }
           </style>
       </head>
       <body>
       <!--<div>
           <a href="javascript:void(0);">點(diǎn)吧</a>
       </div>-->
       <script>
           for(var i=0; i<20; i++){
               var odiv=document.createElement("div");
               odiv.innerHTML=`<a href="javascript:void(0);">${i}點(diǎn)吧</a>`;
               document.body.appendChild(odiv);
           }
           //事件委托堂氯,給最高級(jí)元素添加事件
           //當(dāng)點(diǎn)擊a標(biāo)簽時(shí)蔑担,就會(huì)觸發(fā)a的點(diǎn)擊事件,同時(shí)由里向外觸發(fā)父級(jí)div和祖級(jí)body的點(diǎn)擊事件咽白,然后每個(gè)事件中拿到的事件對(duì)象上的target屬性值都是a元素啤握,即事件源都是a元素;
           //通過判斷事件源來決定刪除哪個(gè)a元素的父級(jí)局扶;
           document.body.onclick=function (e) {
               e=e||window.event;
               e.target=e.target || e.srcElement;
               if(e.target.tagName.toLowerCase()==="a"){
                   this.removeChild(e.target.parentNode);
               }
           }
       </script>
       </body>
       </html>
      
    • 注:某個(gè)元素事件發(fā)生恨统,不用給其添加代碼,只要在它身上觸發(fā)該事件就行三妈,添加代碼畜埋,只不過給其設(shè)置一個(gè)能夠顯現(xiàn)出來的動(dòng)作而已,不添加畴蒲,也會(huì)觸發(fā)悠鞍;
  • onmouseenter、onmouseleave模燥、onmouseover咖祭、onmouseout四者關(guān)系解讀

    • 相同點(diǎn):都是添加鼠標(biāo)移入移出事件
    • 不同點(diǎn):onmouseover和onmouseout中會(huì)存在冒泡事件;onmouseenter和onmouseleave中不存在冒泡事件蔫骂;
    • 實(shí)例解讀:
      • 需求:當(dāng)鼠標(biāo)移動(dòng)到div元素身上時(shí)么翰,p元素顯示,顯示的時(shí)候辽旋,移動(dòng)到p元素身上浩嫌,仍然顯示,移動(dòng)到div和p元素之外的位置补胚,p元素再隱藏码耐;
      • 方法:
        • 使用onmouseenter與onmouseleave設(shè)置:當(dāng)光標(biāo)從div上移出到p元素上時(shí),沒有打印out,也沒有再次打印in,意思是兩個(gè)事件都沒有被觸發(fā)溶其,指的就是當(dāng)移動(dòng)到子級(jí)身上時(shí)骚腥,根本不算移出;所以給oDiv元素添加onmouseenter事件瓶逃,指的是當(dāng)光標(biāo)移入到它或者是它的子級(jí)束铭,都會(huì)觸發(fā)事件;不是冒泡事件厢绝,而是將oDiv和它的子級(jí)作為了一個(gè)整體纯露;
        • 使用onmouseover與onmouseout設(shè)置:使用onmouseover和onmouseout也會(huì)實(shí)現(xiàn)需求,但是實(shí)現(xiàn)的過程不同代芜,當(dāng)光標(biāo)移入div會(huì)觸發(fā)onmouseover事件埠褪,然后打印in,當(dāng)光標(biāo)從div元素上移出并立刻進(jìn)入p元素時(shí),此時(shí)發(fā)生了兩個(gè)過程钞速,移出div時(shí)贷掖,會(huì)觸發(fā)div的onmouseout事件,打印out渴语,并使p隱藏苹威;然后迅速進(jìn)入p元素,此時(shí)觸發(fā)p元素的onmouseover事件驾凶,但是沒有動(dòng)作牙甫,會(huì)通過冒泡事件,連帶父級(jí)div觸發(fā)onmouseover事件调违,所以再次打印in,然后p顯示窟哺;所以肉眼沒有發(fā)現(xiàn)p被隱藏,又被顯示技肩。當(dāng)移出p元素時(shí)也是通過冒泡事件且轨,將父級(jí)onmouseout事件觸發(fā),進(jìn)而打印out虚婿,使p隱藏旋奢;
       <!DOCTYPE html>
       <html lang="en">
       <head>
           <meta charset="UTF-8">
           <title>onmouseenter與onmouseleave解讀</title>
           <style>
               *{
                   margin: 0;
                   padding: 0;
               }
               .div1{
                   width: 200px;
                   height: 50px;
                   background-color: lightseagreen;
                   position: relative;
                   margin: 20px auto;
               }
               .div1 p{
                   width: 500px;
                   height: 300px;
                   position: absolute;
                   right: 0;
                   top: 50px;
                   background-color: lightpink;
                   display: none;
               }
           </style>
       </head>
       <body>
       <div class="div1">
           <p></p>
       </div>
       <script>
           //需求:當(dāng)鼠標(biāo)移動(dòng)到div元素身上時(shí),p元素顯示然痊,顯示的時(shí)候至朗,移動(dòng)到p元素身上,仍然顯示剧浸,移動(dòng)到div和p元素之外的位置锹引,p元素再隱藏;
           var oDiv=document.getElementsByTagName("div")[0];
           var oP=document.getElementsByTagName("p")[0];
           //1 使用onmouseenter與onmouseleave設(shè)置
           oDiv.onmouseenter=function () {
               console.log("in");
               oP.style.display="block";
           };
           oDiv.onmouseleave=function () {
               console.log("out");
               oP.style.display="none";
           };
           //當(dāng)光標(biāo)移入div辛蚊,再移入p粤蝎,再移出p真仲,整個(gè)過程中打印結(jié)果:in-out袋马;
           //2 使用onmouseover與onmouseout設(shè)置
           oDiv.onmouseover=function () {
               console.log("in");
               oP.style.display="block";
           };
           oDiv.onmouseout=function () {
               console.log("out");
               oP.style.display="none";
           }
           //當(dāng)光標(biāo)移入div,再移入p秸应,再移出p虑凛,整個(gè)過程中打印結(jié)果:in-out-in-out
       </script>
       </body>
       </html>
      
  • 冒泡的問題:給父級(jí)添加事件后,在子級(jí)上觸發(fā)软啼,還會(huì)觸發(fā)父級(jí)的事件桑谍,會(huì)重復(fù)觸發(fā),造成性能不好祸挪,還會(huì)造成代碼混亂锣披;

    • 解決方法:在子級(jí)中添加相同事件,并在事件中阻止冒泡;代碼:e.stopPropagation?e.stopPropagation():e.cancelBubble=true;雹仿;
    • 通過關(guān)聯(lián)元素獲取到子級(jí)增热,然后判斷阻止,此方法只能解決代碼混亂問題胧辽,不會(huì)進(jìn)行性能優(yōu)化峻仇,父級(jí)事件還會(huì)因子級(jí)事件觸發(fā)而觸發(fā),只不過是在父級(jí)事件中阻斷了一些代碼的執(zhí)行邑商,避免重復(fù)設(shè)置摄咆,造成混亂;
    • 在父級(jí)事件函數(shù)中人断,通過事件對(duì)象獲取事件源吭从,通過事件源來篩選觸發(fā)元素,不能阻止冒泡事件發(fā)生含鳞,但是可以阻止影锈,當(dāng)從子級(jí)觸發(fā)時(shí),不會(huì)再執(zhí)行父級(jí)函數(shù)體內(nèi)的代碼蝉绷;
  • 冒泡的問題及解決問題的實(shí)例:

    • 實(shí)例1:當(dāng)鼠標(biāo)滑到div上時(shí)鸭廷,新建一個(gè)p元素,讓其跟隨光標(biāo)移動(dòng)熔吗,當(dāng)光標(biāo)移出div后辆床,p元素消失;
      • 問題:當(dāng)鼠標(biāo)移動(dòng)到子級(jí)p身上的時(shí)候桅狠,會(huì)觸發(fā)鼠標(biāo)事件讼载,通過冒泡觸發(fā)父級(jí)身上的鼠標(biāo)事件,進(jìn)而再新建一個(gè)p元素中跌,進(jìn)而出錯(cuò)咨堤;
      • 解決方法:1)將子級(jí)p元素中的冒泡事件阻止,這樣父級(jí)就不會(huì)被關(guān)聯(lián)觸發(fā)漩符;2)利用對(duì)象事件上的屬性獲取添加事件元素的關(guān)聯(lián)元素博烂,判斷當(dāng)包含時(shí)号杠,則阻止程序執(zhí)行渊鞋,進(jìn)而不會(huì)被影響孵淘;3)利用onmouseenter和onmouseleave添加事件;
      • 注意:鼠標(biāo)移動(dòng)事件太靈敏闷沥,所以需要在定位數(shù)值設(shè)置時(shí)使光標(biāo)與定位元素有一段距離萎战;
      • 代碼:
       <!DOCTYPE html>
       <html lang="en">
       <head>
           <meta charset="UTF-8">
           <title>實(shí)例2</title>
           <style>
               *{
                   margin: 0;
                   padding: 0;
               }
               .div{
                   width: 500px;
                   height: 350px;
                   background-color: red;
                   margin: 20px auto;
                   position: relative;
               }
               .div p{
                   width: 50px;
                   height: 50px;
                   background-color: blue;
                   position: absolute;
               }
           </style>
       </head>
       <body>
       <div class="div"></div>
       <script>
           var oDiv=document.getElementsByTagName("div")[0];
           var oS=null;
           //方法1:將子級(jí)p元素中的冒泡事件阻止,這樣父級(jí)就不會(huì)被關(guān)聯(lián)觸發(fā)舆逃;
           oDiv.onmouseover=function () {
               oS=document.createElement("p");
               oS.onmouseover=function (e) {
                   //阻止冒泡事件
                   e=e||window.event;
                   e.stopPropagation? e.stopPropagation():e.cancelBubble=true;
               };
               this.appendChild(oS);
           };
           oDiv.onmousemove=function (e) {
               e=e||window.event;
               oS.style.left=e.clientX-this.offsetLeft-this.clientLeft+5+"px";
               oS.style.top=e.clientY-this.offsetTop-this.clientTop+5+"px";
           };
           oDiv.onmouseout=function () {
               oS.onmouseout=function (e) {
                   //阻止冒泡事件
                   e=e||window.event;
                   e.stopPropagation? e.stopPropagation():e.cancelBubble=true;
               };
               this.removeChild(oS);
           }
           //方法2:利用對(duì)象事件上的屬性獲取添加事件元素的關(guān)聯(lián)元素蚂维,判斷當(dāng)包含時(shí)戳粒,則阻止程序執(zhí)行,進(jìn)而不會(huì)被影響虫啥;
          oDiv.onmouseover=function (e) {
               e=e||window.event;
               //關(guān)聯(lián)元素的獲取享郊,在事件對(duì)象上
               var oMo=e.fromElement || e.realtedTarget;
               //判斷是否包含關(guān)聯(lián)元素,包含則阻止程序執(zhí)行孝鹊;
               if(this.contains(oMo)) return;
               oS=document.createElement("p");
               this.appendChild(oS);
           };
           oDiv.onmousemove=function (e) {
               e=e||window.event;
               oS.style.left=e.clientX-this.offsetLeft-this.clientLeft+8+"px";
               oS.style.top=e.clientY-this.offsetTop-this.clientTop+8+"px";
           };
           oDiv.onmouseout=function (e) {
               e=e||window.event;
               var oMo=e.toElement || e.realtedTarget;
               if(this.contains(oMo)) return;
               this.removeChild(oS);
           }
           //方法3:使用onmouseenter和onmouseleave
           oDiv.onmouseenter=function () {
               oS=document.createElement("p");
               this.appendChild(oS);
           };
           oDiv.onmousemove=function (e) {
               e=e||window.event;
               oS.style.left=e.clientX-this.offsetLeft-this.clientLeft+10+"px";
               oS.style.top=e.clientY-this.offsetTop-this.clientTop+10+"px";
           };
           oDiv.onmouseleave=function () {
               this.removeChild(oS);
           }
       </script>
       </body>
       </html>
      
    • 實(shí)例2:當(dāng)鼠標(biāo)移動(dòng)到div元素身上時(shí)炊琉,p元素顯示,顯示的時(shí)候又活,移動(dòng)到p元素身上苔咪,仍然顯示,移動(dòng)到div和p元素之外的位置柳骄,p元素再隱藏团赏;
      • 問題:當(dāng)鼠標(biāo)移動(dòng)到子級(jí)p元素身上時(shí),會(huì)觸發(fā)p元素的鼠標(biāo)事件耐薯,進(jìn)而再次觸發(fā)父級(jí)div的鼠標(biāo)事件舔清,這樣就會(huì)重復(fù)觸發(fā),性能不好曲初,所以要阻止子級(jí)的冒泡事件
      • 解決方法:1)在子級(jí)中阻止冒泡事件体谒,但是需要在子級(jí)中添加顯示隱藏;2)通過對(duì)象事件獲取關(guān)聯(lián)元素臼婆;3)設(shè)置onmouseenter和onmouseleave事件抒痒,能夠解決性能問題,事件只觸發(fā)一次
      • 注意:關(guān)聯(lián)元素的方法可取颁褂,但是沒有解決性能問題故响,因?yàn)榛阶蛹?jí)上,還是會(huì)觸發(fā)父級(jí)的鼠標(biāo)事件颁独,沒有完成性能優(yōu)化彩届,此處要注意的是,顯示隱藏代碼一定要設(shè)置在判斷元素之后誓酒;在父級(jí)事件中代碼執(zhí)行前樟蠕,判斷關(guān)聯(lián)元素的目的:是阻止父級(jí)事件中代碼的執(zhí)行,不會(huì)阻止冒泡事件的發(fā)生丰捷;
      • 代碼:
       <!DOCTYPE html>
       <html lang="en">
       <head>
           <meta charset="UTF-8">
           <title>冒泡問題解讀</title>
           <style>
               *{
                   margin: 0;
                   padding: 0;
               }
               .div1{
                   width: 200px;
                   height: 50px;
                   background-color: lightseagreen;
                   position: relative;
                   margin: 20px auto;
               }
               .div1 p{
                   width: 500px;
                   height: 300px;
                   position: absolute;
                   right: 0;
                   top: 50px;
                   background-color: lightpink;
                   display: none;
               }
           </style>
       </head>
       <body>
       <div class="div1">
           <p></p>
       </div>
       <script>
           //需求:當(dāng)鼠標(biāo)移動(dòng)到div元素身上時(shí)坯墨,p元素顯示寂汇,顯示的時(shí)候病往,移動(dòng)到p元素身上,仍然顯示骄瓣,移動(dòng)到div和p元素之外的位置停巷,p元素再隱藏;
           //問題:當(dāng)鼠標(biāo)移動(dòng)到子級(jí)p元素身上時(shí),會(huì)觸發(fā)p元素的鼠標(biāo)事件畔勤,進(jìn)而再次觸發(fā)父級(jí)div的鼠標(biāo)事件蕾各,這樣就會(huì)重復(fù)觸發(fā),性能不好庆揪,所以要阻止子級(jí)的冒泡事件
           var oDiv=document.getElementsByTagName("div")[0];
           var oP=document.getElementsByTagName("p")[0];
           //方法1:在子級(jí)中阻止冒泡事件式曲,但是需要在子級(jí)中添加顯示隱藏;
           oDiv.onmouseover=function () {
               console.log("in");
               oP.style.display="block";
               oP.onmouseover=function (e) {
                   //阻止冒泡但是要重新設(shè)置顯示隱藏缸榛;
                   this.style.display="block";
                   e=e||window.event;
                   //阻止子級(jí)的冒泡事件
                   e.stopPropagation?e.stopPropagation():e.cancelBubble=true;
               }
           };
           oDiv.onmouseout=function () {
               console.log("out");
               oP.style.display="none";
               oP.onmouseout=function (e) {
                   this.style.display="none";
                   e=e||window.event;
                   e.stopPropagation?e.stopPropagation():e.cancelBubble=true;
               }
           }
           //方法2:通過對(duì)象事件獲取關(guān)聯(lián)元素
           //方法可取但是沒有解決性能問題吝羞,因?yàn)榛阶蛹?jí)上,還是會(huì)觸發(fā)父級(jí)的鼠標(biāo)事件内颗,沒有完成性能優(yōu)化钧排,此處要注意的是,顯示隱藏代碼一定要設(shè)置在判斷元素之后
           //在父級(jí)事件中代碼執(zhí)行前均澳,判斷關(guān)聯(lián)元素的目的:是阻止父級(jí)事件中代碼的執(zhí)行恨溜,不會(huì)阻止冒泡事件的發(fā)生;
           oDiv.onmouseover=function (e) {
               console.log("in");
               e= e||window.event;
               var oMo=e.fromElement || e.relatedTarget;
               if(this.contains(oMo)) return;
               console.log(2);
               oP.style.display="block";
           };
           oDiv.onmouseout=function (e) {
               console.log("out");
               e= e||window.event;
               var oMo=e.toElement || e.relatedTarget;
               if(this.contains(oMo)) return;
               console.log(1);
               oP.style.display="none";
           }
           //打印結(jié)果:從進(jìn)入div,在出來進(jìn)入p找前,然后再從p移出這個(gè)過程的打印結(jié)果為:in-2-out-in-out-1;
           //方法3:設(shè)置onmouseenter和onmouseleave事件糟袁,能夠解決性能問題,事件只觸發(fā)一次
           oDiv.onmouseenter=function () {
               console.log("in");
               oP.style.display="block";
           };
           oDiv.onmouseleave=function () {
               console.log("out");
               oP.style.display="none";
           }
       </script>
       </body>
       </html>
      
    • 實(shí)例3:當(dāng)鼠標(biāo)移上div元素身上時(shí)躺盛,p顯示系吭;移出div元素后,p隱藏颗品;強(qiáng)調(diào):移出到任何位置肯尺,p都隱藏,移動(dòng)p元素身上躯枢,也必須隱藏则吟;
      • 問題:當(dāng)鼠標(biāo)移動(dòng)到子級(jí)p元素身上時(shí),會(huì)觸發(fā)p元素的鼠標(biāo)事件锄蹂,進(jìn)而再次觸發(fā)父級(jí)div的鼠標(biāo)事件氓仲,這樣就會(huì)重復(fù)觸發(fā),性能不好得糜,同時(shí)當(dāng)鼠標(biāo)移動(dòng)到子級(jí)p元素身上的時(shí)候敬扛,子級(jí)不會(huì)隱藏,所以要阻止子級(jí)的冒泡事件朝抖;
      • 解決方法:1)在子級(jí)元素身上綁定同行為事件啥箭,然后在事件函數(shù)中阻止冒泡發(fā)生;2)在父級(jí)元素中治宣,通過事件對(duì)象獲取事件源急侥,然后判斷事件源的nodeName來獲取元素TagName名砌滞,判斷是否為父級(jí)元素標(biāo)簽,若不是坏怪,則阻止代碼執(zhí)行贝润;
      • 代碼:
       <!DOCTYPE html>
       <html lang="en">
       <head>
           <meta charset="UTF-8">
           <title>需求2</title>
           <style>
               *{
                   margin: 0;
                   padding: 0;
               }
               .div1{
                   width: 200px;
                   height: 50px;
                   background-color: lightseagreen;
                   position: relative;
                   margin: 20px auto;
               }
               .div1 p{
                   width: 500px;
                   height: 300px;
                   position: absolute;
                   right: 0;
                   top: 50px;
                   background-color: lightpink;
                   display: none;
               }
           </style>
       </head>
       <body>
       <div class="div1">
           <p></p>
       </div>
       <script>
           var oDiv=document.getElementsByTagName("div")[0];
           var oP=document.getElementsByTagName("p")[0];
           //方法1:在子級(jí)事件函數(shù)中阻止冒泡發(fā)生;
           oDiv.onmouseover=function () {
               console.log("in");
               oP.style.display="block";
               oP.onmouseover=function (e) {
                   e=e||window.event;
                   //阻止子級(jí)的冒泡事件
                   e.stopPropagation?e.stopPropagation():e.cancelBubble=true;
               }
           };
           oDiv.onmouseout=function () {
               console.log("out");
               oP.style.display="none";
               oP.onmouseout=function (e) {
                   e=e||window.event;
                   e.stopPropagation?e.stopPropagation():e.cancelBubble=true;
               }
           }铝宵;
           //方法2:在父級(jí)元素中判斷事件源
           oDiv.onmouseover=function(e){
               e=e || window;
               e.target=e.target || e.srcElement;
               if(e.target.nodeName.toLowerCase!=="div") return;
               oP.style.display="block";
            };
            oDiv.onmouseout=function(e){
               e=e || window;
               e.target=e.target || e.srcElement;
               if(e.target.nodeName.toLowerCase!=="div") return;
               oP.style.display="none";
            };
       </script>
       </body>
       </html>
      
  • 購物車點(diǎn)擊版實(shí)例

    • 需求:當(dāng)點(diǎn)擊div元素及p元素時(shí)打掘,p元素顯示,點(diǎn)擊除二者以外的任何區(qū)域都讓p隱藏
    • 思路:如果一個(gè)父級(jí)容器下添加多個(gè)事件鹏秋,那么就將事件委托給父級(jí)容器胧卤,通過判斷事件源來進(jìn)行相應(yīng)的操作;
    • 方法:1)通過開關(guān)思想拼岳,控制隱藏與顯示枝誊,但是會(huì)存在一個(gè)問題,在第二個(gè)判斷中如果不設(shè)置bOk=true惜纸,就會(huì)出現(xiàn)叶撒,第一次點(diǎn)擊div后,p顯示耐版,然后點(diǎn)擊外面祠够,p消失,但此時(shí)的bOk為false,再次點(diǎn)擊div時(shí)粪牲,會(huì)走else語句古瓤,不會(huì)顯示;所以必須設(shè)置bOk=true; 2)通過判斷p的行間樣式是否為block來控制顯示和隱藏腺阳;3)通過給父級(jí)容器添加點(diǎn)擊事件落君,然后通過事件對(duì)象來獲取事件源,判斷事件源的nodeName是否為div和p的tagName名亭引,若是二者之一绎速,則設(shè)置p為顯示,若都不是焙蚓,則設(shè)置p為隱藏纹冤;
    • 知識(shí)點(diǎn):事件委托的應(yīng)用環(huán)境及行間樣式的獲取
    • 代碼:
     <!DOCTYPE html>
     <html lang="en">
     <head>
         <meta charset="UTF-8">
         <title>購物車點(diǎn)擊版實(shí)例</title>
         <style>
             *{
                 margin: 0;
                 padding: 0;
             }
             html,body{
                 height: 100%;
             }
             .div1{
                 width: 200px;
                 height: 50px;
                 background-color: lightseagreen;
                 position: relative;
                 margin: 20px auto;
             }
             .div1 p{
                 width: 500px;
                 height: 300px;
                 position: absolute;
                 right: 0;
                 top: 50px;
                 background-color: lightpink;
                 display: none;
             }
         </style>
     </head>
     <body>
     <div class="div1">
         <p></p>
     </div>
     <script>
         //需求:當(dāng)點(diǎn)擊div元素及p元素時(shí),p元素顯示购公,點(diǎn)擊除二者以外的任何區(qū)域都讓p隱藏
         var oDiv=document.getElementsByTagName("div")[0];
         var oP=document.getElementsByTagName("p")[0];
         var bOk=true;
         //思路:如果一個(gè)父級(jí)容器下添加多個(gè)事件萌京,那么就將事件委托給父級(jí)容器,通過判斷事件源來進(jìn)行相應(yīng)的操作宏浩;
         //方法1:通過開關(guān)思想知残,控制隱藏與顯示,但是會(huì)存在一個(gè)問題绘闷,在第二個(gè)判斷中如果不設(shè)置bOk=true橡庞,就會(huì)出現(xiàn),第一次點(diǎn)擊div后印蔗,p顯示扒最,然后點(diǎn)擊外面,p消失华嘹,但此時(shí)的bOk為false,再次點(diǎn)擊div時(shí)吧趣,會(huì)走else語句,不會(huì)顯示耙厚;所以必須天機(jī)bOk=true;
         document.body.onclick=function (e) {
             e=e||window;
             var target=e.target ||e.srcElement;
             if(target.className.toLowerCase()==="div1"){
                 if(bOk){
                     oP.style.display="block";
                 }else{
                     oP.style.display="none";
                 }
                 bOk=!bOk;
             }else if(target.tagName.toLowerCase()!=="p"){
                 oP.style.display="none";
                 bOk=true;
             }
         };
         //方法2:通過判斷p的行間樣式是否為block來控制顯示和隱藏
         //需注意:在第一次點(diǎn)擊div時(shí)强挫,此時(shí)oP.style.display拿到的值為空,因?yàn)槟玫降氖切虚g樣式薛躬,行間沒有設(shè)置俯渤,而在style中設(shè)置的都是非行間樣式,通過style是不能獲取的型宝,所以第一次點(diǎn)擊會(huì)執(zhí)行else語句八匠;
         document.body.onclick=function (e) {
            e=e||window;
            var target=e.target ||e.srcElement;
            if(target.className.toLowerCase()==="div1"){
                if(oP.style.display==="block"){
                    oP.style.display="none";
                }else{
                    oP.style.display="block";
                }
            }else if(target.tagName.toLowerCase()!=="p"){
                oP.style.display="none";
            }
        }
         //方法3:通過判斷事件源的nodeName來進(jìn)行設(shè)置
         document.body.onclick=function (e) {
            e=e || window.event;
            e.target=e.target || e.srcElement;
            if(e.target.nodeName==="DIV" || e.target.nodeName==="P"){
                 oP.style.display="block";
            }else{
                 oP.style.display="none";
            }
        }
     </script>
     </body>
     </html>
    
  • 購物車點(diǎn)擊版實(shí)例2

    • 需求:當(dāng)點(diǎn)擊div時(shí),p顯示趴酣,當(dāng)移出div后梨树,p隱藏,但是保證從div移出到p元素身上時(shí)岖寞,p不隱藏抡四,從p上移出后,p隱藏仗谆;
    • 方法:1)用onclick和onmouseleave事件設(shè)置指巡;2)用onclick和onmouseout事件設(shè)置,但是用onmouseout事件設(shè)置隶垮,會(huì)存在問題:當(dāng)移出div到p元素身上后厌处,p會(huì)隱藏;所以需要獲取關(guān)聯(lián)元素岁疼,阻斷隱藏代碼阔涉;
    • 知識(shí)點(diǎn):onmouseout與onmouseleave的區(qū)別,以及關(guān)聯(lián)元素的獲取及阻斷代碼執(zhí)行捷绒;
    • 代碼:
     <!DOCTYPE html>
     <html lang="en">
     <head>
         <meta charset="UTF-8">
         <title>購物車實(shí)例</title>
         <style>
             *{
                 margin: 0;
                 padding: 0;
             }
             .div1{
                 width: 200px;
                 height: 50px;
                 background-color: lightseagreen;
                 position: relative;
                 margin: 20px auto;
             }
             .div1 p{
                 width: 500px;
                 height: 300px;
                 position: absolute;
                 right: 0;
                 top: 50px;
                 background-color: lightpink;
                 display: none;
             }
         </style>
     </head>
     <body>
     <div class="div1">
         <p></p>
     </div>
     <script>
         //需求:當(dāng)點(diǎn)div時(shí)瑰排,p顯示,當(dāng)移出div后暖侨,p隱藏椭住,但是保證從div移出到p元素身上時(shí),p不隱藏字逗,從p上移出后京郑,p隱藏宅广;
         //方法1:用點(diǎn)擊事件和onmouseleave事件設(shè)置
         var oDiv=document.getElementsByTagName("div")[0];
         var oP=document.getElementsByTagName("p")[0];
         oDiv.onclick=function () {
             oP.style.display="block";
         };
         //用onmouseleave設(shè)置,當(dāng)移出div到p元素身上后些举,p不會(huì)隱藏跟狱;
         oDiv.onmouseleave=function () {
             oP.style.display="none";
         };
         //方法2:用onclick和onmouseout事件設(shè)置,但是用onmouseout事件設(shè)置户魏,會(huì)存在問題:當(dāng)移出div到p元素身上后驶臊,p會(huì)隱藏;所以需要獲取關(guān)聯(lián)元素叼丑,阻斷隱藏代碼关翎;
         oDiv.onclick=function () {
             oP.style.display="block";
         };
         oDiv.onmouseout=function (e) {
             e=e||window.event;
             //獲取關(guān)聯(lián)元素,阻斷隱藏代碼執(zhí)行鸠信;
             var omo=e.toElement || e.relatedTarget;
             if(this.contains(omo)) return;
             oP.style.display="none";
         }
     </script>
     </body>
     </html>
    

知識(shí)點(diǎn)擴(kuò)充

  • 定位:
    • 頁面結(jié)構(gòu)中元素A包含著B元素纵寝,A為父級(jí)元素,B為子級(jí)元素星立,B相對(duì)于A定位
    • B的盒子模型是包含margin在內(nèi)的大盒子店雅,然后相對(duì)于A的邊框內(nèi)邊緣定位,即若B的margin設(shè)置為0贞铣,并且定位中l(wèi)eft也設(shè)置為0闹啦,則B的左邊框外邊緣與A的左邊框內(nèi)邊緣貼合,當(dāng)添加margin之后辕坝,二者之間會(huì)存在相應(yīng)間隔窍奋;
    • 總結(jié):子級(jí)元素盒子模型(包含margin)相對(duì)于定位父級(jí)的邊框內(nèi)邊緣進(jìn)行定位;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末酱畅,一起剝皮案震驚了整個(gè)濱河市琳袄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纺酸,老刑警劉巖窖逗,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異餐蔬,居然都是意外死亡碎紊,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門樊诺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來仗考,“玉大人,你說我怎么就攤上這事词爬⊥菏龋” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長锅锨。 經(jīng)常有香客問我叽赊,道長,這世上最難降的妖魔是什么必搞? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任必指,我火速辦了婚禮,結(jié)果婚禮上顾画,老公的妹妹穿的比我還像新娘取劫。我一直安慰自己匆笤,他們只是感情好研侣,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著炮捧,像睡著了一般庶诡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上咆课,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天末誓,我揣著相機(jī)與錄音,去河邊找鬼书蚪。 笑死喇澡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的殊校。 我是一名探鬼主播晴玖,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼为流!你這毒婦竟也來了呕屎?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤敬察,失蹤者是張志新(化名)和其女友劉穎秀睛,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體莲祸,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蹂安,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了锐帜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片藤抡。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖抹估,靈堂內(nèi)的尸體忽然破棺而出缠黍,到底是詐尸還是另有隱情,我是刑警寧澤药蜻,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布瓷式,位于F島的核電站替饿,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏贸典。R本人自食惡果不足惜视卢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望廊驼。 院中可真熱鬧据过,春花似錦、人聲如沸妒挎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽酝掩。三九已至鳞芙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間期虾,已是汗流浹背原朝。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留镶苞,地道東北人喳坠。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像茂蚓,于是被迫代替她去往敵國和親壕鹉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5煌贴? 答:HTML5是最新的HTML標(biāo)準(zhǔn)御板。 注意:講述HT...
    kismetajun閱讀 27,447評(píng)論 1 45
  • "use strict";function _classCallCheck(e,t){if(!(e instanc...
    久些閱讀 2,028評(píng)論 0 2
  • (續(xù)jQuery基礎(chǔ)(1)) 第5章 DOM節(jié)點(diǎn)的復(fù)制與替換 (1)DOM拷貝clone() 克隆節(jié)點(diǎn)是DOM的常...
    凜0_0閱讀 1,324評(píng)論 0 8
  • 1.JQuery 基礎(chǔ) 改變web開發(fā)人員創(chuàng)造搞交互性界面的方式。設(shè)計(jì)者無需花費(fèi)時(shí)間糾纏JS復(fù)雜的高級(jí)特性牛郑。 1....
    LaBaby_閱讀 1,167評(píng)論 0 1
  • 比特幣資訊:比特幣算力持續(xù)暴漲怠肋,打破“加密貨幣寒冬”謠言!在過去的4個(gè)月以來淹朋,大量的媒體開始報(bào)道比特幣挖礦盈利少得...
    Miss莊一分析閱讀 317評(píng)論 0 0