04-DOM和事件案例分析

元素居中效果

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .box {
      width: 400px;
      height: 100px;
      border: 1px solid red;
      background: #ffc0cb;
      padding: 10px;
      position: absolute;
    }
  </style>
</head>

<body>
  <div class="box"></div>

  <script>
    var box = document.querySelector('.box');
    //浏览器的宽度 - 盒子的宽度 除以2 设置为 盒子的left
    center(box)

    // 当窗口变化的时候也要实现居中的效果
    window.onresize = function () {
      center(box)
    }

    // 实现一个居中效果的函数
    function center(ele) {
      // 获取浏览器的宽高
      var winHeight = window.innerHeight;
      var winWidth = window.innerWidth;

      // 获取元素的宽高
      var eleWidth = ele.offsetWidth;
      var eleHeight = ele.offsetHeight;
      // console.log(eleWidth, eleHeight)

      ele.style.left = (winWidth - eleWidth) / 2 + 'px';
      ele.style.top = (winHeight - eleHeight) / 2 + 'px';
    }

  </script>
</body>

</html>

可编辑表格

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>动态生成表格</title>
  <style>
    table {
      margin-top: 20px;
      width: 800px;
      border: 1px solid #ddd;
      border-collapse: collapse;
    }

    td,
    th {
      border: 1px solid #ddd;
      padding: 5px 10px;
    }

    td {
      padding: 0;
      height: 30px;
    }

    td input {
      width: 100%;
      height: 30px;
      border: none;
      background-color: #ffc;
    }
  </style>
  <script>
    window.onload = function () {
			/*
				动态生成可编辑表格
					1)生成表格
						1>序号
							1-n
						2>数据
							根据输入值确定数据
						3>删除
							显示删除按钮
					2)表格编辑
						1>点击td时,生成一个输入框
						2>把td的内容赋值给输入框
						3>把输入框添加到td
					3)保存编辑
						把输入框的值写入td
			 */

      // 获取页面元素
      var username = document.getElementById('username');
      var age = document.getElementById('age');
      var tel = document.getElementById('tel');
      var qq = document.getElementById('qq');
      var btnSave = document.getElementById('btnSave');
      var tableList = document.getElementById('tableList');
      var tbody = tableList.children[1];

      // 序号
      var index = 1;

      // 1)生成表格
      // 点击保存按钮生成表格
      btnSave.onclick = function () {
        // 生成一行
        var tr = document.createElement('tr');

        // 给可编辑的表格添加 class名 为 name
        tr.innerHTML = '<td>' + index++ + '</td><td class="name">' + username.value + '</td><td  class="name">' + age.value + '</td><td  class="name">' + tel.value + '</td><td  class="name">' + qq.value + '</td><td><button class="btnDel">删除</td>';

        // 往表格里添加行
        tbody.appendChild(tr);

        // 删除操作
        // 获取删除按钮
        var btnDel = document.getElementsByClassName('btnDel');

        // 绑定点击事件,移除tr
        for (var i = 0; i < btnDel.length; i++) {
          btnDel[i].onclick = function () {
            tbody.removeChild(this.parentNode.parentNode);
          }
        }

        // 给一个标识 标标识td中是否 有input元素
        var flag = false
        // 获取class名为 name 的td 绑定点击事件,然后 编辑表格
        var $name = document.querySelectorAll('.name');
        // 绑定点击事件, 和编辑内容
        $name.forEach(function (item, index) {
          item.onclick = function () {
            // 如果td中没有input元素就添加 input元素
            if (!flag) {
              //  点击的时候可编辑 td内容
              //  所有的标签中 只有input 和 textarea能页面中写内容
              var input = document.createElement('input');

              // 拿到原来td的内容 给到input
              input.value = item.innerHTML;
              // 把td的内容清空
              item.innerHTML = ''
              // 把input添加到 点击的这个元素中
              item.appendChild(input);

              // input自动获取焦点
              input.focus();
              // 添加input元素之后 把这个标识改为true,表示已经有input了
              flag = true
            }

            // 当input失去焦点的时候 ,移出input元素 ,并且input的内容给到td
            input.onblur = function () {
              // 当失去焦点 移出input之后,把标识改为 false,表示 td中没有input元素了

              flag = false
              // item.innerHTML = input.value
              // 拿input.value 来替换 item的所有内容
              item.innerHTML = input.value
            }
          }
        })
      }

    }
  </script>
</head>

<body>
  <label for="username">姓名</label>
  <input type="text" id="username" name="username">
  <label for="age">年龄</label>
  <input type="text" id="age" name="age">
  <label for="tel">电话</label>
  <input type="text" id="tel" name="tel">
  <label for="qq">QQ</label>
  <input type="text" id="qq" name="qq">
  <button id="btnSave">保存</button>
  <div class="list">
    <table id="tableList">
      <thead>
        <tr>
          <th width="40">序号</th>
          <th width="160">姓名</th>
          <th width="60">年龄</th>
          <th width="160">电话</th>
          <th width="160">QQ</th>
          <th width="60">操作</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>
</body>

</html>

事件委托实现表格的复制和删除

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    table {
      width: 100%;
      border: 1px solid #ccc;
      border-collapse: collapse;
      border-spacing: 0px;
    }

    table td {
      border: 1px solid #ccc;
      height: 30px;
    }
  </style>
</head>

<body>
  <div class="box">
    <h1>的使用创建dom节点动态生成表格</h1>
    <label for="">行:</label>
    <input type="text" id="row">
    <label for="">列:</label>
    <input type="text" id="col">
    <input type="button" id="btn" value="生成">
    <div id="output">
      <!-- <table>
                <tbody>
                    <tr>
                        <td>浮动法</td>
                    </tr>
                </tbody>
            </table> -->
    </div>
  </div>

  <script>
    /*
        【1】先获取页面中你需要用到的元素
        【2】点击生成的时候根据行和列数生成 表格
            【2】拿到输入框的值
            【2】根据值循环生成表格
        【3】点击表格中的 复制 和删除按钮 
            复制:复制整行 添加 tbody
            删除:把整行从tbody里面删除

     */
    //  【1】先获取页面中你需要用到的元素
    var output = document.querySelector('#output');
    var btn = document.querySelector('#btn');
    var row = document.querySelector('#row');
    var col = document.querySelector('#col');

    // 生成table 和tbody
    var table = document.createElement('table');
    var tbody = document.createElement('tbody');

    // 把tbody放入table中
    table.appendChild(tbody);

    // 【2】点击生成的时候根据行和列数生成 表格
    btn.onclick = function () {
      // 1】拿到输入框的值
      var _row = row.value;
      var _col = col.value;
      renderTable(_row, _col);
      // 需要点击复制和删除按钮 ,必须保证页面中有这个两个按钮
      // 等页面渲染完成之后才能执行这个操作
      // 在获取元素 绑定事件
    }

    // 事件委托:给父元素output元素绑定事件
    output.onclick = function (e) {
      // 判断点击的是复制按钮,实现克隆元素
      if (e.target.className === 'copy') {
        var newTr = e.target.parentNode.parentNode.cloneNode(true);
        tbody.appendChild(newTr)
      }
      // 判断点击的时候删除按钮 实现删除元素
      if (e.target.className === 'delete') {
        // e.target就是鼠标点击的元素
        e.target.parentNode.parentNode.remove();
      }
    }

    function renderTable(_row, _col) {
      // 2】循环生成行和列
      for (var i = 0; i < _row; i++) {
        var tr = document.createElement('tr');

        // 循环生成列数
        for (var j = 0; j < _col; j++) {
          var td = document.createElement('td');
          td.innerHTML = '单元格' + i + j;
          tr.appendChild(td);
        }
        // 多一列出来 存放删除和赋值按钮
        var _td = document.createElement('td');
        var copyEle = document.createElement('button');
        // 给元素绑定给一个id属性
        copyEle.className = 'copy';
        copyEle.innerHTML = '复制';
        var deleteEle = document.createElement('button');
        deleteEle.className = 'delete';
        deleteEle.innerHTML = '删除'

        _td.appendChild(copyEle);
        _td.appendChild(deleteEle);

        // 把这个的多出来的列也放入 tr
        tr.appendChild(_td)

        // 把生成的tr放入tbody中
        tbody.appendChild(tr);
      }

      // 把table放入output里面
      output.appendChild(table);
    }


  </script>

</body>

</html>

右键菜单事件

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        ul {
            list-style: none;
            padding: 0;
            margin: 0;
        }

        .contextMenu {
            display: none;
            position: absolute;
            top: 0;
            left: 0;
            padding: 2px;
            width: 220px;
            border: 1px solid #ddd;
        }

        .contextMenu li {
            position: relative;
            padding-left: 10px;
            border-bottom: 1px dotted #ddd;
            line-height: 2.2;
        }

        .contextMenu li:hover {
            background-color: #efefef;
        }

        .contextMenu li:last-child {
            border: none;
        }

        .contextMenu li span {
            position: absolute;
            right: 5px;
            top: 0;
            color: #999;
        }
    </style>
</head>

<body>
    <div class="contextMenu">
        <ul>
            <li class="copy">复制<span>Ctrl+C</span></li>
            <li class="paste">粘贴<span>Ctrl+V</span></li>
            <li class="cut">剪切<span>Ctrl+X</span></li>
            <li class="delete">删除<span>Del</span></li>
            <li class="save">保存<span>Ctrl+S</span></li>
        </ul>
    </div>
    <script>
        // 点击右键的时候 阻止默认的菜单 显示我们自定义的菜单
        // contextmenu 右键事件 菜单事件
        var contextMenu = document.querySelector('.contextMenu');
        window.oncontextmenu = function (e) {
            //阻止默认事件
            e.returnValue = false;
            contextMenu.style.display = 'block'
            contextMenu.style.left = e.clientX + 'px';
            contextMenu.style.top = e.clientY + 'px'
        }
        window.onclick = function (e) {
            if (e.target.className === 'copy') {
                alert('复制功能')
            }
            contextMenu.style.display = 'none'
        }

    </script>
</body>

</html>

发送信息案例

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      padding: 0;
      margin: 0;
    }

    .box {
      width: 800px;
      margin: auto;
    }

    .box .content {
      width: 100%;
      height: 350px;
      border: 1px solid #ccc;
      margin: 20px auto;
      padding: 10px;
      box-sizing: border-box;
    }

    .box .content li {
      margin: 10px 0;
      padding: 5px;
      line-height: 2;
      border-radius: 5px;
      clear: both;
    }

    .box textarea {
      height: 80px;
      display: block;
      margin: auto;
      margin-top: 20px;
      width: 100%;
    }

    .box button {
      width: 80px;
      height: 30px;
      border: 1px solid #ccc;
      float: right;
      margin-top: 10px;
    }

    .active {
      float: right;
      background-color: #fc0;
      color: #fff;
    }

    p {
      color: #ccc;
      font-size: 12px;
    }
  </style>
</head>

<body>
  <div class="box">
    <ul class="content"></ul>
    <textarea name="" id="text" cols="30" rows="10"></textarea>
    <button id="btn">发送</button>
    <p>温馨提示:按 ctrl + shift键也可以发送消息哟</p>
  </div>

  <script>
    /*
        【1】点击发送按钮的时候 获取输入框的信息
        【2】把信息 写入 content里面
     */
    //  获取所需要的元素
    var content = document.querySelector('.content');
    var text = document.querySelector('#text');
    var btn = document.querySelector('#btn');

    // 给按钮绑定点击事件
    btn.onclick = function () {
      if (text.value) {
        renden()
      } else {
        alert('请输入内容')
      }

    }

    // 按下ctrl + shift键也可以发送信息
    text.onkeydown = function (e) {
      // console.log(e.ctrlKey);
      // keydown 可以同时监听多个按下的事件
      if (e.ctrlKey && e.shiftKey) {
        if (text.value) {
          renden()
        } else {
          alert('请输入内容')
        }

      }
    }
    function renden() {

      // 获取输入框的内容 并且还要创建一个元素来接收内容
      var li = document.createElement('li');
      li.className = 'active';
      li.innerHTML = text.value;

      // 把创建的这个标签写入 content
      content.appendChild(li);

      // 清空输入框的内容
      text.value = ''
    }
  </script>
</body>

</html>

根据数据生成表单

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <form action="" id="form"></form>
  <!-- <p>
        <label for="">用户名:</label>
        <input type="text">
    </p>
    <p>
        <label for="">密码:</label>
        <input type="password">
    </p> -->
  <script>
    var arr = [
      {
        label: "用户名",
        name: "username",
        type: "text"
      }, {
        label: "密码",
        name: "password",
        type: "password"
      }, {
        label: "性别",
        name: "gender",
        type: "select",
        value: ['男', '女', '不男', '不女', 'Gay', '妖王']
      }, {
        label: "爱好",
        name: "hobby",
        type: "checkbox",
        value: ['篮球', '足球', '羽毛球', '兵乓球', '爬山', '购物', '旅游', '看美女']
      }, {
        label: '是否已婚',
        name: 'married',
        type: 'radio',
        value: ['已婚', '未婚']
      },
      {
        label: '简介',
        name: 'resume',
        type: 'textarea'
      }];

    var form = document.querySelector('#form');
    // 循环数组 根据数组的数据生成表单
    arr.forEach(function (item, index) {
      // 生成一个p标签
      var p = document.createElement('p');
      var label = document.createElement('label');
      label.innerHTML = item.label + ':';
      p.appendChild(label);

      var input;//不能直接创建input标签,
      // 而是根据 数组对象中 type类型来判断我到底生成什么的标签
      // type为 text,password就生input
      // 如果为 radio,checkbox  就生成 span标签,然后根据对象中的value循环生成input元素
      // type 为select 生成 select标签
      // type 为 textarea 生成textarea
      switch (item.type) {
        case 'text':
        case 'password':
          input = document.createElement('input');
          input.type = item.type;
          input.id = item.name;
          p.appendChild(input)
          break
        case 'radio':
        case 'checkbox':
          // 要来包裹爱好 value循环生成的值
          input = document.createElement('span');
          item.value.forEach(function (items, index) {
            var inp = document.createElement('input');
            // 存放文字
            var text = document.createElement('label');
            text.innerHTML = items;
            inp.type = item.type;
            // 给input添加name属性,实现单选按钮的切换
            inp.name = item.name
            input.appendChild(inp);
            input.appendChild(text);
          })
          p.appendChild(input)
          break
        case 'select':
          input = document.createElement('select');
          // 循环对象中的value 生成option标签
          item.value.forEach(function (items, index) {
            var option = document.createElement('option');
            option.innerHTML = items;
            input.appendChild(option)
          })
          p.appendChild(input)
          break
        case 'textarea':
          input = document.createElement('textarea');
          p.appendChild(input)
      }
      // 把p标签 添加到form中
      form.appendChild(p)
    })

  </script>
</body>

</html>

补充:编辑表格

<!DOCTYPE html>
<html>

<head lang="en">
  <meta charset="UTF-8">
  <title></title>
  <style>
    .main,
    table {
      width: 800px;
      margin: 0 auto;
    }

    .main {
      height: 40px;
      line-height: 40px;
    }

    table,
    th,
    td {
      border: 2px solid black;
      border-collapse: collapse;
    }

    .optd {
      width: 200px;
    }

    input {
      font-size: 14px;
      height: 20px;
      border-radius: 2px;
      border: 1px solid;
      margin: 2px;
    }

    .addTable {
      padding: 10px;
      position: fixed;
      top: 0px;
      left: 0px;
      bottom: 0px;
      right: 0px;
      background: rgba(21, 20, 20, 0.2);
      display: none;
    }

    .addTable table {
      text-align: center;
      margin-bottom: 10px;
      position: absolute;
      top: 50%;
      left: 50%;
      background: #fff;
      transform: translate(-50%, -50%);
    }

    .confirm {
      position: absolute;
      top: 60%;
      left: 50%;
      width: 800px;
      transform: translateX(-50%);
      text-align: center;
      height: 40px;
      line-height: 40px;
    }

    .confirm input {
      height: 40px;
      width: 100px;
    }
  </style>
</head>

<body>
  <div class="main">
    <input type="button" value="新增一行" id="add" />
  </div>
  <table id="table">

  </table>
  <div class="addTable" id="addRow">
    <table>
      <!-- <tr>
        <th>学号</th>
        <th>姓名</th>
        <th>性别</th>
        <th>年龄</th>
      </tr>
      <tr>
        <td><input type="text" id="number" /></td>
        <td><input type="text" id="name" /></td>
        <td>
          <select id="gender">
            <option></option>
            <option></option>
          </select>
        </td>
        <td><input type="text" id="age" /></td>
      </tr> -->
    </table>
    <div class="confirm">
      <input type="button" value="确定" id="sure" />
      <input type="button" value="取消" id="cancle" />
    </div>
  </div>
  <script>
    function $id(id) {
      return document.getElementById(id);
    }
    // 兼容
    function setInnerText(element, text) {
      if (element.innerText !== undefined) {
        element.innerText = text;
      } else {
        element.textContent = text;
      }
    }

    function getInnerText(element) {
      if (element.innerText !== undefined) {
        return element.innerText;
      } else {
        return element.textContent;
      }
    }
    var head = ["学号", "姓名", "性别", "年龄", "操作"];
    var data = [
      { "number": "001", "name": "张三", "gender": "男", "age": 16 },
      { "number": "002", "name": "王五", "gender": "女", "age": 17 },
      { "number": "003", "name": "李葫芦", "gender": "男", "age": 15 },
      { "number": "004", "name": "小明", "gender": "男", "age": 18 },
      { "number": "005", "name": "小红", "gender": "女", "age": 16 }
    ];

    var table = $id("table");
    var headtr = document.createElement("tr");
    table.appendChild(headtr);
    // 循环给headtr里面添加th
    for (var i = 0; i < head.length; i++) {
      var th = document.createElement("th");
      setInnerText(th, head[i]);
      headtr.appendChild(th);
    }

    // data数据,调用函数createRow
    for (var i = 0; i < data.length; i++) {
      var tr = createRow(data[i]);
      table.appendChild(tr);
    }


    function moveUp() {
      var tr = this.parentNode.parentNode;
      var previous = tr.previousElementSibling;
      if (previous.previousElementSibling) {
        table.insertBefore(tr, previous);
      } else {
        alert("已经是第一行了");
      }
    }
    function moveDown() {
      var tr = this.parentNode.parentNode;
      var next = tr.nextElementSibling;
      if (next) {
        if (next.nextElementSibling) {
          table.insertBefore(tr, next.nextElementSibling);
        } else {
          table.appendChild(tr);
        }
      } else {
        alert("已经是最后一行了!!")
      }
    }
    function deleteRow() {
      var res = confirm("确定要删除?");
      if (res) {
        var tr = this.parentNode.parentNode;
        table.removeChild(tr);
      }
    }

    // 添加绑定事件
    $id("add").onclick = function () {
      $id("addRow").style.display = "block";
    }

    $id("sure").onclick = function () {
      var number = $id("number").value;
      var name = $id("name").value;
      var opts = $id("gender").getElementsByTagName("option");
      var gender;
      for (var i = 0; i < opts.length; i++) {
        if (opts[i].selected) {
          gender = getInnerText(opts[i]);
          break;
        }
      }
      var age = $id("age").value;

      var obj = {
        number: number,
        name: name,
        gender: gender,
        age: age
      };
      var tr = createRow(obj);
      table.appendChild(tr);
      $id("addRow").style.display = "none";
    }

    // 封装createRow函数
    function createRow(obj) {
      var tr = document.createElement("tr");
      table.appendChild(tr);
      for (var key in obj) {
        var td = document.createElement("td");
        setInnerText(td, obj[key]);
        tr.appendChild(td);
      }
      var optd = document.createElement("td");
      optd.className = "optd";
      var up = document.createElement("input");
      up.type = "button";
      up.value = "向上移动";
      up.onclick = moveUp;
      optd.appendChild(up);
      var down = document.createElement("input");
      down.type = "button";
      down.value = "向下移动";
      down.onclick = moveDown;
      optd.appendChild(down);
      var del = document.createElement("input");
      del.type = "button";
      del.value = "删除";
      del.onclick = deleteRow;
      optd.appendChild(del);
      tr.appendChild(optd);
      return tr;
    }

    // 取消按钮绑定事件
    $id("cancle").onclick = function () {
      $id("addRow").style.display = "none";
    }
  </script>
</body>

</html>

在这里插入图片描述

换肤效果

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    * {
      padding: 0;
      margin: 0;
    }

    html,
    body {
      height: 100%;
    }

    ul,
    li {
      list-style: none;
    }

    .box {
      display: flex;
      justify-content: space-evenly;
      align-items: center;
      height: 0px;
      background: #ddd;
      overflow: hidden;
      transition: height 1s;
    }

    .box1 {
      height: 240px
    }

    .box li {
      width: 300px;
    }

    .box li img {
      width: 100%;
    }
  </style>
</head>

<body>
  <ul class="box" style="background:#ddd no-repeat center center">
    <li><img src="images/1.jpg" alt=""></li>
    <li><img src="images/2.jpg" alt=""></li>
    <li><img src="images/3.jpg" alt=""></li>
  </ul>
  <button class="btn">换肤</button>

  <script>
    /*
        换肤案例:
        【1】点击换肤的时候,显示图片的容器(改变高度)
            高度为0   隐藏
            高度为240 显示 .box{height:240px}
            当盒子没有box1的时候那么久给元素添加box1名,如果有box就移出box1
        【2】点击图片的时候,把图片的路径给到 body

        // box.className += 'box1'
        // if (flag) {
        //     box.classList.remove('box1');
        //     flag = false;
        // } else {
        //     box.classList.add('box1');
        //     flag = true;
        // }
        // classList 获取元素class属性的一些方法的对象
        // classlist.add() 添加
        // classlist.remove() 移出
        // classlist.toggle() 转换,有就移出,没有就添加
     */
    let btn = document.querySelector('.btn');
    let box = document.querySelector('.box');
    var flag = false;
    btn.onclick = function () {
      box.classList.toggle('box1');
    }
    box.onclick = function (e) {
      document.body.style.background = 'url(' + e.target.src + ') no-repeat center center / 100% 100%';
      box.classList.toggle('box1')
    }
  </script>
</body>

</html>

拖拽轨迹回放

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    html,
    body {
      overflow: hidden;
    }
    body,
    div,
    h2,
    p {
      margin: 0;
      padding: 0;
    }
    body {
      color: #fff;
      background: #000;
      font: 12px/2 Arial;
    }
    p {
      padding: 0 10px;
      margin-top: 10px;
    }
    span {
      color: #ff0;
      padding-left: 5px;
    }
    #box {
      position: absolute;
      width: 300px;
      height: 150px;
      background: #333;
      border: 2px solid #ccc;
    }
    #box h2 {
      height: 25px;
      line-height: 25px;
      cursor: move;
      /*手型:移动*/
      background: #222;
      border-bottom: 2px solid #ccc;
      text-align: right;
      padding: 0 10px;
    }
    #box h2 a {
      color: #fff;
      font: 12px/25px Arial;
      text-decoration: none;
      outline: none;
    }
  </style>
</head>

<body>
  <div id="box">
    <h2><a href="#">点击回放拖动轨迹</a></h2>
    <p><strong>Drag:</strong><span>false</span></p>
    <p><strong>offsetLeft:</strong><span>0</span></p>
    <p><strong>offsetTop:</strong><span>0</span></p>
  </div>

  <script>
    window.onload = function () {
      /* 
          两个阶段:
          【1】拖拽阶段
              1.在元素上按下 mousedown,同时给document添加 mousemove 事件
                  记录光标在元素上的位置
              2.但在元素上鼠标抬起 mouseup,解除 document的 mousemove 事件
              3.mousemove过程,将盒子的 左边和上边的位置 以对象的形式存在数组中
          【2】回放阶段
              1.点击回放的时候,把存入数组中的 数据一次取出添加给 元素
      */
      var box = document.getElementById('box');
      var h2 = box.children[0];
      var dragSpan = box.children[1].children[1];
      var leftSpan = box.children[2].children[1];
      var topSpan = box.children[3].children[1];
      var links = h2.children[0];
      var arr = [];
      // 给h2绑定点击事件
      h2.onmousedown = function (e) {
        // console.log(1);
        var obj = {};
        obj.x = box.offsetLeft;
        obj.y = box.offsetTop;
        arr.push(obj);
        // 获取点击时候,光标在元素上的位置
        var ox = e.offsetX;
        var oy = e.offsetY;
        dragSpan.innerHTML = 'true';
        document.onmousemove = function (evt) {
          box.style.left = evt.clientX - ox + 'px'
          box.style.top = evt.clientY - oy + 'px';
          leftSpan.innerHTML = evt.clientX - ox;
          topSpan.innerHTML = evt.clientY - oy;
          var obj = {};
          obj.x = evt.clientX - ox;
          obj.y = evt.clientY - oy;
          arr.push(obj);
        }
      }
      document.onmouseup = function () {
        document.onmousemove = null;
        dragSpan.innerHTML = 'false'
      }
      links.onclick = function () {
        clearInterval(links.timer);
        var i = 0;
        links.timer = setInterval(function () {
          box.style.left = arr[i].x + 'px';
          box.style.top = arr[i].y + 'px';

          leftSpan.innerHTML = arr[i].x;
          topSpan.innerHTML = arr[i].y;
          i++;
          if (i === arr.length) {
            clearInterval(links.timer);
            arr = [];
          }
        }, 10)
      }
    }
  </script>

</body>

</html>

在这里插入图片描述

元素在窗口内拖拽(不超出窗口范围)

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .box {
      width: 110px;
      height: 100px;
      background: pink;
      position: absolute;
    }
  </style>
</head>

<body>
  <div class="box"></div>
  <script>
    /*
        1.当鼠标在box盒子按下的时候
        2.并且鼠标window中移动时候 box元素跟着鼠标一起移动
    */
    var box = document.querySelector('.box');
    box.onmousedown = function () {
      console.log(1);

      // 按下之后 在window中移动
      window.onmousemove = function (e) {
        // box元素跟着光标移动
        // 获取光标在可视窗口的坐标
        e = e || window.event;
        //  box.offsetWidth / 2 盒子宽度的一半
        //  box.offsetHeight /2 盒子高度的一半
        var x = e.clientX - box.offsetWidth / 2;
        var y = e.clientY - box.offsetHeight / 2;
        // 边界值的判断
        // 当l盒子的left 和top 小于0 的时候,直接强制等于0 
        // left  和 top的极限值为0 
        if (x <= 0) {
          x = 0;
        }
        if (y <= 0) {
          y = 0;
        }
        // 判断left的最大极限 浏览器的宽度 - 盒子的宽度
        if (x >= window.innerWidth - box.offsetWidth) {
          x = window.innerWidth - box.offsetWidth
        }

        //判断top的极限值
        if (y >= window.innerHeight - box.offsetHeight) {
          y = window.innerHeight - box.offsetHeight
        }

        // 然后把这个值赋值给box的left和top值
        box.style.left = x + 'px';
        box.style.top = y + 'px'
      }
    }
    // 当鼠标在任何位置抬起来的时候,要把移动事件清除
    window.onmouseup = function () {
      //清除一个事件,只需要将事件的值设置null
      window.onmousemove = null;
    };
  </script>
</body>

</html>

下拉菜单升级

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    ul {
      list-style: none;
      padding: 0;
      margin: 0;
    }
    body {
      background: #23384e;
      font: 12px/1.5 \5fae\8f6f\96c5\9ed1;
    }
    .search,
    .search .inner-box,
    .search .box,
    .search .select,
    .search a {
      background: url(images/search.jpg) no-repeat;
    }
    .search,
    .search .box,
    .search .inner-box {
      height: 34px;
    }
    .search {
      position: relative;
      width: 350px;
      margin: 10px auto;
    }
    .search .box {
      background-position: right 0;
    }
    .search .inner-box {
      background-repeat: repeat-x;
      background-position: 0 -34px;
      margin: 0 20px 0 40px;
    }
    .search .select {
      float: left;
      color: #fff;
      width: 190px;
      height: 22px;
      border: none;
      cursor: pointer;
      margin-top: 4px;
      line-height: 22px;
      padding-left: 10px;
      background-position: 0 -68px;
    }
    .search a {
      float: left;
      width: 80px;
      height: 24px;
      color: #333;
      letter-spacing: 4px;
      line-height: 22px;
      text-align: center;
      text-decoration: none;
      background-position: 0 -90px;
      margin: 4px 0 0 10px;
    }
    .search a:hover {
      color: #f60;
      background-position: -80px -90px;
    }
    .search ul {
      position: absolute;
      top: 26px;
      left: 40px;
      color: #fff;
      width: 198px;
      background: #2b2b2b;
      border: 1px solid #fff;
      display: none;
    }
    .search ul li {
      height: 25px;
      line-height: 24px;
      cursor: pointer;
      padding-left: 10px;
      margin-bottom: -1px;
      border-bottom: 1px dotted #fff;
    }
    .search ul li:hover,
    .search ul li.active {
      background: #8b8b8b;
    }
  </style>
</head>

<body>
  <div class="search">
    <div class="box">
      <div class="inner-box">
        <input type="text" id="keyword" class="select" autocomplete="off" placeholder="请选择游戏名称">
        <a href="#">搜索</a>
      </div>
    </div>
    <ul class="list">
      <li>地下城与勇士</li>
      <li>魔兽世界(国服)</li>
      <li>魔兽世界(台服)</li>
      <li>热血江湖</li>
      <li>大话西游II</li>
      <li>QQ幻想世界</li>
    </ul>
  </div>

  <script>
    /*
        实现的功能:
            【1】搜索框获取焦点的时候 显示下拉下单
                【1】获取元素
            【2】搜索框失去焦点时候 隐藏下拉菜单

            一下两个功能只有在获取焦点的时候才会有用
            【3】按下鼠标的上下键 可以动态选中 li元素(给li元素添加 active 这个class名)
            【4】当按下 enter键的时候,把拥有 activeclass名的元素的内容 赋值给搜索框
     */
    var keyword = document.querySelector('#keyword');
    var list = document.querySelector('.list');
    var lists = document.querySelectorAll('.list>li');
    var index = -1;
    // 绑定获取焦点事件
    keyword.onclick = function (event) {
      list.style.display = 'block';
      document.onkeydown = function (e) {
        // 按下下键
        if (e.keyCode === 40) {
          index++;
          if (index > lists.length - 1) {
            index = 0;
          }
          // 排他思想
          for (var i = 0; i < lists.length; i++) {
            lists[i].className = '';
          }
          lists[index].className = 'active';
          //index = 1;
        }
        if (e.keyCode === 38) {
          index--;
          if (index < 0) {
            index = lists.length - 1;
          }
          // 排他思想
          for (var i = 0; i < lists.length; i++) {
            lists[i].className = '';
          }
          lists[index].className = 'active';
        }
        if (e.keyCode === 13) {
          // 把当前选中的li的内容赋值给 搜索框 lists[index]
          // console.log(lists[index].innerHTML);
          keyword.value = lists[index].innerHTML;
          list.style.display = 'none';
          keyword.blur();
        }

      }
      // 点击li的时候,把li的内容赋值给keyword
      lists.forEach(function (items, index) {
        items.onclick = function () {
          for (var i = 0; i < lists.length; i++) {
            lists[i].className = '';
          }
          lists[index].className = 'active';
          keyword.value = this.innerHTML;
        }
      })

      // 阻止事件的传播
      event.cancelBubble = true;
    }

    // 失去焦点的时候 隐藏下拉菜单
    // keyword.onblur = function () {
    //     list.style.display = 'none';
    // }
    document.onclick = function () {
      list.style.display = 'none';
    }

  </script>
</body>

</html>

在这里插入图片描述

全选和反选

<!DOCTYPE html>
<html>

<head lang="en">
  <meta charset="UTF-8">
  <title></title>
  <style>
    * {
      padding: 0;
      margin: 0;
    }

    .wrap {
      width: 300px;
      margin: 100px auto 0;
    }

    table {
      border-collapse: collapse;
      border-spacing: 0;
      border: 1px solid #c0c0c0;
      width: 300px;
    }

    th,
    td {
      border: 1px solid #d0d0d0;
      color: #404060;
      padding: 10px;
    }

    th {
      background-color: #09c;
      font: bold 16px "微软雅黑";
      color: #fff;
    }

    td {
      font: 14px "微软雅黑";
    }

    tbody tr {
      background-color: #f0f0f0;
    }

    tbody tr:hover {
      cursor: pointer;
      background-color: #fafafa;
    }
  </style>

</head>

<body>
  <div class="wrap">
    <table>
      <thead>
        <tr>
          <th>
            <input type="checkbox" id="j_cbAll" />
          </th>
          <th>商品</th>
          <th>价钱</th>
        </tr>
      </thead>
      <tbody id="j_tb">
        <tr>
          <td>
            <input type="checkbox" />
          </td>
          <td>iPhone8</td>
          <td>8000</td>
        </tr>
        <tr>
          <td>
            <input type="checkbox" />
          </td>
          <td>iPad Pro</td>
          <td>5000</td>
        </tr>
        <tr>
          <td>
            <input type="checkbox" />
          </td>
          <td>iPad Air</td>
          <td>2000</td>
        </tr>
        <tr>
          <td>
            <input type="checkbox" />
          </td>
          <td>Apple Watch</td>
          <td>2000</td>
        </tr>

      </tbody>
    </table>
  </div>
  <script>
    // 1. 全选和取消全选做法:  让下面所有复选框的checked属性(选中状态) 跟随 全选按钮即可
    // 获取元素
    var j_cbAll = document.getElementById('j_cbAll'); // 全选按钮
    var j_tbs = document.getElementById('j_tb').getElementsByTagName('input'); // 下面所有的复选框
    // 注册事件
    j_cbAll.onclick = function () {
      // this.checked 它可以得到当前复选框的选中状态如果是true 就是选中,如果是false 就是未选中
      console.log(this.checked);
      for (var i = 0; i < j_tbs.length; i++) {
        j_tbs[i].checked = this.checked;
      }
    }
    // 2. 下面复选框需要全部选中, 上面全选才能选中做法: 给下面所有复选框绑定点击事件,每次点击,都要循环查看下面所有的复选框是否有没选中的,如果有一个没选中的, 上面全选就不选中。
    for (var i = 0; i < j_tbs.length; i++) {
      j_tbs[i].onclick = function () {
        // flag 控制全选按钮是否选中
        var flag = true;
        // 每次点击下面的复选框都要循环检查者4个小按钮是否全被选中
        for (var i = 0; i < j_tbs.length; i++) {
          if (!j_tbs[i].checked) {
            flag = false;
            break; // 退出for循环 这样可以提高执行效率 因为只要有一个没有选中,剩下的就无需循环判断了
          }
        }
        j_cbAll.checked = flag;
      }
    }
  </script>
</body>

</html>

某东显示和隐藏密码

<style>
    .box {
      position: relative;
      width: 400px;
      border-bottom: 1px solid #ccc;
      margin: 100px auto;
    }

    .box input {
      width: 370px;
      height: 30px;
      border: 0;
      outline: none;
    }

    .box img {
      position: absolute;
      top: 2px;
      right: 2px;
      width: 24px;
    }
  </style>
  
  <div class="box">
    <label for="">
      <img src="images/close.png" alt="" id="eye">
    </label>
    <input type="password" name="" id="pwd">
  </div>
  <script>
    // 1. 获取元素
    var eye = document.getElementById('eye');
    var pwd = document.getElementById('pwd');
    // 2. 注册事件 处理程序
    var flag = 0;
    eye.onclick = function () {
      // 点击一次之后, flag 一定要变化
      if (flag == 0) {
        pwd.type = 'text';
        eye.src = 'images/open.png';
        flag = 1; // 赋值操作
      } else {
        pwd.type = 'password';
        eye.src = 'images/close.png';
        flag = 0;
      }
    }
    

在这里插入图片描述

删除留言

思路分析:

  • 当我们给文本域里面的值赋值给li的时候,多添加一个删除链接;
  • 需要把所有的链接获取过来,当我们点击当前的链接的时候,删除当前的链接所在的小 li ;
  • 阻止链接跳转需要添加 javascript:void(0); 或者 javascript:;

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    body {
      padding: 100px;
    }

    textarea {
      width: 200px;
      height: 100px;
      border: 1px solid pink;
      outline: none;
      resize: none;
    }

    ul {
      margin-top: 50px;
    }

    li {
      width: 300px;
      padding: 5px;
      background-color: rgb(245, 209, 243);
      color: red;
      font-size: 14px;
      margin: 15px 0;
    }

    li a {
      float: right;
    }
  </style>
</head>

<body>
  <textarea name="" id=""></textarea>
  <button>发布</button>
  <ul>

  </ul>
  <script>
    // 1. 获取元素
    var btn = document.querySelector('button');
    var text = document.querySelector('textarea');
    var ul = document.querySelector('ul');
    // 2. 注册事件
    btn.onclick = function () {
      if (text.value == '') {
        alert('您没有输入内容');
        return false;
      } else {
        // console.log(text.value);
        // (1) 创建元素
        var li = document.createElement('li');
        // 先有li 才能赋值
        li.innerHTML = text.value + "<a href='javascript:;'>删除</a>";
        // (2) 添加元素
        // ul.appendChild(li);
        ul.insertBefore(li, ul.children[0]);
        // (3) 删除元素 删除的是当前链接的li  它的父亲
        var as = document.querySelectorAll('a');
        for (var i = 0; i < as.length; i++) {
          as[i].onclick = function () {
            // node.removeChild(child); 删除的是 li 当前a所在的li  this.parentNode;
            ul.removeChild(this.parentNode);
          }
        }
      }
    }
  </script>
</body>

</html>

动态生成表格

思路分析:

  • 因为里面的数据是动态的,所以需要js动态生成。这里模拟数据,自己定义好数据,数据采取对象形式存储;
  • 所有的数据都是放到tbody里面的行里面;
  • 因为行很多,需要循环创建多个行(对应多个人);
  • 每个行里面又有很多单元格(对应里面的数据),还需要继续使用循环创建多个单元格,并把数据存入里面(双重for循环);
  • 最后一列单元格是删除,需要单独创建单元格;
  • 最后添加删除操作,单击删除,可以删除当前行;
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    table {
      width: 500px;
      margin: 100px auto;
      border-collapse: collapse;
      text-align: center;
    }

    td,
    th {
      border: 1px solid #333;
    }

    thead tr {
      height: 40px;
      background-color: #ccc;
    }
  </style>
</head>

<body>
  <table cellspacing="0">
    <thead>
      <tr>
        <th>姓名</th>
        <th>科目</th>
        <th>成绩</th>
        <th>操作</th>
      </tr>
    </thead>
    <tbody>

    </tbody>
  </table>
  <script>
    // 1.先去准备好学生的数据
    var datas = [{
      name: '牛一',
      subject: 'JavaScript',
      score: 100
    }, {
      name: '牛二',
      subject: 'JavaScript',
      score: 98
    }, {
      name: '牛三',
      subject: 'JavaScript',
      score: 99
    }, {
      name: '牛五',
      subject: 'JavaScript',
      score: 88
    }, {
      name: '牛六六',
      subject: 'JavaScript',
      score: 0
    }];
    // 2. 往tbody 里面创建行: 有几个人(通过数组的长度)我们就创建几行
    var tbody = document.querySelector('tbody');
    for (var i = 0; i < datas.length; i++) { // 外面的for循环管行 tr
      // 1. 创建 tr行
      var tr = document.createElement('tr');
      tbody.appendChild(tr);
      // 2. 行里面创建单元格(跟数据有关系的3个单元格) td 单元格的数量取决于每个对象里面的属性个数  for循环遍历对象 datas[i]
      for (var k in datas[i]) { // 里面的for循环管列 td
        // 创建单元格 
        var td = document.createElement('td');
        // 把对象里面的属性值 datas[i][k] 给 td  
        // console.log(datas[i][k]);
        td.innerHTML = datas[i][k];
        tr.appendChild(td);
      }
      // 3. 创建有删除2个字的单元格 
      var td = document.createElement('td');
      td.innerHTML = '<a href="javascript:;">删除 </a>';
      tr.appendChild(td);

    }
    // 4. 删除操作 开始 
    var as = document.querySelectorAll('a');
    for (var i = 0; i < as.length; i++) {
      as[i].onclick = function () {
        // 点击a 删除 当前a 所在的行(链接的爸爸的爸爸)  node.removeChild(child)  
        tbody.removeChild(this.parentNode.parentNode)
      }
    }
        // for(var k in obj) {
        //     k 得到的是属性名
        //     obj[k] 得到是属性值
        // }
  </script>
</body>

</html>

在这里插入图片描述
当数据增多时,渲染到页面的数据


  //当数据增多时
 var datas = [{
      name: '牛一',
      subject: 'JavaScript',
      score: 100
    }, {
      name: '牛二',
      subject: 'JavaScript',
      score: 98
    }, {
      name: '牛三',
      subject: 'JavaScript',
      score: 99
    }, {
      name: '牛五',
      subject: 'JavaScript',
      score: 88
    }, {
      name: '牛六六',
      subject: 'JavaScript',
      score: 60
    }, {
      name: '牛二',
      subject: 'JavaScript',
      score: 98
    }, {
      name: '牛二',
      subject: 'JavaScript',
      score: 98
    }, {
      name: '牛二',
      subject: 'JavaScript',
      score: 98
    }, {
      name: '牛二',
      subject: 'JavaScript',
      score: 98
    }];

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值