国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

JavaScript實現類似拉勾網的鼠標移入移出效果

2019-11-20 08:38:48
字體:
來源:轉載
供稿:網友

先上效果圖(gif自己錄制的,有點難看抱歉,工具licecap)

 

實現思路

 HTML結構

  <ul>    <li>      <div class="bg">        <p>JS</p>      </div>    </li>    .....  </ul>

    li作為鼠標移入(mouseenter)和鼠標移出(mouseleave)的載體。

    div作為動畫執行的載體。

CSS

    div采用absolute定位,通過top、left改變它的位置。

    由于div的top、left可能會超出li的大小,所以要設置li的overflow:hidden;

JS

    1、采用JS操縱CSS3 transition動畫

    2、如何判斷鼠標移入移除的方向

鼠標坐標的相關知識

MouseEvent對象

下面介紹幾個MouseEvent中坐標的相關知識:

    (clientX, clientY): 以可視區域為參考系的坐標。

    (pageX, pageY): 以整個頁面(包括滾動條卷出的區域)為參考系的坐標。

    (screenX, screenY): 以你的電腦屏幕為參考系的坐標。

    獲取某個元素內部的坐標

  function pointTo(element, e) {    var elementBox = element.getBoundingClientRect();    return {      x: e.clientX - elementBox.left,      y: e.clientY - elementBox.top    };  }

    計算元素左上角的坐標

  function startPoint(element){    var x = 0,y = 0;    while(element != null) {      x += element.offsetLeft;      y += element.offsetTop;      element = element.offsetParent;    }    return {      x: x,      y: y    }  }

    獲取元素的寬度和高度(不要認為是width和height 新手特別容易犯錯)

  offsetHeight與offsetWidth

簡單的封裝一下CSS3 transition動畫

/* options參數: obj: 運動的對象 speed: 運動的持續時間(可選) changeStyle: 改變的屬性,這里可能多個,所以采用函數的方式(可選) callback: 回調函數(可選) */  function animation(options){    if(!options.obj) {      return false;    }    //設置默認持續時間    options.speed = options.speed || '.5s';    options.obj.style.transition = "all " + options.speed + " ease-in-out";    options.changeStyle.call(options.obj);    var flag = false;    options.obj.addEventListener('transitionend',function(){      //這里主要由于transitionend在每個屬性的動畫執行完多會走一遍,所以我們要讓它只執行一次。      if(!flag) {        options.callback && options.callback();      }    },false);  }

如何確定方向

這里要用到數學中的正切相關的概念,我自己畫了一張圖,不知道你們能不能看特明白:(奇丑。。。)

 

得到元素的運動方向

  function getDirection(element,startPoint,pagePoint){    var halfWidth = element.offsetWidth / 2,halfHeight = element.offsetHeight / 2;    //得到中心點    var center = {      x: startPoint.x + halfWidth,      y: startPoint.y + halfHeight    }    //得到鼠標偏離中心點的距離    var disX = pagePoint.x - center.x;    var disY = pagePoint.y - center.y;    if(disY < 0 && Math.abs(disY / disX) >= 1) {      //上方      return 1;    }    else if(disY > 0 && Math.abs(disY / disX) >= 1) {      //下      return 2;    }    else if(disX < 0 && Math.abs(disY / disX) < 1) {      //左      return 3;    }    else {      //右      return 4;    }  }

啟動事件的代碼,有注釋

/* options中的參數: 觸發事件的載體: targetElement 執行動畫的載體: animationElement */  function HoverAction(options) {    if(!options.targetElement || !options.animationElement) {      return false;    }    this.targetElement = options.targetElement;    this.animationElement = options.animationElement;    this.timeId = null;    this.speed = "0.3s";  }  HoverAction.prototype.addEvent = function() {    //保存this的指向    var _this = this;    _this.targetElement.addEventListener('mouseenter',function(e){      //得到鼠標的坐標      var point = {        x: e.pageX,        y: e.pageY      }      console.log(point);      //獲得方向      var dir = getDirection(_this.targetElement,startPoint(_this.targetElement),point);      clearTimeout(_this.timeId);      //取消過渡動畫(防止重置動畫載體位置時觸發過渡效果)      _this.animationElement.style.transition = "";      //得到運動的方向,要確定動畫載體的開始位置      switch(dir){        case 1:          _this.animationElement.style.top = "-100%";          _this.animationElement.style.left = "0";          break;        case 2:          _this.animationElement.style.top = "100%";          _this.animationElement.style.left = "0";          break;        case 3:          _this.animationElement.style.top = "0";          _this.animationElement.style.left = "-100%";          break;        case 4:          _this.animationElement.style.top = "0";          _this.animationElement.style.left = "100%";          break;      }      //異步執行      _this.timeId = setTimeout(function(){        animation({          obj: _this.animationElement,          speed: _this.speed,          changeStyle: function(){            this.style.top = "0";            this.style.left = "0";          }        });      },20);    },false);    _this.targetElement.addEventListener('mouseleave',function(e){      var left,top;      var point = {        x: e.pageX,        y: e.pageY      }      clearTimeout(_this.timeId);      _this.animationElement.style.transition = "";      var dir = getDirection(_this.targetElement,startPoint(_this.targetElement),point);      switch(dir) {        case 1:          top = '-100%';          left = '0';          break;        case 2:          top = '100%';          left = "0";          break;        case 3:          left = "-100%";          top = "0";          break;        case 4:          left = "100%";          top = "0";          break;      }      _this.timeId = setTimeout(function(){        animation({          obj: _this.animationElement,          speed: _this.speed,          changeStyle: function(){            this.style.top = top;            this.style.left = left;          }        });      },20);    },false);  }

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能有所幫助,如果有疑問大家可以留言交流。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 香河县| 新昌县| 松潘县| 枣强县| 平度市| 霍山县| 利川市| 平遥县| 潼南县| 康马县| 和顺县| 泰兴市| 濉溪县| 咸丰县| 郑州市| 沁水县| 南投县| 榆林市| 三亚市| 方城县| 迭部县| 探索| 获嘉县| 静海县| 江陵县| 建水县| 霸州市| 甘南县| 宝应县| 萍乡市| 名山县| 盐边县| 大关县| 上蔡县| 长葛市| 花莲县| 白城市| 瑞丽市| 神木县| 乌拉特后旗| 澄江县|