整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          33-jquery移入移出事件

          33-jquery移入移出事件

          lt;!DOCTYPE html>

          <html>

          <head>

          <meta charset="utf-8">

          <title>33-jquery移入移出事件</title>

          <style type="text/css"> /*樣式開始*/

          *{ /*表示 所選取的該元素以及其所屬的子元素 */

          margin: 0; /*外邊距*/

          padding: 0; /*內邊距*/

          }

          .father{ /* 選中class叫父親的div盒子*/

          width: 200px; /* 寬:200像素*/

          height: 200px; /* 高:200像素*/

          background: red; /* 背景:紅色*/

          }

          .son{ /* 選中class叫兒子的div盒子*/

          width: 100px; /* 寬:100像素*/

          height: 100px; /* 高:100像素*/

          background: #0000FF; /* 背景:藍色*/

          }

          </style>

          <script src="../static/js/jquery-3.6.0.js"></script> <!--引入jQuery 否則后面的$符號不能用 -->

          <script>

          $(function(){ /* jQuery 的入口函數 */

          // alert('入口函數') /* 入口函數沒有錯誤就會彈出 */

          /*

          mouseover mouseout 事件, 子元素被移入移出,也會觸發父元素的事件

          */

          // $(".father").mouseover(function(){ /*選擇class叫父親的div的鼠標移入事件*/

          // alert('鼠標進入了父親的盒子區域') /* 彈出窗口'鼠標進入了父親的盒子區域'*/

          // })

          // $(".father").mouseout(function(){ /*選擇class叫父親的div的鼠標移出事件*/

          // alert('鼠標移出了父親的盒子區域') /* 彈出窗口'鼠標移出了父親的盒子區域'*/

          // })



          /*mouseenter mouseleave 事件, 子元素被移入移出,不會觸發父元素的事件 */

          // $(".father").mouseenter(function(){ /*選擇class叫父親的div的鼠標移入事件*/

          // alert('鼠標進入了父親的盒子區域') /* 彈出窗口'鼠標進入了父親的盒子區域'*/

          // })

          // $(".father").mouseleave(function(){ /*選擇class叫父親的div的鼠標移出事件*/

          // alert('鼠標移出了父親的盒子區域') /* 彈出窗口'鼠標移出了父親的盒子區域'*/

          // })


          // $(".father").hover(function(){ /* 同時監聽鼠標移入移出的事件用hover 子元素被移入移出,不會觸發父元素的事件*/

          // console.log('鼠標移入了') /* 移入后調用*/

          // }, function(){

          // console.log('鼠標移出了') /* 移出后調用*/

          // })


          $(".father").hover(function(){ /* 同時監聽鼠標移入移出的事件用hover 子元素被移入移出,不會觸發父元素的事件*/

          console.log('鼠標移入移出了') /*鼠標移入和移出都監聽了*/

          })


          })


          </script>

          </head>

          <body>

          <div class="father"> <!-- class叫父親的div盒子 -->

          <div class="son"> <!-- class叫兒子的div盒子 -->


          </div>


          </div>

          </body>

          </html>

          內容是《Web前端開發之Javascript視頻》的課件,請配合大師哥《Javascript》視頻課程學習。

          MouseEvent鼠標事件:

          DOM2級事件中定義了7個,DOM3級事件增加了2個鼠標事件:

          • click:單擊或者回車(一般是左按鈕,可以通過鍵盤和鼠標進行);
          • dbclick:雙擊(從技術上說,這個事件不是DOM事件規范中規定);
          • mousedown:按下任意鼠標鍵;
          • mouseup:釋放鼠標按鈕時觸發;
          • mousemove:在元素內部移動時重復地觸發;
          • mouseover:當鼠標進入元素時觸發;
          • mouseout:在鼠標光標位于一個元素上方,再將其移入另一個元素時觸發;又移入的另一個元素可能位于前一個元素的外部,也可能是這個元素的子元素;
          • mouseenter:在鼠標光標從元素外部首次移動到元素范圍之內時觸發;類似于mouseover,但該事件不冒泡,而且在光標移動到后代元素上不會觸發,該事件由IE引入,在DOM3級事件中被納入規范;
          • mouseleave:在位于元素上方的鼠標光標移動到元素范圍之外時觸發,類似于mouseout,但該事件不冒泡,而且在光移動到后代元素上不會觸發,該事件由IE引入,在DOM3級事件中被納入規范;
          • contextmenu:鼠標右擊出現上下文菜單時觸發,這個事件是在HTML5中定義的,其可以取消;

          鼠標事件中還有一類滾輪事件,只包括一個mousewheel事件,但此事件已歸WheelEvent類了;

          document.addEventListener("click", function(event){
              console.log(event);  // MouseEvent
          },false);
          document.addEventListener("mousewheel", function(event){
              console.log(event);  // WheelEvent
          },false);

          可以檢測瀏覽器是否支持所有事件,如:

          var isSupported=document.implementation.hasFeature("MouseEvent", "3.0");

          頁面上的所有元素都支持鼠標事件;除了mouseenter和mouseleave,其他所有鼠標事件都會冒泡,也可以取消,而取消鼠標事件將會影響瀏覽器的默認行為,也會影響其他事件;

          click事件:

          在一個元素上被按下和放開時,click事件就會被觸發,包括鼠標單擊(通常是左按鈕)或鍵盤回車,或者在腳本中為一個對象執行了click()方法也會觸發該事件;

          var btn=document.getElementById("btn");
          btn.click();

          在一個focusable元素上單擊時,該元素就獲得了焦點,就會觸發focus事件和click事件;

          function handler(event){
          console.log(event.type);
          }
          var txt=document.getElementById("txt");
          txt.addEventListener("click", handler,false);
          txt.addEventListener("focus", handler,false);

          其觸發的順序為:focus、click;

          只有在同一個元素上相繼觸發mousedown和mouseup事件,才會觸發click事件;如果mousedown或mouseup中一個被取消,就不會觸發click事件,類似只有觸發兩次click事件才會觸發一次dbclick事件;

          這4個鼠標事件觸發順序:
          mousedown –> mouseup –> click –> mousedown –> mouseup –> click –> dbclick;

          mouseover和mouseout事件:
          當鼠標進入或移出元素時觸發這兩個事件;

          示例:鼠標懸停改變表格行的背景色,如:

          <style>
          #mytable{width: 400px; border-collapse: collapse;}
          #mytable td{ height: 20px; border: 1px solid #000;}
          </style>
          <table id="mytable">
          <tr>
          <td></td> <td></td> <td></td>
          </tr>
          <!-- 多行 -->
          </table>
          <script>
          // 表格名稱、奇數行背景、偶數行背景、鼠標經過背景、點擊后背景
          function changeBg(table, oddColor, evenColor,overColor, clickColor){
          var rows=document.getElementById(table).rows;
          for(var i=0; i < rows.length; i++){
          var tr=rows[i];
          tr.style.backgroundColor=(tr.sectionRowIndex % 2==0) ? oddColor : evenColor;
          tr.original=true;
          tr.addEventListener("click", function(event){
          if(this.original){
          this.original=false;
          this.style.backgroundColor=clickColor;
          }else{
          this.original=true;
          this.style.backgroundColor=(this.sectionRowIndex % 2==0) ? oddColor : evenColor;
          }
          });
          tr.addEventListener("mouseover", function(){
          if(this.original)
          this.style.backgroundColor=overColor;
          });
          tr.addEventListener("mouseout", function(){
          if(this.original)
          this.style.backgroundColor=(this.sectionRowIndex % 2==0) ? oddColor : evenColor;
          });
          }
          }
          changeBg("mytable", "#FFF", "#ccc", "#cfc", "#f00");
          </script>

          mouseover和mouseout事件會冒泡,因此,當觸發mouseout事件時,有可能鼠標真的離開了目標元素,但也有可能是從這個元素移動到它的子元素上,或者從一個子元素移動到另一個子元素,所以在這種情況下,需要判斷鼠標的確切位置;

          <div id="mydiv">
          <div id="div1">div1</div>
          <div id="div2">div2</div>
          </div>
          <script>
          var oDiv=document.getElementById("mydiv");
          oDiv.addEventListener("mouseover", function(event){
          console.log("mouseover:" + event.target.id);
          },false);
          oDiv.addEventListener("mouseout", function(event){
          console.log("mouseout:" + event.target.id);
          },false);
          </script>

          DOM3提供了兩個不冒泡的對應版本mouseenter和mouseleave,如:

          oDiv.addEventListener("mouseenter", function(event){
          console.log("mouseenter:" + event.target.id);
          },false);
          oDiv.addEventListener("mouseleave", function(event){
          console.log("mouseleave:" + event.target.id);
          },false);

          示例:圖片遮罩,如:

          <style>
          *{margin:0; padding: 0;}
          ul,li{list-style: none;}
          ul{display:flex; flex-wrap: wrap;}
          li{width: 200px;}
          li>a{display: block; width: 100%; position: relative;}
          li img{width:200px;}
          </style>
          <ul id="mylist">
          <li><a href="#" title="天下第一山"><img src="images/1.jpg"></a></li>
          <li><a href="#" title="zeronetwork"><img src="images/2.jpg"></a></li>
          <li><a href="#" title="Javascript"><img src="images/3.jpg"></a></li>
          <li><a href="#" title="Web前端開發"><img src="images/4.jpg"></a></li>
          </ul>
          <script>
          window.onload=function(){
          var mylist=document.getElementById("mylist");
          var aList=mylist.getElementsByTagName("a");
          for(var i=0,len=aList.length; i<len; i++){
          var a=aList[i];
          var mask=null;
          a.addEventListener("mouseenter", function(event){
          mask=this.getElementsByClassName("mask")[0];
          if(!mask){
          mask=document.createElement("div");
          mask.className="mask";
          }
          mask.style.backgroundColor="rgba(0,0,0,0.8)";
          var computedStyle=document.defaultView.getComputedStyle(this, null);
          mask.style.width=computedStyle.width;
          mask.style.height=computedStyle.height;
          mask.style.position="absolute";
          mask.style.color="#FFF";
          mask.style.textAlign="center";
          mask.style.lineHeight=computedStyle.height;
          mask.innerHTML=this.title;
          this.insertBefore(mask, this.firstChild);
          },false);
          a.addEventListener("mouseleave", function(event){
          var mask=this.getElementsByClassName("mask")[0];
          console.log(this);
          if(mask){
          this.removeChild(mask);
          }
          },false);
          }
          }
          </script>

          mouseleave和mouseenter事件的行為與CSS的:hover 偽類非常相似;

          mousemove事件,會頻繁觸發,所以,在其事件處理程序中不能放置計算密集的任務,或者使用事件節流的方式;

          鼠標事件對象:

          鼠標事件屬于MouseEvent類,該類指的是用戶與指針設備( 如鼠標 )交互時發生的事件,其繼承自UIEvent類;
          MouseEvent類定義了一組專屬于鼠標事件的屬性,描述了當事件發生時鼠標的位置和按鍵的狀態,也包含了是否有輔助鍵被按下等所有信息;

          客戶區坐標位置:
          clientX與clientY屬性:取得鼠標相對于瀏覽器視口的坐標位置;

          var oDiv=document.getElementById("mydiv");
          EventUtil.addHandler(oDiv, "click", function(event){
          event=EventUtil.getEvent(event);
          console.log(event);
          console.log(event.clientX + "," + event.clientY);
          });

          注,這個位置不包括頁面滾動的距離,如果加上窗口的滾動偏移量,就會把鼠標位置轉換成文檔坐標;
          所有瀏覽器也都實現了x和y屬性,其是clientX和clientY的別名;

          示例:計算鼠標拖動的直線距離,如:

          var obj={};
          function downHandler(event){
          obj.x=event.x;
          obj.y=event.y;
          }
          function upHandler(event){
          obj.mx=event.x - obj.x;
          obj.my=event.y - obj.y;
          obj.d=Math.sqrt((Math.pow(obj.mx,2) + Math.pow(obj.my,2)));
          console.log(obj.mx, obj.my, obj.d);
          }
          document.addEventListener("mousedown", downHandler, false);
          document.addEventListener("mouseup", upHandler, false);

          示例:自定義鼠標樣式,如:

          document.documentElement.style.cursor="none";
          var cursor=document.createElement("span");
          cursor.style.width="20px";
          cursor.style.height="20px";
          cursor.style.position="absolute";
          cursor.style.backgroundColor="#000";
          document.body.appendChild(cursor);
          document.addEventListener("mousemove", function(event){
          cursor.style.left=event.clientX - cursor.offsetWidth / 2 + "px";
          cursor.style.top=event.clientY - cursor.offsetHeight / 2 + "px";
          },false);

          文檔坐標位置:
          pageX和pageY屬性:取得鼠標光標在文檔中的位置;

          console.log(event.pageX + "," + event.pageY);

          這個位置是包括滾動距離的,在文檔沒有滾動的情況下,pageX、pageY與clientX、clientY值相等;
          IE8及以下不支持文檔坐標,不過使用客戶區坐標和滾動信息可以計算出來,也就是需要用到scrollLeft和scrollTop屬性,如:

          var oDiv=document.getElementById("mydiv");
          EventUtil.addHandler(oDiv, "click", function(event){
          event=EventUtil.getEvent(event);
          var pageX=event.pageX,
          pageY=event.pageY;
          if(pageX==undefined)
          pageX=event.clientX + (document.body.scrollLeft || document.documentElement.scrollLeft);
          if(pageY==undefined)
          pageY=event.clientY + (document.body.scrollTop || document.documentElement.scrollTop);
          console.log(pageX + ":" + pageY);
          });

          屏幕坐標位置:screenX與screenY屬性:取得相對于屏幕的位置;

          console.log(event.screenX + ":" + event.screenY);

          元素坐標位置:
          offsetX和offsetY屬性,返回與目標元素(target)的內填充邊(padding edge)在X和Y軸方向上的偏移量;坐標原點為padding區左上角,因此,如果目標元素有邊框,鼠標的位置位于邊框上,該屬性值為負值;

          var oDiv=document.getElementById("mydiv");
          oDiv.style.position="relative";
          oDiv.style.left="100px";
          oDiv.style.top="50px";
          document.addEventListener("click", function(event){
          console.log("offsetX:" + event.offsetX + ",offsetY:" + event.offsetY);
          },false);

          如果元素滾動了,也包括offsetLeft和offsetTop值;

          示例:繪圖:

          <style>
          canvas{border: 1px solid;}
          </style>
          <canvas id="mydraw" width="560" height="360"></canvas>
          <script>
          var isDrawing=false;
          var x=0, y=0;
          var mydraw=document.getElementById("mydraw");
          var context=mydraw.getContext("2d");
          mydraw.addEventListener("mousedown", function(event){
          x=event.offsetX, y=event.offsetY;
          isDrawing=true;
          });
          mydraw.addEventListener("mousemove", function(event){
          if(isDrawing===true){
          drawLine(context, x, y, event.offsetX, event.offsetY);
          x=event.offsetX, y=event.offsetY;
          }
          });
          window.addEventListener("mouseup", function(event){
          if(isDrawing===true){
          drawLine(context, x, y, event.offsetX, event.offsetY);
          x=0, y=0;
          isDrawing=false;
          }
          });
          function drawLine(content, x1, y1, x2, y2){
          context.beginPath();
          context.strokeStyle="black";
          context.lineWidth=1;
          context.moveTo(x1, y1);
          context.lineTo(x2, y2);
          context.stroke();
          context.closePath();
          }
          </script>

          movementX和movementY屬性:

          返回當前事件和上一個mousemove事件之間鼠標在水平或垂直方向上的移動值;

          即:currentEvent.movementX=currentEvent.screenX - previousEvent.screenX;

          currentEvent.movementY=currentEvent.screenY - previousEvent.screenY;
          document.addEventListener("mousemove", function(event){
          console.log(event.movementX);
          },false);

          但IE不支持,并且此屬性只有在mousemove事件中才能返回正確的值;

          輔助鍵:

          DOM規定了4個屬性:shiftkey、ctrlKey、altkey和metaKey,表示當事件發生時shift、ctrl、alt和meta4個鍵的按下狀態,均為布爾值,如果按下為true,反之為false;

          var btn=document.getElementById("btn");
          EventUtil.addHandler(btn, "click", handler);
          function handler(event){
          event=EventUtil.getEvent(event);
          var keys=new Array();
          if(event.shiftKey)
          keys.push("shift");
          if(event.altKey)
          keys.push("alt");
          if(event.ctrlKey)
          keys.push("ctrl");
          if(event.metaKey)
          keys.push("meta");
          console.log("keys:" + keys.join(","));
          }

          標準瀏覽器支持,但IE不支持metaKey屬性;

          getModifierState(key)方法:返回指定修飾鍵的當前狀態;
          參數key可以為Control、Alt、Shift和Meta,注意,大小寫是敏感的;

          btn.addEventListener("click", function(event){
          console.log(event.getModifierState("Control"));
          },false);

          relatedTarget相關元素:

          在發生mouseover和mouseout事件時,會涉及到多個元素;對mouseover而言,事件的主目標是獲得光標的元素,而相關元素就是那個失去光標的元素(這個相關元素也可以把它叫做次目標元素);對mouseout事件而言,事件的主目標是失去光標的元素,而相關元素則是獲得光標的元素;
          DOM通過event對象的relatedTarget屬性提供了相關元素的信息,該屬性只針于mouseover、mouseout、mouseenter、mouseleave、focusin、focusout、dragenter(拖動元素進入)事件時才有值;對于其他事件,該屬性為null;

          var oDiv=document.getElementById("mydiv");
          oDiv.addEventListener("mouseover", function(event){
          console.log(event);
          },false);
          oDiv.addEventListener("mouseout", function(event){
          console.log(event);
          },false);

          IE8及以下不支持relatedTarget屬性,但提供了保存著同樣信息不同的屬性,在mouseover事件觸發時,fromElement屬性中保存了相關元素,toElement屬性為事件目標;在mouseout事件觸發時,toElement屬性保存了相關元素,fromElement屬性為事件目標;

          document.addEventListener("mouseover", function(event){
          console.log(event.fromElement);
          console.log(event.toElement);
          },false);

          跨瀏覽器取得相關元素,添加到eventutil文件中;

          getRelatedTarget: function(event){
          if(event.relatedTaret)
          return event.relatedTaret;
          else if(event.toElement)
          return event.toElement;
          else if(event.fromElement)
          return event.fromElement;
          else
          return null;
          }

          應用:

          var oDiv=document.getElementById("mydiv");
          EventUtil.addHandler(oDiv, "mouseout", function(event){
          event=EventUtil.getEvent(event);
          var target=EventUtil.getTarget(event);
          var relatedTarget=EventUtil.getRelatedTarget(event);
          console.log(relatedTarget);
          console.log(relatedTarget.tagName);
          })

          鼠標按鈕:
          對于mousedown和mouseup事件來說,在其event對象存在一個button屬性,表示按下或釋放的哪個鼠標按鈕;可能有3個值:0主按鈕;1中間按鈕鼠標滾輪);2次按鈕;

          btn.addEventListener("mouseup", function(event){
          console.log(event.button);
          },false);

          IE8及以下也提供了button,但其值與DOM的button屬性有很大差異:0 沒有按下按鈕;1按下主按鈕;2次按鈕;3同時按下主次按鈕;4中間按鈕;5同時按下主和中間按鈕;6次和中間按鈕;7同時按下三個;

          跨瀏覽器取得button屬性,在eventutil文件中添加:

          getButton: function(event){
          if(document.implementation.hasFeature("MouseEvents","2.0"))
          return event.button;
          else{
          switch(event.button){
          case 0:
          case 1:
          case 3:
          case 5:
          case 7:
          return 0;
          case 2:
          case 6:
          return 2;
          case 4:
          return 1;
          }
          }
          }

          buttons屬性:
          當鼠標事件觸發的時,如果多個鼠標按鈕被按下,將會返回一個或者多個代表鼠標按鈕的位掩碼:

          • 0:沒有按鍵或者是沒有初始化;
          • 1:鼠標左鍵;
          • 2:鼠標右鍵;
          • 4:鼠標滾輪或者是中鍵;
          • 8:第四按鍵 (通常是“瀏覽器后退”按鍵);
          • 16:第五按鍵 (通常是“瀏覽器前進”);

          buttons的值為各鍵對應值做按位與(+)計算后的值,例如,如果右鍵(2)和滾輪鍵(4)被同時按下,buttons的值為 2 + 4=6,如:

          btn.addEventListener("mousedown", function(event){
          console.log(event.button);
          console.log(event.buttons);
          },false);

          屬性button和buttons 是不同的,buttons可指示任意鼠標事件中鼠標的按鍵情況,而 button只能保證在由按下和釋放一個或多個按鍵時觸發的事件中獲得正確的值;

          which屬性:
          當鼠標事件觸發時,表示被按下的按鈕,其返回特定按鍵的數字,0為無、1為左鍵、2為中間滾輪、3為右鍵;其是非標準屬性,但所有瀏覽器都支持;

          btn.addEventListener("mousedown", function(event){
          console.log(event.which);
          console.log(event.button);
          },false);

          注意,此時應該注冊mousedown或mouseup事件而不是click事件,因為右擊或按下中間滾動不會觸發click事件;

          detail屬性:
          DOM2在event對象中提供了detail屬性,用于給出有關事件的更多信息;對于鼠標click、mousedown和mouseup事件來說,detail中包含了一個數值,表示目標元素被單擊了多少次,其它事件返回0;detail從1開始計數,每次單擊都會遞增;

          console.log(event.detail);

          用此屬性就可以判斷用戶是單擊、雙擊還是三擊;如果鼠標在mousedown和mouseup之間移動了位置,則detail被重置為0;

          IE也通過下列屬性為鼠標事件提供了更多信息:

          • altLeft :布爾值,是否按下了Alt,如果為true,則altKey的值也為true;
          • ctrlLeft:布爾值,是否按下了ctrl,如果為true,則ctrlKey的值也為true;
          • shiftLeft:布爾值,是否按下了shift,如果為true,則shiftKey的值也為true;

          這些屬性只有IE支持;

          示例:拖動文檔元素,當鼠標按下或釋放時,會觸發mousedown和mouseup事件,因此,通過這兩個事件,可以探測和響應鼠標的拖動;如:

          function drag(elementToDrag, event){
              var scroll={x:0, y:0};
              var startX=event.clientX + scroll.x;
              var startY=event.clientY + scroll.y;
          
              var origX=elementToDrag.offsetLeft;
              var origY=elementToDrag.offsetTop;
          
              var deltaX=startX - origX;
              var deltaY=startY - origY;
          
              if(document.addEventListener){
              document.addEventListener("mousemove", moveHandler, true);
              document.addEventListener("mouseup", upHandler, true);
              }else if(document.attachEvent){
          
              elementToDrag.setCapture();
              elementToDrag.attachEvent("onmousemove", moveHandler);
              elementToDrag.attachEvent("onmouseup", upHandler);
              // 作為mouseup事件看待鼠標捕獲的丟失
              elementToDrag.attachEvent("onlosecapture", upHandler);
              }
              // 處理了這個事件,不讓任何其他元素看到它
              if(event.stopPropagation)
              event.stopPropagation();
              else
              event.cancelBubble=true;
              // 現在阻止任何默認操作
              if(event.preventDefault)
              event.preventDefault();
              else
              event.returnValue=false;
          
              // 當元素正在被拖動時,這就是捕獲mousemove事件的處理程序
              // 它用于移動這個元素
              function moveHandler(e){
              if(!e) e=window.event;
              // 移動這個元素到當前鼠標位置
              // 通過滾動條的位置和初始單擊的偏移量來調整
              // var scroll=getScrollOffsets();
              var scroll={x:0,y:0};
              elementToDrag.style.left=(e.clientX + scroll.x - deltaX) + "px";
              elementToDrag.style.top=(e.clientY + scroll.y - deltaY) + "px";
              // 同時不讓任何其他元素看到這個事件
              if(e.stopPropagation)
              e.stopPropagation();
              else
              e.cancelBubble=true;
              }
              // 這是捕獲在拖動結束時發生的最終mouseup事件的處理程序
              function upHandler(e){
              if(!e) e=window.event;
              // 注銷捕獲事件處理程序
              if(document.removeEventListener){
              document.removeEventListener("mouseup", upHandler, true);
              document.removeEventListener("mousemove", moveHandler, true);
              }else if(document.detachEvent){
              elementToDrag.detachEvent("onlosecapture", upHandler);
              elementToDrag.detachEvent("onmouseup", upHandler);
              elementToDrag.detachEvent("onmousemove", moveHandler);
              elementToDrag.releaseCapture();
              }
              // 并且不讓事件進一步傳播
              if(e.stopPropagation)
              e.stopPropagation();
              else
              e.cancelBubble=true;
              }
          }

          應用:

          <div style="position: absolute;left:100px;top:100px; width:150px;background-color: purple;">
          <div style="background-color: gray;" onmousedown="drag(this.parentNode, event);">標題欄-拖動我</div>
          <p>Lorem ...</p>
          </div>

          CSS的pointer-events屬性:

          指定在什么情況下 (如果有) 某個特定的元素可以成為鼠標事件的target;主要用于 SVG元素;
          可能的值為:

          • auto:默認效果,對于SVG內容,該值與visiblePainted效果相同;
          • none:元素永遠不會成為鼠標事件的target;但是,當其后代元素的pointer-events屬性指定其他值時,鼠標事件可以指向后代元素,在這種情況下,鼠標事件將在捕獲或冒泡階段觸發父元素的事件偵聽器;
          • visiblePainted、visibleFill、visibleStroke、visible、painted、fill、stroke、all;

          該屬性可以:

          • 阻止用戶的點擊動作產生任何效果;
          • 阻止缺省鼠標指針的顯示;
          • 阻止CSS里的hover和active狀態的變化觸發事件;
          • 阻止JavaScript點擊動作觸發的事件;
          <style>
          /* 鏈接不會跳轉 */
          a[href="https://www.zeronetwork.cn/"]{
          pointer-events: none;
          }
          </style>
          <a href="https://www.zeronetwork.cn/">零點網絡</a>
          <script>
          var link=document.querySelector("a");
          function handler(event){
          console.log(event);
          }
          // 以下均無效
          link.addEventListener("click",handler,false);
          link.addEventListener("mouseover",handler,false);
          link.addEventListener("drag",handler,false);
          </script>

          此屬性可以通過控制臺改變,如在控制臺輸入:document.querySelector("a").style.pointerEvents="auto";此時,超鏈接就可以觸發了;

          <style>
          /* 使所有img對任何鼠標事件(如拖動、懸停、單擊等)無反應 */
          img{
          pointer-events: none;
          }
          </style>
          <img src="images/1.jpg" />
          <script>
          var img=document.querySelector("img");
          function handler(event){
          console.log(event);
          }
          // 以下均無效
          img.addEventListener("click",handler,false);
          img.addEventListener("mouseover",handler,false);
          img.addEventListener("drag",handler,false);
          </script>

          除了指示該元素不是鼠標事件的目標之外,值none表示鼠標事件“穿透”該元素并且指定該元素“下面”的任何元素;如:

          <style>
          .container{position: relative; width: 200px; height: 150px;}
          .mask{width: 100%; height: 100%; background-color: rgba(0, 0, 0, .5);
          position: absolute; pointer-events: none; color:#FFF}
          .container img{width: 100%; height: 100%;}
          </style>
          <div class="container">
          <div class="mask"></div>
          <a href="https://www.zeronetwork.cn"><img src="images/1.jpg" /></a>
          </div>
          <script>
          var link=document.querySelector(".container>a");
          link.addEventListener("mouseover", function(event){
          var mask=event.currentTarget.parentNode.querySelector(".mask");
          mask.innerHTML=event.currentTarget.title;
          },false);
          link.addEventListener("mouseout", function(event){
          var mask=event.currentTarget.parentNode.querySelector(".mask");
          mask.innerHTML="";
          },false);
          </script>

          示例:取得一個元素的相對鼠標坐標,如:

          <style>
          .parent{ width:400px; height:400px; padding: 50px; margin:100px; background:#f20; }
          .child{ width:200px; height:200px; padding:50px; background:#ff0;}
          .child-child{ width:50px; height:50px; background:#00d;}
          </style>
          <div class="parent" id="parent">
          <div class="child">
          <div class="child-child"></div>
          </div>
          </div>
          <script>
          var parent=document.getElementById("parent");
          parent.addEventListener("click",function(event){
          console.info(event.offsetX);
          });
          </script>

          使用pointer-events屬性后再獲取,如為child和child-child類分別添加pointer-events屬性,此時打印的值就是相對于parent元素的坐標了;

          使用pointer-events來阻止元素成為鼠標事件目標不一定意味著元素上的事件偵聽器永遠不會觸發,如果元素后代明確指定了pointer-events屬性并允許其成為鼠標事件的目標,那么指向該元素的任何事件在事件傳播過CSS添加pointer-events:none,再為其子元素添加pointer-events:all,此時在子元素上單擊就可以觸發注冊在父元素上的事件處理程序;

          當然,位于父元素但不在后代元素上的鼠標活動都不會被父元素和后代元素捕獲(鼠標活動將會穿過父元素而指向位于其下面的元素);

          var subchild=document.querySelector(".child-child");
          subchild.addEventListener("click",function(event){
          console.log("child-child");
          parent.style.pointerEvents="auto";
          });

          該屬性也可用來提高滾動時的幀頻;例如,當頁面滾動時,如果恰巧鼠標懸停在某些元素上,則會觸發其上的hover效果或觸發onmouseover事件,有可能會造成滾動出現問題,此時,如果對body元素應用pointer-events:none,則會禁用了包括hover在內的鼠標事件,從而提高滾動性能;

          <style>
          #mydiv:hover{
          background-color: lightgreen !important;
          }
          </style>
          <div id="mydiv" style="height: 300px;background-color: purple;"></div>
          <div style="height: 1000px;"></div>
          <script>
          var mydiv=document.getElementById("mydiv");
          mydiv.addEventListener("mouseover", function(event){
          console.log(event);
          },false);
          </script>

          滾動頁面時觸發了mouseover事件及hover效果,可以在scroll事件中進行相應的處理,如:

          var timeoutId=null;
          window.addEventListener("scroll", function(event){
          document.body.style.pointerEvents="none";
          if(timeoutId){
          clearTimeout(timeoutId);
          timeoutId=null;
          }else{
          timeoutId=setTimeout(function(){
          console.log("解禁了");
          document.body.style.pointerEvents="auto";
          },500);
          }
          },false);

          部分瀏覽器不支持該屬性,可以判斷其支持情況,如:

          var supportsPointerEvents=(function(){
          var dummy=document.createElement("_");
          if(!('pointerEvents' in dummy.style))
          return false;
          dummy.style.pointerEvents='auto';
          // 如果是真的屬性,則賦值不成功
          dummy.style.pointerEvents='x';
          document.body.appendChild(dummy);
          var result=getComputedStyle(dummy).pointerEvents==='auto';
          document.body.removeChild(dummy);
          return result;
          })();
          console.log(supportsPointerEvents);

          WheelEvent滾輪事件:

          當用戶通過鼠標滾輪與頁面交互,在垂直方向上滾動頁面時(無論向上還是向下),就會觸發mousewheel事件;該事件可以在任何元素上觸發,最終會冒泡到document或window對象,也可以阻止其默認行為;

          document.addEventListener("mousewheel", function(event){
              console.log(event);  // WheelEvent
          },false);

          WheelEvent類:

          表示用戶滾動鼠標滾輪或類似輸入設備時觸發的事件,用以替代MouseWheelEvent和MouseScrollEvent,mousewheel實際上是屬于MouseWheelEvent類,而后面要講的Firefox中的DOMMouseScroll屬于MouseScrollEvent類,它們兩者都不屬于標準,兼容性也不好,為了統一兩者,就出現了標準的WheelEvent類;

          WheelEvent類繼承自MouseEvent類(MouseEvent類繼承自UIEvent類),所有也可以把它看作是鼠標事件,因此,對于WheelEvent事件對象來說,其中也保存著大量與MouseEvent事件同樣的屬性,例如,四對有關獲取坐標的屬性、which(值為0)、relatedTarget(為null)等等;還包括輔助鍵的屬性;

          mousewheel事件中的event對象,除了保存鼠標事件的所有標準信息外,還包含一個特殊的wheelDelta屬性,其指定用戶滾動滾輪有多遠,當用戶向前滾動鼠標滾輪時,該屬性值是120的倍數,當向后滾動時,該值是-120的倍數;

          EventUtil.addHandler(document, "mousewheel", function(event){
              event=EventUtil.getEvent(event);
              console.log(event);
              console.log(event.wheelDelta);
          })

          如果要判斷用戶滾動的方向,只要檢測wheelDelta屬性的正負號即可;在Opera9.5之前的版本中,wheelDelta的值的正負號是顛倒的;

          除了wheelDelta屬性外,事件對象還有wheelDeltaX和wheelDeltaY屬性,并且wheelDelta和wheelDeltaY的值一直相同;

          console.log(event.wheelDelta);
          console.log(event.wheelDeltaY);
          console.log(event.wheelDeltaX);

          IE不支持這兩個屬性;
          Firefox不支持mousewheel事件,但支持一個名為DOMMouseScroll的類似事件,也是在鼠標滾輪滾動時觸發,它也被視為鼠標事件,也包含與鼠標事件有關的所有鼠標;而有關鼠標滾輪的信息則保存在detail屬性中,該屬性與wheelDelta作用相同;當向前滾動鼠標滾輪時,該屬性返回-3的位數,反之返回3的位數;

          可以把該事件添加到頁面中的任何元素,而且該事件會冒泡到window對象;

          EventUtil.addHandler(document, "DOMMouseScroll", function(event){
              event=EventUtil.getEvent(event);
              console.log(event);
              console.log(event.detail);  // 向前為-3,向后是3
          })

          detail屬性值與wheelDelta的值的關系是:wheelDelta等于detail乘以-40;

          可以跨瀏覽器取得鼠標滾輪增值(delta),并添加到eventutil.js中,如:

              getWheelDelta: function(event){
                  if(event.wheelDelta){
                      return event.wheelDelta;
                  }else
                      return -event.detail * 40;
              }

          應用時,需要同時注冊mousewheel和DOMMouseScroll事件,如:

          function handlerMouseWheel(event){
              event=EventUtil.getEvent(event);
              var delta=EventUtil.getWheelDelta(event);
              console.log(delta);
          }
          EventUtil.addHandler(document, "mousewheel", handlerMouseWheel);
          EventUtil.addHandler(document, "DOMMouseScroll", handlerMouseWheel);

          另外,DOMMouseEvent事件對象中還有一個axis屬性,其返回一個long型常量值,表明鼠標滾輪滾動的方向,當返回常量HORIZONTAL_AXIS,值為1時,表示由鼠標滾輪的橫向滾動觸發的,當返回VERTICAL_AXIS,值為2時,表示是由鼠標滾輪的縱向滾動觸發的;

          wheel事件:
          DOM3事件定義了一個名為wheel事件,用于替代mousewheel和DOMMouseScroll事件;事件對象中保存著deltaX、deltaY及deltaZ屬性:用來獲取三個不同的鼠標滾軸;大多數鼠標滾輪是一維或二維的,所以并不能使用deltaZ屬性;

          EventUtil.addHandler(document, "wheel", function(event){
              event=EventUtil.getEvent(event);
              console.log(event);  // WheelEvent
              console.log(event.wheelDelta);  // -120
              console.log(event.wheelDeltaY);  // -120
              console.log(event.deltaX);  // -0
              console.log(event.deltaY);  // chrome返回100,Firefox返回63
              console.log(event.deltaZ);  // 0
          });

          這些值必須乘以-1.2,才和mousewheel事件的wheelDelta值和正負號相匹配;

          wheel事件對象還有一個deltaMode屬性,只讀,其返回long常量值,表示各delta*的值的單位,其值及所表示的單位如下:

          常量值描述

          • DOM_DELTA_PIXEL0x00滾動量單位為像素
          • DOM_DELTA_LINE0x01滾動量單位為行
          • DOM_DELTA_PAGE0x02滾動量單位為頁
          console.log(event.deltaMode);

          示例:在Enclose.js文件中定義enclose()函數,可以把一個圖片裝載到一個容器中,并且能移動這個容器,也能改變容器的大小,如:

          function enclose(content, framewidth, frameheight, contentX, contentY){
              // 這些參數不僅僅是初始值,它們保存當前狀態,能被mousewheel處理程序使用和修改
              framewidth=Math.max(framewidth, 50);
              frameheight=Math.max(frameheight, 50);
              contentX=Math.min(contentX, 0) || 0;
              contentY=Math.min(contentY, 0) || 0;
              // 創建frame元素,且設置CSS類和樣式
              var frame=document.createElement("div");
              frame.className="enclose";
              frame.style.width=framewidth + "px";
              frame.style.height=frameheight + "px";
              frame.style.overflow="hidden"; // 沒有滾動條,不能溢出
              frame.style.boxSizing="border-box"; // 能簡化調整frame大小的計算
              content.parentNode.insertBefore(frame, content);
              frame.appendChild(content);
              // 確定元素相對于frame的位置
              content.style.position="relative";
              content.style.left=contentX + "px";
              content.style.top=contentY + "px";
              var isFirefox=(navigator.userAgent.indexOf('Gecko') !=-1);
              // 注冊mousewheel事件處理程序
              frame.onwheel=wheelHandler;
              frame.onmousewheel=wheelHandler;
              if(isFirefox)
                  frame.addEventListener("DOMMouseScroll", wheelHandler, false);
              function wheelHandler(event){
                  var e=event || window.event;
                  var deltaX=e.deltaX / 3.33 || // wheel事件
                             e.wheelDeltaX / 4 || // mousewheel事件
                                             0    // 屬性未定義
                  var deltaY=e.deltaY / 3.33 || 
                             e.wheelDeltaY / 4 ||
              (e.wheelDeltaY===undefined &&     // 如果沒有2D屬性
                             e.wheelDelta / 4) || // 就使用1D的滾輪屬性
                               e.detail * -1.2 || // DOMMouseScroll事件
                                             0;   // 屬性未定義
                  if(isFirefox && e.type !=="DOMMouseScroll")
                      frame.removeEventListener("DOMMouseScroll", wheelHandler, false);
                  // 獲取內容元素的當前尺寸
                  var contentbox=content.getBoundingClientRect();
                  var contentwidth=contentbox.right - contentbox.left;
                  var contentheight=contentbox.bottom - contentbox.top;
                  // 如果按下Alt鍵,就可以調整frame大小
                  if(e.altKey){
                      if(deltaX){
                          framewidth -=deltaX; // 新寬度,但不能比內容大
                          framewidth=Math.min(framewidth, contentwidth);
                          framewidth=Math.max(framewidth, 50); // 不能小于50
                          frame.style.width=framewidth + "px";
                      }
                      if(deltaY){
                          frameheight -=deltaY; 
                          frameheight=Math.min(frameheight, contentheight);
                          frameheight=Math.max(frameheight - deltaY, 50);
                          frame.style.height=frameheight + "px";
                      }
                  }else{ // 沒有按Alt鍵,就可以平移frame中的內容
                      if(deltaX){
                          var minoffset=Math.min(framewidth - contentwidth, 0);
                          // 把deltaX添加到contentX中,但不能小于minoffset
                          contentX=Math.max(contentX + deltaX, minoffset);
                          contentX=Math.min(contentX, 0);
                          content.style.left=contentX + "px";
                      }
                      if(deltaY){
                          var minoffset=Math.min(frameheight - contentheight, 0);
                          contentY=Math.max(contentY + deltaY, minoffset);
                          contentY=Math.min(contentY, 0);
                          content.style.top=contentY + "px";
                      }
                  }
                  if(e.preventDefault)
                      e.preventDefault();
                  if(e.stopPropagation)
                      e.stopPropagation();
                  e.cancelBubble=true;
                  e.returnValue=false;
                  return false;
              }
          }

          應用:

          <style>
          div.enclose{border: 10px solid; margin:10px}
          </style>
          <img id="content" src="images/1.jpg" />
          <script>
          window.onload=function(){
              enclose(document.getElementById("content"),400,200,-200,-300);
          }
          </script>

          不要混淆wheel事件和scroll事件:wheel事件的默認動作取決于瀏覽器實現,因此wheel事件不一定會觸發scroll事件;即便滾輪事件引發了文檔內容的滾動行為,也不表示wheel事件中的delta*值恰好反映文檔內容的滾動方向;因此,不要依賴delta*屬性獲知文檔內容的滾動方向,可在文檔內容滾動事件中監視target的scrollLeft和scrollTop的變化以推斷滾動方向;

          實現鼠標懸停時圖片放大的效果,可以使用 HTML、CSS 和 JavaScript 來實現。以下是一個簡單的示例代碼:

          HTML:

          <img src="image.jpg" id="myImage" />

          CSS (僅供示例,可根據實際需求調整樣式):

          #myImage {

          transition: transform 0.3s;

          }

          #myImage:hover {

          transform: scale(1.2);

          }

          JavaScript (用于添加鼠標懸停事件監聽器):

          document.getElementById("myImage").addEventListener("mouseover", function () {

          // 這里可以添加其他鼠標懸停時的操作

          });


          document.getElementById("myImage").addEventListener("mouseout", function () {

          // 這里可以添加鼠標移出時的操作

          });

          在上述代碼中,當鼠標懸停在圖片上時,通過 CSS 的 transform:scale(1.2) 實現了圖片放大的效果。同時,使用 JavaScript 添加了鼠標懸停和移出事件的監聽器,以便在這些事件發生時執行其他操作。


          主站蜘蛛池模板: 亚洲国产AV一区二区三区四区| 国产肥熟女视频一区二区三区| 久久久av波多野一区二区| 国产一区内射最近更新| 色欲AV蜜桃一区二区三| 一区二区视频在线| 国产AV一区二区三区无码野战| 波多野结衣一区二区免费视频| 亚洲一区二区三区AV无码| 日韩有码一区二区| 精品国产亚洲一区二区在线观看 | 精品人妻一区二区三区毛片 | 精品无码人妻一区二区免费蜜桃 | 国产成人久久精品区一区二区| 无码人妻一区二区三区av| 中文字幕一区二区三区日韩精品| 色国产精品一区在线观看| 在线观看中文字幕一区| 久久久精品人妻一区二区三区四 | 日本在线视频一区二区三区 | 午夜天堂一区人妻| 国产aⅴ精品一区二区三区久久| 性色AV一区二区三区| 国产伦一区二区三区高清| AV天堂午夜精品一区二区三区 | 午夜视频在线观看一区| 国产在线一区二区三区| 日本高清无卡码一区二区久久 | 国产午夜精品一区二区三区嫩草| 亚洲一区二区三区久久久久| 中文乱码精品一区二区三区| 国精产品一区一区三区| 久久亚洲综合色一区二区三区| 国产探花在线精品一区二区| 国产伦精品一区二区三区无广告| 精产国品一区二区三产区| 亚洲国产精品一区二区久久hs| 冲田杏梨AV一区二区三区| 亚洲一区二区三区日本久久九 | 色老板在线视频一区二区| 免费一区二区无码东京热|