Skip to content
html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet">
  <style>
    html, body {
      position: relative;
    }

    .login {
      width: 500px;
      height: 300px;
      border: 1px solid black;
      user-select: none;
      position: absolute;
    }

    .login .header {
      width: 100%;
      height: 60px;
      cursor: move;
      font-size: 25px;
      text-align: center;
      line-height: 60px;
    }

    .login .content {
      width: 100%;
      height: 180px;
      background-color: pink;
    }

    .login .footer {
      width: 100%;
      height: 60px;
      font-size: 25px;
      text-align: right;
      line-height: 60px;
    }

    .login .footer span {
      margin: 0 20px;
    }
  </style>
</head>

<body>
  <section class="login">
    <div class="header">登录</div>
    <div class="content">...</div>
    <div class="footer">
      <span>Cancel</span>
      <span>Login</span>
    </div>
  </section>

  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js"></script>
  
  <script>
    function move (event) {
      let curX = event.pageX,
        curY = event.pageY,
        curL = curX - this.startX + this.startL,
        curT = curY - this.startY + this.startT,
        minL = 0,
        minT = 0,
        maxL = document.documentElement.clientWidth - this.offsetWidth,
        maxT = document.documentElement.clientHeight - this.offsetHeight

      // 边界判断
      curT = curT < minT ? minT : (curT > maxT ? maxT : curT)
      curL = curL < minL ? minL : (curL > maxL ? maxL : curL)
      this.style.top = curT + 'px'
      this.style.left = curL + 'px'
    }

    function up () {
      document.removeEventListener('mousemove', this._move)
      document.removeEventListener('mouseup', this._up)
    }

    function down (event) {
      this.startX = event.pageX,
      this.startY = event.pageY,
      this.startL = this.offsetLeft,
      this.startT = this.offsetTop
      this._move = move.bind(this)
      this._up = up.bind(this)
      
      document.addEventListener('mousemove', this._move)

      this.addEventListener('mouseup', this._up)
    }

    let header = document.querySelector('.header'),
      login = document.querySelector('.login')

    // 核心: 点击头部时让触发事件的this变为login, 并且给login开启定位
    header.addEventListener('mousedown', down.bind(login))
  </script>
</body>

</html>