模态框与产品放大镜效果

拖动模态框(弹出框)

案例分析:

  • 点击弹出层,模块框和灰色半透明的遮挡层就会显示出来 display:block;
  • 点击关闭按钮,模块框和灰色半透明的遮挡层就会隐藏出来 display:none;
  • 鼠标放到模块框最上面一行,可以按住鼠标拖拽模块框在页面中移动,触发的事件源是最上面一行,即id为title
  • 鼠标松开,可以停止拖动模态框移动
  • 在页面中拖拽的原理:鼠标按下并且移动,之后松开鼠标
  • 触发事件是鼠标按下mousedown、鼠标移动mousemove、鼠标松开mouseup
  • 拖拽过程:鼠标在移动过程中获得最新的值赋值给模态框的left和top值,这样模态框就会跟着鼠标走了
  • 鼠标的坐标 - 鼠标在盒子内的坐标 = 模态框真正的位置
  <head>
    <style>
      * {
        padding: 0;
        margin: 0;
      }

      a {
        text-decoration: none;
        color: #000;
      }

      .login {
        display: none;
        width: 512px;
        height: 280px;
        position: fixed;
        border: #ebebeb solid 1px;
        left: 50%;
        top: 50%;
        background: #fff;
        box-shadow: 0px 0px 20px #ddd;
        z-index: 9999;
        transform: translate(-50%, -50%);
      }

      .login-header {
        width: 100%;
        height: 30px;
        line-height: 30px;
        font-size: 24px;
        text-align: center;
      }

      .login-title {
        position: relative;
        width: 100%;
        margin: 10px 0px 0px 0px;
        text-align: center;
        line-height: 40px;
        height: 40px;
        font-size: 18px;
        cursor: move;
      }

      .login-title span {
        position: absolute;
        right: -20px;
        top: -30px;
        border: #ebebeb solid 1px;
        width: 40px;
        height: 40px;
        border-radius: 20px;
        background-color: #fff;
      }

      .login-input-content {
        margin-top: 20px;
      }

      .login-input {
        overflow: hidden;
        margin: 0px 0px 20px 0px;
      }

      .login-input input {
        float: left;
        line-height: 35px;
        height: 35px;
        width: 350px;
        border: #ebebeb 1px solid;
        text-indent: 5px;
        background-color: #fff;
      }

      .login-input label {
        float: left;
        width: 90px;
        padding-right: 10px;
        text-align: right;
        line-height: 35px;
        height: 35px;
        font-size: 14px;
      }

      .login-button {
        width: 50%;
        line-height: 40px;
        font-size: 14px;
        margin: 30px auto 0px auto;
        border: #ebebeb 1px solid;
        text-align: center;
      }

      .login-button a {
        display: block;
      }

      .login-bg {
        display: none;
        width: 100%;
        height: 100%;
        position: fixed;
        top: 0px;
        left: 0px;
        background: rgba(0, 0, 0, 0.3);
      }
    </style>
  </head>
  <body>
    <div class="login-header">
      <a href="javascript:;" id="link">点击,弹出登录框</a>
    </div>
    <div class="login">
      <div id="title" class="login-title">
        登录会员
        <span
          ><a href="javascrip:;" id="closeBtn" class="close-login"
            >关闭</a
          ></span
        >
      </div>
      <div class="login-input-content">
        <div class="login-input">
          <label>用户名</label>
          <input type="text" placeholder="请输入用户名" class="list-input" />
        </div>
        <div class="login-input">
          <label>密码</label>
          <input
            type="passwords"
            placeholder="请输入登录密码"
            class="list-input"
          />
        </div>
      </div>
      <div id="loginBtn" class="login-button">
        <a href="javascript" id="login-button-submit">登录会员</a>
      </div>
    </div>
    <!-- 遮罩层 -->
    <div id="bg" class="login-bg"></div>
    <script>
      // 1. 获取元素
      var link = document.querySelector("#link");
      var login = document.querySelector(".login");
      var closeBtn = document.querySelector("#closeBtn");
      var mask = document.querySelector(".login-bg");
      var title = document.querySelector("#title");
      // 2. 点击弹出层这个链接 link  让mask 和login 显示出来
      link.addEventListener("click", function () {
        login.style.display = "block";
        mask.style.display = "block";
        // 3. 点击 closeBtn 就隐藏 mask 和 login
        closeBtn.addEventListener("click", function () {
          login.style.display = "none";
          mask.style.display = "none";
        });
        // 4. 开始拖拽
        // (1) 当我们鼠标按下, 就获得鼠标在盒子内的坐标
        title.addEventListener("mousedown", function (e) {
          var x = e.pageX - login.offsetLeft;
          var y = e.pageY - login.offsetTop;
          // (2) 鼠标移动的时候,把鼠标在页面中的坐标,减去 鼠标在盒子内的坐标就是模态框的left和top值
          document.addEventListener("mousemove", move);
          function move(e) {
            login.style.left = e.pageX - x + "px";
            login.style.top = e.pageY - y + "px";
          }
          // (3) 鼠标弹起,就让鼠标移动事件移除
          document.addEventListener("mouseup", function () {
            document.removeEventListener("mousemove", move);
          });
        });
      });
    </script>
  </body>
</html>

仿京东放大镜效果

案例分析:

整个案例分为3个功能模块

1、鼠标经过小图片盒子,黄色的遮挡层和大图片盒子显示,离开隐藏2个盒子功能

2、黄色的遮挡层跟随鼠标功能

  • 把鼠标坐标给遮挡层不合适,因为遮挡层坐标以父盒子为准
  • 首先是获得鼠标在盒子的坐标,之后把数值给给遮挡层做为left值和top值
  • 此时用到鼠标移动事件,但是还是在小图片盒子内移动
  • 发现遮挡层的位置不对(鼠标在遮挡层的顶点,要在遮挡层的中间),需要减去盒子自身的高度和宽度的一半
  • 遮挡层不能超出小图片盒子范围 如果小于0,就把坐标设置为0,如果大于遮挡层最大的移动距离,就把坐标设置为最大的移动距离
  • 遮挡层的最大移动距离:小图片盒子的宽度减去遮挡层盒子宽度

3、移动黄色遮挡层,大图片跟随移动功能

  • 求大图片的移动距离公式:遮挡层距离/遮挡层最大移动距离=大图片距离/大图片最大移动距离

detail.html

  <head>
    <link rel="stylesheet" href="detail.css" />
    <script src="detail.js"></script>
  </head>
  <body>
    <div class="w">
      <div class="preview_img">
        <img src="../image/s3.png" alt="" />
        <div class="mask"></div>
        <div class="big">
          <img src="../image/big.jpg" alt="" class="bigImg" />
        </div>
      </div>
    </div>
  </body>
</html>

detail.css

*{
    padding: 0;
    margin: 0;
}
.w {
	width: 1200px;
	margin: 0 auto;
}
.preview_img{
    position: relative;
    width: 398px;
    height: 398px;
    margin: 50px;
    border: 1px solid #ccc;
}
.preview_img img{
    vertical-align: middle;
}
.mask{
    display: none;
    position: absolute;
    top: 0;
    left: 0;
    height: 298px;
    width: 298px;
    background-color: #FEDE4F;
    border: 1px solid #ccc;
    opacity: .5;
    cursor: move;
}
.big{
    display: none;
    position: absolute;
    top: 0;
    left: 410px;
    width: 498px;
    height: 498px;
    /* background-color: pink; */
    border: 1px solid #ccc;
    overflow: hidden;
}
.big img{
    position: absolute;
    left: 0;
    top: 0;
}

detail.js

window.addEventListener('load', function() {
    var preview_img = document.querySelector('.preview_img');
    var mask = document.querySelector('.mask');
    var big = document.querySelector('.big');
    // 1. 当我们鼠标经过 preview_img 就显示和隐藏 mask 遮挡层 和 big 大盒子
    preview_img.addEventListener('mouseover', function() {
        mask.style.display = 'block';
        big.style.display = 'block';
    })
    preview_img.addEventListener('mouseout', function() {
            mask.style.display = 'none';
            big.style.display = 'none';
        })
        // 2. 鼠标移动的时候,让黄色的盒子跟着鼠标来走
    preview_img.addEventListener('mousemove', function(e) {
        // (1). 先计算出鼠标在盒子内的坐标
        var x = e.pageX - this.offsetLeft;
        var y = e.pageY - this.offsetTop;
        // console.log(x, y);
        // (2) 减去盒子高度 300的一半 是 150 就是我们mask 的最终 left 和top值了
        // (3) 我们mask 移动的距离
        var maskX = x - mask.offsetWidth / 2;
        var maskY = y - mask.offsetHeight / 2;
        // (4) 如果x 坐标小于了0 就让他停在0 的位置
        // 遮挡层的最大移动距离
        var maskMax = preview_img.offsetWidth - mask.offsetWidth;
        if (maskX <= 0) {
            maskX = 0;
        } else if (maskX >= maskMax) {
            maskX = maskMax;
        }
        if (maskY <= 0) {
            maskY = 0;
        } else if (maskY >= maskMax) {
            maskY = maskMax;
        }
        mask.style.left = maskX + 'px';
        mask.style.top = maskY + 'px';
        // 3. 大图片的移动距离 = 遮挡层移动距离 * 大图片最大移动距离 / 遮挡层的最大移动距离
        // 大图
        var bigIMg = document.querySelector('.bigImg');
        // 大图片最大移动距离
        var bigMax = bigIMg.offsetWidth - big.offsetWidth;
        // 大图片的移动距离 X Y
        var bigX = maskX * bigMax / maskMax;
        var bigY = maskY * bigMax / maskMax;
        bigIMg.style.left = -bigX + 'px';
        bigIMg.style.top = -bigY + 'px';
    })

})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值