js进阶(BOM-网页坐标,窗口偏移实现案例)

BOM

BOM概述

bom即为浏览器对象模型,提供了独立于内容而与浏览器窗口进行交互的对象,核心对象是windows,windows是最大的,所以BOM包含DOM
js进阶(BOM-网页坐标,窗口偏移实现案例)_第1张图片

常见事件

窗口加载事件

等页面加载完再执行的事件,包含页面dom元素,即整个dom树加载完毕。所以不存在命名调用的顺序。
js进阶(BOM-网页坐标,窗口偏移实现案例)_第2张图片
DOMConteneLoaded是DOM元素加载完毕,不包含图片,flash等就可以执行,速度更快

调整窗口大小事件

窗口大小发生像素变化,就会触发该事件,即有些页面放大缩小就会改变样式。
一般用来完成响应式布局。windo.innerWidth获取当前屏幕的宽度

案例:缩小窗口隐藏ul

      var ul = document.querySelector('ul');
      window.addEventListener('resize',function(){
     
          if(window.innerWidth<1000){
     
              ul.style.display = 'none';
          }else{
     
              ul.style.display = 'block';
          }
      })

定时器

有多个定时器要其不同的名字,做不同的标识符
setTimeout()和setInterval()的用法与区别:

  1. setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。
  2. setTimeout()方法只调用一次函数。

视情况而用不同定时器。

案例1:倒计时效果。在3个span中显示倒计时。(用到了之前的时间戳)

      var span = document.querySelectorAll('span');             
      var inputTime = +new Date('2021-4-7 14:10:00');//目标时间         
      countDown();//先调用一次函数,避免调用定时器前出现的间隙,因为调用定时器也需要时间。
      setInterval(countDown,1000);
      function countDown(){
     
             var nowTime = +new Date();

             var times = (inputTime - nowTime) / 1000;//倒计时的秒数   h
             var h = parseInt(times / 60 /60%24);//时 
             h = h < 10? '0' + h : h;    
             span[0].innerHTML = h;
             var m = parseInt(times / 60 %60);//分 
             m = m < 10? '0' + m : m;  
             span[1].innerHTML = m; 
             var s = parseInt(times %60);//秒 
             s = s < 10? '0' + s : s;     
             span[2].innerHTML = s; 
         }

案例2:模拟显示短时间内不能再次发送短信。如60s内发送验证码则需要倒计时60s。
在这里插入图片描述

      var btn = document.querySelector('button')
      var time = 10//定义剩下的秒数
      btn.addEventListener('click',function(){
     
          btn.disabled = true;
          var timer= setInterval(function(){
     
              if(time ==0){
     
                  clearInterval(timer)
                  btn.disabled = false;
                  btn.innerHTML = '发送验证码'
                  time=10//重置倒计时
              }else{
     
                btn.innerHTML = '还剩下'+ time +'s';
                time--
              }
          },1000);  
      })

这里很巧妙地让秒数递减,再用定时器逐秒显示,就不用将整个倒计时用定时器做。

this指向问题: 定时器里的this指向的是window,定时器算window地一个属性,其他的都指向调用者。

js队列

js进阶(BOM-网页坐标,窗口偏移实现案例)_第3张图片

同步与异步

js进阶(BOM-网页坐标,窗口偏移实现案例)_第4张图片
执行机制:
先执行同步任务,异步任务(回调函数)放入任务队列,再执行在任务队列中任务,回调函数都属于异步任务,因为回调函数需要时间,如果时间较长,会影响后面的任务
js进阶(BOM-网页坐标,窗口偏移实现案例)_第5张图片

      console.log(1);
      setTimeout(function(){
     
         console.log(3);
      },0)
      console.log(2);

//输出为1 2 3

location对象

URL

js进阶(BOM-网页坐标,窗口偏移实现案例)_第6张图片

location属性

js进阶(BOM-网页坐标,窗口偏移实现案例)_第7张图片
案例:按键定时跳转其他页面,综合运用了前面刚学的倒计时配合location

  <body>
    <button>跳转button>
    <div>div>
  body>
  <script>
    var btn = document.querySelector("button");
    var div = document.querySelector("div");
    var time = 5;
    btn.addEventListener("click", function () {
      
      setInterval(function () {
      
        if (time == 0) {
      
          location.href = "http://www.baidu.com";
        } else {
      
          div.innerHTML = "还剩" + time + "s进入新页面";
          time--;
        }
      }, 1000);
    });
  script>

案例2:提交表单跳转页面,输入英文名,跳转另一个欢迎界面

      <form action="index.html">
      <input type="text" name="uname" id="">
    <button>跳转button>

      form>
//主页面


//跳转后的页面
    <div>div>
    <script>
        //location.search得到的是?uname=...,要先用substr去掉问好
        var params = location.search.substr(1)
        //再利用=把字符串分割为数组
        var arr = params.split('=');
        var div = document.querySelector('div')
        div.innerHTML = arr[1] + ',欢迎你'
    script>

表单form中的action属性,是向何处提交数据,即数据去向的地址

location对象方法

括号内加地址
js进阶(BOM-网页坐标,窗口偏移实现案例)_第8张图片

history对象

js进阶(BOM-网页坐标,窗口偏移实现案例)_第9张图片

PC端网页特效

offset元素偏移量

概述:

js进阶(BOM-网页坐标,窗口偏移实现案例)_第10张图片

  <script>
      var fa = document.querySelector('.fa')
      var son = document.querySelector('.son')
      console.log(fa.offsetTop);

      console.log(son.offsetLeft);
      //这个显示的是距离网页边框的距离,因为这个已带定位的父亲为准,如果父亲没有定位,则以浏览器为准

      console.log(son.offsetWeight)
      //得到元素大小,包含内外边距和边框,height同理

       console.log(son.offsetParent)
       //返回带有定位的父亲,否则返回body

offset与style区别

js进阶(BOM-网页坐标,窗口偏移实现案例)_第11张图片

案例:获取鼠标在盒子内的坐标
用鼠标在页面中的坐标减去盒子的在页面中的距离

      var fa = document.querySelector('.fa')
      fa.addEventListener('mousemove',function(e){
     
          
        var x = e.pageX - this.offsetLeft
        var y = e.pageY - this.offsetTop

        this.innerHTML = '这个点坐标为'+x+y;
      })

案例:模拟拖动模态框,点击相应按键才显示,且可拖拽

  <body>
    <div class="btn">
      <p>点击出现拖拽框</p>

    </div>            
     <div class="login">
          <input type="text" />
          <input type="text" />
          <button>关闭</button>
    </div> 
    <div class="bg"></div>
  </body>
  
    var btn = document.querySelector(".btn");
    var login = document.querySelector(".login");
    var bg = document.querySelector(".bg");
    var close = document.querySelector("button");
    btn.addEventListener("click", function () {
     
      bg.style.display = "block";
      login.style.display = "block";
    });
    close.addEventListener("click", function () {
     
      bg.style.display = "none";
      login.style.display = "none";
    });
    login.addEventListener('mousedown',function(e){
     
        // 获取鼠标在框内的坐标
        var x = e.pageX - this.offsetLeft
        var y = e.pageY - this.offsetTop +60//使得鼠标在login盒子中间

         //鼠标移动到的距离减去距离盒子的距离,就是盒子的坐标
        document.addEventListener('mousemove',move)
        function move (e){
     
            login.style.left =e.pageX - x +'px' 
            login.style.top =e.pageY - y +'px' 
        }
        // 鼠标弹起,移除移动事件
        document.addEventListener('mouseup',function(){
     
            document.removeEventListener('mousemove',move)
        })
    })
  </script>

该案例比较综合,用了偏移量结合之前的随鼠标移动实现拖曳,还有很多细节,比如控制拖曳时鼠标应对应哪个板块,即目标框不会突然闪烁跳动。

今日经典案例:模拟京东图片放大镜,即鼠标移动会形成一个放大镜,在隔壁放大显示图形。

    <style>
      * {
      
        padding: 0;
        margin: 0;
      }
      .old,
      .old img {
      
        width: 300px;
        height: 300px;
      }
      .mask {
      
        display: none;
        position: absolute;
        top: 0;
        left: 0;
        width: 100px;
        height: 100px;
        background-color: rgb(184, 184, 92);
        opacity: 0.5;
        cursor: move;
        pointer-events: none;
      }
      .show {
      
        display: none;
        position: relative;
        overflow: hidden;
        left: 300px;
        top: -200px;
        z-index: 999;
        width: 450px;
        height: 450px;
      }
      .showImg{
      
          position: absolute;
          top: 0;
          left: 0%;
          width: 750px;
          height: 750px;
      }
    style>
  head>
  <body>
    <div class="old">
      <img src="微信图片_20200831202623.jpg" alt="" />
    div>
    <div class="mask">div>
    <div class="show">
      <img
        src="微信图片_20200831202623.jpg" alt="" class="showImg"/>
    div>
  body>
  <script>
    var old = document.querySelector(".old");
    var mask = document.querySelector(".mask");
    var show = document.querySelector(".show");
    var bigPic = show.querySelector('img') 
    //   显示隐藏
    old.addEventListener("mouseover", function () {
      
      mask.style.display = "block";
      show.style.display = "block";
    });
    old.addEventListener("mouseout", function () {
      
      mask.style.display = "none";
      show.style.display = "none";
    });

    //   遮挡层拖动
    old.addEventListener("mousemove", function (e) {
      
      var x = e.pageX - this.offsetLeft;
      var y = e.pageY - this.offsetTop;

      // 超出框则停在边上
      var maskX = x - mask.offsetWidth / 2;
      var maskY = y - mask.offsetHeight / 2;
      if (maskX < 0) {
      
        maskX = 0;
      } else if (maskX>=old.offsetWidth - mask.offsetWidth) {
      
        maskX = old.offsetWidth - mask.offsetWidth;
      }
      if (maskY < 0) {
      
        maskY = 0;
      } else if (maskY>=old.offsetHeight - mask.offsetHeight) {
      
        maskY = 200;
      }
      // else if是为了判断在右侧和下侧时的停止条件,因为只能以左上为参照,所以要算停止距离
      // 最大移动距离:盒子宽度减去遮挡层宽度

      mask.style.left = maskX + "px";
      mask.style.top = maskY + "px";

      //大图片的移动距离 = 遮挡层移动距离 * 大图片最大移动距离 / 遮挡层最大移动距离
      //大图片最大移动距离
      var bigMax = bigPic.offsetWidth - show.offsetWidth;
      var bigX = maskX * bigMax/(old.offsetHeight - mask.offsetHeight)
      var bigY = maskY * bigMax/(old.offsetHeight - mask.offsetHeight)
    //   镜像移动,所以要负号
      bigPic.style.left = -bigX + 'px'
      bigPic.style.top = -bigY + 'px'
    });
  script>

整个案例细节很多

  • 通过拖曳“放大镜”,在另一个盒子中移动放大过的照片,达到放大镜的效果
  • 大图移动距离与遮挡层移动距离的关系
    js进阶(BOM-网页坐标,窗口偏移实现案例)_第12张图片
  • pointer-events: none;关键点。说白了就是不接受鼠标事件。一开始一拖曳放大镜图片会一直闪烁,加了这个才解决问题。因为设置的是old触发事件,但目的是mask移动,但是mask移动同时也会触发old事件,所以要让mask不接受鼠标事件,即 :即使鼠标在mask上,也与mask没关系,只是坐标刚好重叠而已。不会重复触发事件。

你可能感兴趣的:(前端)