38、事件

一、点击事件

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>点击事件</title>
  </head>

  <body>
    <!-- onclick = '函数名()' -->
    <button class="btn1" onclick="fn(1,2)">点击事件第一种方法</button>
    <button class="btn2">点击事件第二种方法</button>
  </body>
</html>
<script type="text/javascript">
  // 第一种方法
  var btn1 = document.querySelector(".btn1");
  function fn(a, b) {
    btn1.style.color = "blue";
    console.log(a + b);
  }

  // *第二种方法
  // dom.on事件类型=function(){}
  var btn2 = document.querySelector(".btn2");
  // 我给这个按钮绑定了一个onclick点击事件 每点击一次按钮触发一次函数
  btn2.onclick = function () {
    btn2.style["background-color"] = "pink";
    console.log("我是第二种方法");
  };
</script>

二、this

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>this</title>
  </head>

  <body>
    <button class="btn">点击事件</button>
  </body>
</html>
<script type="text/javascript">
  var str = "今天星期日";
  /*
		windoow是js中最大的对象 所有的全局变量都存储在window中
	 */
  // 可以简写为console.log(str)
  console.log(window.str);
  /*
		普通函数中的this:
			1.指向的是当前的调用者
			2.如果没有调用者,那么this指向的是window
	 */
  function fn1() {
    var str = "多云";
    console.log(str);
    console.log(this.str); // 今天星期四
  }
  window.fn1();

  var btn = document.querySelector(".btn");
  btn.onclick = function () {
    console.log(this); // 指向的是当前调用者button
  };
</script>

三、事件类型

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>事件类型</title>
  </head>

  <body>
    <button style="width: 200px; height: 200px">按钮</button>
    <input type="text" />
  </body>
</html>
<script type="text/javascript">
  /*
		事件类型:
			一、鼠标事件
				*onclick	单击事件
				ondbclick	双击事件
				*onmouseover	鼠标移入/指向时触发
				*onmouseout		鼠标移除/离开时触发
				onmousedown		鼠标按下的时候触发
				onmouseup		鼠标松开的时候触发
				onmousemove		鼠标移动的时候触发
				oncontextmenu	点击鼠标右键的时候触发

			二、键盘事件
				onkeydown	键盘按下的时候触发
				onkeyup		键盘抬起的时候触发

			三、HTML事件
				1.window事件
					*window.onload 		页面加载完成的时候
					*window.onresize	窗口发生改变的时候
					*window.onscroll 	页面滚动的时候
				
				2.表单事件
					*onfocus	获取焦点的时候
					*onblur		失去焦点的时候
					onselsec 	选中文本的时候
					*oninput	input框中用户输入内容的时候
					*onchange	输入框内容发生改变,并且时候焦点的时候触发
	 */
  var btn = document.querySelector("button");
  var ipt = document.querySelector("input");

  btn.onmouseover = function () {
    console.log("鼠标移入时触发");
  };
  btn.onmouseout = function () {
    console.log("鼠标移除的时候触发");
  };

  ipt.onkeydown = function () {
    console.log("键盘被按下时触发");
  };
  ipt.onkeyup = function () {
    console.log("键盘被抬起时触发");
  };

  // 窗口发生变化的时候触发
  window.onresize = function () {
    btn.style.background = "pink";
  };

  ipt.oninput = function () {
    console.log("数据发生变化了");
  };

  ipt.change = function () {
    console.log("输入框的内容发生变化了,并且失去焦点了");
  };
</script>

四、留言例子

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>留言例子</title>
    <style type="text/css">
      * {
        padding: 0;
        margin: 0;
      }

      ul li {
        list-style: none;
      }

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

      textarea {
        width: 100%;
      }

      .title {
        text-align: right;
      }

      .box-foot {
        text-align: right;
      }

      input,
      textarea {
        outline: none;
      }

      .box-foot {
        overflow: hidden;
      }

      .box-foot label {
        float: left;
        padding: 10px 0;
      }

      .box-foot input[type="submit"] {
        float: right;
        background-color: blue;
        border: 0;
        color: #fff;
        padding: 10px 30px;
        border-radius: 5px;
      }
    </style>
  </head>

  <body>
    <div class="box">
      <h2>提问:</h2>
      <p class="title"></p>
      <!-- 输入内容时候的触发 handInput() -->
      <textarea
        rows="10"
        maxlength="49"
        placeholder="请输入内容"
        oninput="handleInput()"
      ></textarea>
      <div class="box-foot">
        <label>匿名 <input type="checkbox" name="" class="multi" /></label>
        <!-- 点击提交按钮的时候 调用fn这个函数 -->
        <input type="submit" name="" value="提交" onclick="fn()" />
      </div>
      <h2>回答</h2>
      <ul>
        <li>正常:张三</li>
      </ul>
    </div>
  </body>
</html>
<script type="text/javascript">
  // 获取多行文本输入框
  var txt = document.querySelector("textarea");
  // 获取多选框
  var multi = document.querySelector(".multi");
  // 获取p标签
  var op = document.querySelector("p");

  function handleInput() {
    // txt.value输入框里面的内容
    console.log(txt.value.length);
    op.innerText = 49 - txt.value.length + "/49";
  }
  handleInput();

  function fn() {
    if (txt.value == "") {
      alert("请输入内容");
    } else {
      // 当内容不为空的时候
      // checked="checked" 设置默认选中
      if (multi.checked != true) {
        // 多选框未选中
        text("正常:");
      } else {
        // 多选框选中的时候
        text("匿名:");
      }
    }
  }

  function text(row) {
    var oUl = document.querySelector("ul");
    oUl.innerHTML += `<li>${row}${txt.value}</li>`;
    // 没提交一次将输入框的内容清空
    txt.value = "";
    op.innerText = "49/49";
  }
</script>

五、简易轮播图

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>简易轮播图</title>
    <style type="text/css">
      * {
        padding: 0;
        margin: 0;
      }
      .box {
        width: 900px;
        height: 350px;
        margin: auto;
        background: url(图片相对路径) no-repeat center;
        background-size: 100% 100%;
        position: relative;
      }
      .dot {
        position: absolute;
        right: 0;
        bottom: 0;
      }
      .dot span {
        display: inline-block;
        width: 30px;
        height: 30px;
        margin-left: 10px;
        background-color: rgba(0, 0, 0, 0.4);
        border-radius: 15px;
        text-align: center;
        line-height: 30px;
        color: #fff;
        cursor: pointer;
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div class="dot">
        <span>1</span>
        <span>2</span>
        <span>3</span>
      </div>
    </div>
  </body>
</html>
<script type="text/javascript">
  /*
		轮播图实现思想:
			点击分页器显示对应的图片
			1.点击事件
			2.点击的时候实现背景图的切换
	 */
  var spans = document.querySelectorAll(".dot span");
  // 获取类名为box的div
  var odiv = document.querySelector(".box");
  // 分别给span添加点击事件
  spans[0].onclick = function () {
    odiv.style["background-image"] = "url(图片相对路径)";
  };
  spans[1].onclick = function () {
    odiv.style["background-image"] = "url(图片相对路径)";
  };
  spans[2].onclick = function () {
    odiv.style["background-image"] = "url(图片相对路径)";
  };
</script>

六、轮播图优化

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>轮播图优化</title>
    <style type="text/css">
      * {
        padding: 0;
        margin: 0;
      }
      .box {
        width: 900px;
        height: 350px;
        margin: auto;
        background: url(图片相对路径) no-repeat center;
        background-size: 100% 100%;
        position: relative;
      }
      .dot {
        position: absolute;
        right: 0;
        bottom: 0;
      }
      .dot span {
        display: inline-block;
        width: 30px;
        height: 30px;
        margin-left: 10px;
        background-color: rgba(0, 0, 0, 0.4);
        border-radius: 15px;
        text-align: center;
        line-height: 30px;
        color: #fff;
        cursor: pointer;
      }
      .dot .active {
        background-color: orangered;
        box-shadow: 0px 0px 10px 3px #d4d0d0;
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div class="dot">
        <span class="active">1</span>
        <span>2</span>
        <span>3</span>
      </div>
    </div>
  </body>
</html>
<script type="text/javascript">
  /*
		轮播图实现思想:
			点击分页器显示对应的图片
			1.点击事件
			2.点击的时候实现背景图的切换
	 */
  var spans = document.querySelectorAll(".dot span");
  // 获取类名为box的div
  var odiv = document.querySelector(".box");
  // 分别给span添加点击事件
  /*spans[0].onclick = function(){
		odiv.style['background-image'] = 'url(图片相对路径)'
	}
	spans[1].onclick = function(){
		odiv.style['background-image'] = 'url(图片相对路径)'
	}
	spans[2].onclick = function(){
		odiv.style['background-image'] = 'url(图片相对路径)'
	}*/
  function changeImg() {
    for (var i = 0; i < spans.length; i++) {
      spans[i].onclick = function () {
        console.log(this.innerText); // 获取的是每一个span的文本内容
        var currentIndex = this.innerText;
        /*
					为什么不用i?
						用for循环添加的点击事件内部的i是最后一次执行的i
						因为页面加载立刻执行for循环,循环结束后才点击的点击事件,会导致i变成最后一次点击的结果
				 */
        odiv.style["background"] = `url(images/desktop_${currentIndex}.jpg)`;
        console.log(this);
        // 先给其他项移除类名
        document.querySelector(".active").className = "";
        // 再给当前点击项添加类名
        this.classList.add("active");
      };
    }
  }
  changeImg();
</script>

七、表格操作案例

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>表格操作案例</title>
    <style type="text/css">
      * {
        padding: 0;
        margin: 0;
      }
      table {
        width: 600px;
        margin: 30px auto 0;
        border-collapse: collapse;
        border: 1px solid #000;
      }
      td,
      th {
        padding: 10px 15px;
        text-align: center;
      }
      input[type="text"] {
        width: 160px;
        height: 30px;
        padding-left: 10px;
        margin-right: 15px;
        outline: none;
      }
      button {
        background: blue;
        border: 0;
        width: 100px;
        color: #fff;
        height: 40px;
        line-height: 40px;
        border-radius: 5px;
      }
      .header {
        width: 1000px;
        margin: 15px auto;
      }
    </style>
  </head>
  <body>
    <div class="header">
      歌曲名:<input type="text" name="ipt" /> 演唱者:<input
        type="text"
        name="ipt"
      />
      发行时间:<input type="text" name="ipt" />
      <button class="btnAdd" onclick="handleAdd()">点击添加</button>
      <button class="btnClone" onclick="handleClone()">点击复制</button>
    </div>
    <table border="1">
      <thead>
        <tr>
          <th>序号</th>
          <th>歌曲名</th>
          <th>演唱者</th>
          <th>发行时间</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>1</td>
          <td>晴天</td>
          <td>周杰伦</td>
          <td>2002年</td>
          <td>
            <a href="javascript:;" onclick="del(this)">删除</a>
          </td>
        </tr>
      </tbody>
    </table>
  </body>
</html>
<script type="text/javascript">
  // 获取表格内容部分
  var tBody = document.querySelector("tbody");
  // 获取所有的输入框
  var ipt = document.querySelectorAll("input");
  // 获取添加按钮
  var btnAdd = document.querySelector(".btnAdd");
  // 获取复制按钮
  var btnClone = document.querySelector(".btnClone");

  // 删除
  function del(row) {
    // console.log(row.parentNode.parentNode)
    row.parentNode.parentNode.remove();
    // 每复制一次 调用一下这个函数 对每一行的序号进行重置
    handleNum();
  }

  // 添加
  function handleAdd() {
    // 要判断输入框的内容不为空 再去进行添加操作
    if (ipt[0].value == "" || ipt[1].value == "" || ipt[2].value == "") {
      alert("请输入内容");
    } else {
      // 输入框内容不为空的时候
      // 第一种方法
      // 获取当前表格的行数
      var num = document.querySelectorAll("tbody tr");
      console.log(num, "序号");
      // tBody.innerHTML +=`
      // 	<tr>
      // 		<td>${num.length+1}</td>
      // 		<td>${ipt[0].value}</td>
      // 		<td>${ipt[1].value}</td>
      // 		<td>${ipt[2].value}</td>
      // 		<td>
      // 			<a href="javascript:;" onclick="del(this)">删除</a>
      // 		</td>
      // 	</tr>
      // `
      // 第二种方法
      // 创建元素
      var tr = document.createElement("tr");
      // 设置内容
      tr.innerHTML = `
					<td>${num.length + 1}</td>
					<td>${ipt[0].value}</td>
					<td>${ipt[1].value}</td>
					<td>${ipt[2].value}</td>
					<td>
						<a href="javascript:;" onclick="del(this)">删除</a>
					</td>
			`;
      // 添加
      tBody.appendChild(tr);
      // 每一次添加数据 清空输入框的内容
      for (var i = 0; i < ipt.length; i++) {
        ipt[i].value = "";
      }
    }
  }

  // 复制
  function handleClone() {
    // 复制的是当前表格的最后一行 先获取表格的最后一行 然后复制一份 添加到tbdoy的最后
    var copyTr = tBody.lastElementChild;
    console.log(copyTr);
    if (copyTr == null) {
      alert("请先添加内容");
    } else {
      tBody.appendChild(copyTr.cloneNode(true));
      // 每复制一次 调用一下这个函数 对每一行的序号进行重置
      handleNum();
    }
  }

  // 重置序号
  function handleNum() {
    var nums = document.querySelectorAll("tbody tr");
    for (var i = 0; i < nums.length; i++) {
      nums[i].firstElementChild.innerText = i + 1;
      // console.log(nums[i])
    }
  }
</script>

八、事件冒泡

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>事件冒泡</title>
    <style type="text/css">
      .box1 {
        width: 300px;
        height: 300px;
        background-color: #eee;
      }
      .box2 {
        width: 100px;
        height: 100px;
        background-color: orange;
      }
    </style>
  </head>
  <body>
    <div class="box1">
      第一个
      <div class="box2">第二个</div>
    </div>
  </body>
</html>
<script type="text/javascript">
  /*
        事件冒泡:
            当一个元素接收到事件的时候,会把它接受到的时间传给自己的父级,就像气泡从水底到水面一样。
            由内到外逐层传递触发

        通俗来讲,事件就是两个div两两嵌套,当我点击里面的div的时候,外面的div的事件也会触发。
    */
  var box1 = document.querySelector(".box1");
  var box2 = document.querySelector(".bxo2");
  box1.onclick = function () {
    console.log("box1的函数被调用了");
  };
  box2.onclick = function () {
    console.log("box2被调用了");
  };
</script>

九、事件委托

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>事件委托</title>
  </head>
  <body>
    <ul>
      <li>
        <span>我是span标签</span>
        <button>我是button按钮</button>
      </li>
      <li>
        <span>我是span标签</span>
        <button>我是button按钮</button>
      </li>
    </ul>
  </body>
</html>
<script type="text/javascript">
  /*
        事件委托(事件代理):
            利用事件冒泡的的原理,通过处理的程序来管理某一类型的所有事件,我只要获取一次dom,就可通过事件委托来操作dom元素,减少内存。

        事件冒泡就是一个元素触发了某个事件,那么这个事件会从当前触发元素开始,向父级冒泡,也就是说,父亲元素可以捕获到所有子元素,在给父级元素绑定的点击事件里面判断当前目标元素,来为不同标签执行相应操作。

        例:假如说页面中有一万个不同大的标签,要求为这个一万个标签添加事件,可以给这一万个标签的爸爸添加一个事件,用事件委托的方法获取一万个儿子,这样就不需要逐个添加事件了。。
    */
  var oUl = document.querySelector("ul");
  // 只需要给祖辈添加事件,就可以通过事件冒泡的原理,让祖辈的后代都添加点击事件
  oUl.onclick = function (event) {
    // 事件函数,会会默认自动接受一个参数 event(形参) ---- 事件委托
    var e = event || window.event; //兼容不同浏览器
    // e.target 会找到你点击的标签
    // e.target.tagName 会找到你点击的标签的标签名
    // toLowerCase() 转小写
    console.log(e.target.tagName.toLowerCase());
    if (e.target.tagName.toLowerCase() == "span") {
      e.target.style.color = "pink";
    } else if (e.target.tagName.toLowerCase() == "button") {
      e.target.style.backgroundColor = "skyblue";
    }
  };
</script>

十、阻止事件冒泡

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>阻止事件冒泡</title>
    <style type="text/css">
      .box1 {
        width: 300px;
        height: 300px;
        background-color: #eee;
      }
      .box2 {
        width: 100px;
        height: 100px;
        background-color: orange;
      }
    </style>
  </head>
  <body>
    <div class="box1">
      第一个
      <div class="box2">第二个</div>
    </div>
    <a href="http://www.baidu.com">百度一下</a>
  </body>
</html>
<script type="text/javascript">
  var box1 = document.querySelector(".box1");
  var box2 = document.querySelector(".box2");

  box1.onclick = function () {
    console.log("box1的函数被调用了");
  };

  //e 事件委托
  box2.onclick = function (e) {
    // 阻止事件冒泡的第一种方法
    // e.stopPropagation()
    // 阻止事件冒泡的第二种方法
    e.cancelBubble = true;
  };

  // 阻止标签的默认行为
  var oA = document.querySelector("a");
  oA.onclick = function (e) {
    e.preventDefault();
  };
</script>

十一、选项卡

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>选项卡</title>
    <style type="text/css">
      .box-head span {
        width: 100px;
        height: 30px;
        line-height: 30px;
        display: inline-block;
        text-align: center;
        background-color: pink;
        color: #fff;
        font-size: 18px;
        cursor: pointer;
      }
      .box-main > div {
        width: 340px;
        height: 300px;
        border: 1px solid #000;
        display: none;
      }
      .box-main > div:first-child {
        display: block;
      }
      .box-head .active {
        background-color: red;
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div class="box-head">
        <span class="active">1</span>
        <span>2</span>
      </div>
      <div class="box-main">
        <div>我是1</div>
        <div>我是2</div>
      </div>
    </div>
  </body>
</html>
<script type="text/javascript">
  /*
        思路:
            1.点击选项卡 点击哪一个选项就给哪个添加类名active 其他的选项清空这个类名
            2.选项卡显示的内容和选项是一一对应的
    */
  // 获取所有的选项
  var btns = document.querySelectorAll(".box .box-head span");
  // 获取切换内容的div
  var oDiv = document.querySelectorAll(".box .box-main>div");
  // console.log(btns,oDiv)
  for (var i = 0; i < btns.length; i++) {
    // 给每一个span添加一个自定义属性
    btns[i].setAttribute("data-index", i);
    // 给每一个span选项添加一个点击事件
    btns[i].onclick = function () {
      // this指向的是当前函数的调用者
      // console.log(this)
      for (var j = 0; j < btns.length; j++) {
        // 将所有选项的类名给他清空
        btns[j].className = "";
        // 点击的时候先让所有的div都隐藏
        oDiv[j].style.display = "none";
      }
      // 给当前点击的添加active类名
      this.className = "active";
      // 获取的是当前点击选项的自定义属性 0 1 2
      // console.log(this.getAttribute('data-index'))
      oDiv[this.getAttribute("data-index")].style.display = "block";
    };
  }
</script>

十二、选项卡封装

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>选项卡封装</title>
    <style type="text/css">
      .box-head span {
        width: 100px;
        height: 30px;
        line-height: 30px;
        display: inline-block;
        text-align: center;
        background-color: pink;
        color: #fff;
        font-size: 18px;
        cursor: pointer;
      }
      .box-main > div {
        width: 340px;
        height: 300px;
        border: 1px solid #000;
        display: none;
      }
      .box-main > div:first-child {
        display: block;
      }
      .box-head .active {
        background-color: red;
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div class="box-head">
        <span class="active">a</span>
        <span>b</span>
        <span>c</span>
      </div>
      <div class="box-main">
        <div>a</div>
        <div>b</div>
        <div>c</div>
      </div>
    </div>
  </body>
</html>
<script src="tab.js">
  // 不允许在这里面写js逻辑
</script>
<script type="text/javascript">
  // 调用函数
  // 传两个参数:
  // 第一个参数:所有的tab选项 也就是box-head下面的所有的span
  // 第二个参数:所有tab选项对应的内容 也就是box-main下面所有的div
  tab(".box .box-head span", ".box .box-main>div");
</script>
function tab(domBtn, domBox) {
  /*
        思路:
            1.点击选项卡 点击哪一个选项就给哪个添加类名active 其他的选项清空这个类名
            2.选项卡显示的内容和选项是一一对应的
    */
  // 获取所有的选项
  var btns = document.querySelectorAll(domBtn);
  // 获取切换内容的div
  var oDiv = document.querySelectorAll(domBox);
  // console.log(btns,oDiv)
  for (var i = 0; i < btns.length; i++) {
    // 给每一个span添加一个自定义属性
    btns[i].setAttribute("data-index", i);
    // 给每一个span选项添加一个点击事件
    btns[i].onclick = function () {
      // this指向的是当前函数的调用者
      // console.log(this)
      for (var j = 0; j < btns.length; j++) {
        // 将所有选项的类名给他清空
        btns[j].className = "";
        // 点击的时候先让所有的div都隐藏
        oDiv[j].style.display = "none";
      }
      // 给当前点击的添加active类名
      this.className = "active";
      // 获取的是当前点击选项的自定义属性 0 1 2
      console.log(this.getAttribute("data-index"));
      oDiv[this.getAttribute("data-index")].style.display = "block";
    };
  }
}

十三、事件绑定

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>事件绑定</title>
  </head>
  <body>
    <p class="tit">我是p标签</p>
    <button>删除鼠标移入事件</button>
    <button>我有很多功能</button>
  </body>
</html>
<script type="text/javascript">
  /*
        事件绑定:给一个元素添加多个相同的事件
    */
  var op = document.querySelector(".tit");
  //给同一个标签添加多个点击事件 后添加的会覆盖前面的 只执行最后一个
  //op.onclick = function(){
  //console.log('我是添加的第一个点击事件')
  //}
  //op.onclick = function(){
  //console.log('我是添加的第二个点击事件')
  //}
  /*
        事件绑定语法:
            dom元素.addEventListener('事件名称',函数名称)
    */
  function f1() {
    console.log("我是a");
  }

  function f2() {
    console.log("身高b");
  }

  function f3() {
    console.log("养了c");
  }
  // 给p标签添加事件绑定
  op.addEventListener("click", f1);
  op.addEventListener("click", f2);
  op.addEventListener("mouseover", f3);
  // 移除给p标签添加的鼠标移入事件f3
  /*
        事件移除:
            removeEventListener
        语法:dom元素.removeEventListener('事件名称',要移除的函数名称)
    */
  // op.removeEventListener('mouseover',f3)

  var btn = document.querySelectorAll("button");
  // 给第一个按钮添加点击事件 点击时移除给p标签添加的鼠标移入事件
  btn[0].addEventListener("click", function () {
    op.removeEventListener("mouseover", f3);
  });

  function handleClick() {
    console.log("我点击了");
  }
  function handleOver() {
    console.log("我经过了");
  }
  function handleOut() {
    console.log("我离开了");
  }
  // 鼠标点击的时候触发handleClick
  btn[1].addEventListener("click", handleClick);
  // 鼠标经过时 触发handleOver
  btn[1].addEventListener("mouseover", handleOver);
  // 鼠标离开时 触发handleOut
  btn[1].addEventListener("mouseout", handleOut);
</script>

十四、键盘事件

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>键盘事件</title>
  </head>
  <body>
    <input type="text" name="" id="" />
  </body>
</html>
<script type="text/javascript">
  /*
        keydown:键盘按下
        keyup:键盘抬起

        keyCode:键盘码
    */
  var oInput = document.querySelector("input");
  // 给输入框添加键盘按下事件
  oInput.onkeydown = function (e) {
    console.log(e.keyCode);
    // 如果按下的是回车键
    if (e.keyCode == 13) {
      console.log("我按下回车了");
    }
  };

  // 整个文档中添加键盘按下事件
  document.onkeydown = function (e) {
    // f12 键盘值123
    if (e.keyCode == 123) {
      alert("想看代码没门");
      // 阻止默认事件
      // e.preventDefault()
      // return false 也可以阻止默认事件
      return false;
    } else if (e.keyCode == 67 && e.ctrlKey) {
      // 按下ctrl + c
      alert("想复制,没门");
      return false;
    }
  };

  // js内置函数 会把传入的字符串作为js代码进行解析执行
  // eval()
</script>

十五、轮播图1

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>轮播图1</title>
    <style type="text/css">
      * {
        padding: 0;
        margin: 0;
      }
      .box {
        width: 900px;
        height: 350px;
        margin: auto;
        background: url(图片相对路径) no-repeat center;
        background-size: 100% 100%;
        position: relative;
      }
      .dot {
        position: absolute;
        right: 0;
        bottom: 0;
      }
      .dot span {
        display: inline-block;
        width: 30px;
        height: 30px;
        margin-left: 10px;
        background-color: rgba(0, 0, 0, 0.4);
        border-radius: 15px;
        text-align: center;
        line-height: 30px;
        color: #fff;
        cursor: pointer;
      }
      .dot .active {
        background-color: orangered;
        box-shadow: 0px 0px 10px 3px #d4d0d0;
      }
      .left,
      .right {
        width: 20px;
        height: 40px;
        line-height: 40px;
        text-align: center;
        position: absolute;
        top: 50%;
        transform: translate(-50%);
        background-color: rgba(0, 0, 0, 0.5);
        color-scheme: #fff;
        font-weight: bold;
        font-size: 20px;
        cursor: pointer;
      }
      .left {
        left: 10px;
      }
      .right {
        right: -10px;
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div class="left">&lt;</div>
      <div class="right">&gt;</div>
      <div class="dot">
        <span class="active">1</span>
        <span>2</span>
        <span>3</span>
      </div>
    </div>
  </body>
</html>
<script type="text/javascript">
  /*
		轮播图实现思想:
			点击分页器显示对应的图片
			1.点击事件
			2.点击的时候实现背景图的切换
	 */
  var spans = document.querySelectorAll(".dot span");
  // 获取类名为box的div
  var odiv = document.querySelector(".box");

  function changeImg() {
    for (var i = 0; i < spans.length; i++) {
      spans[i].onclick = function () {
        console.log(this.innerText); // 获取的是每一个span的文本内容
        var currentIndex = this.innerText;
        /*
					为什么不用i?
						用for循环添加的点击事件内部的i是最后一次执行的i
						因为页面加载立刻执行for循环,循环结束后才点击的点击事件,会导致i变成最后一次点击的结果
				 */
        odiv.style["background"] = `url(images/desktop_${currentIndex}.jpg)`;
        console.log(this);
        // 先给其他项移除类名
        document.querySelector(".active").className = "";
        // 再给当前点击项添加类名
        this.classList.add("active");
      };
    }
  }
  changeImg();
  // 左侧按钮
  var left = document.querySelector(".left");
  left.onclick = function () {
    // 获取具有active类名的标签
    var spanActive = document.querySelector(".active");
    // 获取的是具有active类名的标签的上一个兄弟节点
    console.log(spanActive.previousElementSibling);
    if (spanActive.previousElementSibling != null) {
      // 为当前具有active类名的上一个兄弟节点执行点击事件
      spanActive.previousElementSibling.onclick();
    } else {
      // 当前具有active类名的标签没有上一个兄弟节点 为最后一个span执行点击事件
      // spans.length-1 最后一个兄弟节点
      spans[spans.length - 1].onclick();
    }
  };

  // 右侧按钮
  var right = document.querySelector(".right");
  right.onclick = function () {
    // 获取具有active类名的标签
    var spanActive = document.querySelector(".active");
    // 获取的是具有active类名的标签的下一个兄弟节点
    console.log(spanActive.nextElementSibling);
    if (spanActive.nextElementSibling != null) {
      // 为当前具有active类名的下一个兄弟节点执行点击事件
      spanActive.nextElementSibling.onclick();
    } else {
      // 当前具有active类名的标签没有下一个兄弟节点 为最后一个span执行点击事件
      spans[0].onclick();
    }
  };
</script>

十六、计算器

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>计算器</title>
    <style>
      * {
        padding: 0;
        margin: 0;
      }
      .clearfix::after {
        content: "";
        display: block;
        clear: both;
      }
      .box {
        margin: 50px auto;
        padding: 20px;
        width: 370px;
        height: 300px;
        background: #9dd2ea;
      }
      .clear {
        float: left;
        background: #ff9fa8;
        height: 50px;
        width: 80px;
        text-align: center;
        line-height: 50px;
        margin-left: 10px;
        box-shadow: 0 4px rgba(0, 0, 0, 0.2);
        color: #000;
        cursor: pointer;
      }
      .clear:hover {
        background: #9c89f6;
      }
      .screen {
        background: rgba(0, 0, 0, 0.2);
        height: 54px;
        line-height: 54px;
        width: 260px;
        float: left;
        margin-left: 10px;
        box-shadow: inset 0 4px 0 rgba(0, 0, 0, 0.2);
        color: #fff;
        text-align: right;
      }
      .keys span {
        float: left;
        background: #fff;
        height: 50px;
        line-height: 50px;
        width: 80px;
        text-align: center;
        margin: 10px 0 0 10px;
        box-shadow: 0 4px rgba(0, 0, 0, 0.2);
        color: #000;
        cursor: pointer;
      }
      .keys span:hover {
        background: #9c89f6;
      }
      .keys .oper {
        background: #e5c0c4;
      }
      .keys .eval {
        background: #f1ff92;
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div class="clearfix">
        <span class="clear">c</span>
        <div class="screen"></div>
      </div>
      <div class="keys">
        <span>7</span>
        <span>8</span>
        <span>9</span>
        <span class="oper">+</span>
        <span>4</span>
        <span>5</span>
        <span>6</span>
        <span class="oper">-</span>
        <span>1</span>
        <span>2</span>
        <span>3</span>
        <span class="oper">*</span>
        <span>0</span>
        <span>.</span>
        <span class="eval">=</span>
        <span class="oper">/</span>
      </div>
    </div>
  </body>
</html>
<script type="text/javascript">
  // 获取屏幕
  var ipt = document.querySelector(".screen");
  // 获取所有的点击按钮
  var keys = document.querySelectorAll("span");
  // 遍历循环所有的按钮
  for (var i = 0; i < keys.length; i++) {
    // 给每一个按钮添加点击事件
    keys[i].onclick = function () {
      // 获取当前点击按钮的文字内容
      console.log(this.innerText);
      // 当我点击清除的时候
      if (this.innerText == "c") {
        ipt.innerText = "";
      }
      // 当我点击的是=时
      else if (this.innerText == "=") {
        // eval() 会将传入的字符串作为js代码进行解析
        ipt.innerText = eval(ipt.innerText);
      }
      // 其他情况
      else {
        // 将点击的按钮的值输出到屏幕上
        ipt.innerText += this.innerText;
      }
    };
  }
</script>

十七、事件对象

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>事件对象</title>
    <style>
      * {
        padding: 0;
        margin: 0;
      }
      .container {
        background-color: #ccc;
        margin: 0;
        padding: 0;
        height: 3000px;
        padding-top: 100px;
      }
      .main {
        width: 500px;
        height: 330px;
        background-color: #eee;
        margin: auto;
        position: relative;
      }
      .box {
        position: absolute;
        top: 80px;
        left: 80px;
        width: 220px;
        height: 180px;
        background-color: orange;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="main">
        <div class="box"></div>
      </div>
    </div>
  </body>
</html>
<script type="text/javascript">
  /*
        事件对象:是在事件触发时,由浏览器创建的对象,它包含了与事件相关的信息,以便在事件处理程序中对事件进行处理。
    */
  var box = document.querySelector(".box");
  box.onclick = function (event) {
    // 兼容
    var e = event || window.event;
    // 1.clientX clientY 鼠标点击的位置在浏览器可视区的坐标 以可视区左上角为坐标原点
    console.log(e.clientX, e.clientY, "点击位置在可视区的坐标");
    // 2.pageX pageY 鼠标点击的位置对弈整个页面来说(包括滚动条)的坐标 以页面左上角为原点
    console.log(e.pageX, e.pageY, "点击位置相对整个页面来说的坐标");
    // 3.screenX screenY 鼠标当前点击的位置距离电脑屏幕的距离 以电脑屏幕的左上角为坐标原点
    console.log(e.screenX, e.screenY, "当前点击位置在电脑屏幕的坐标");
    // 4.offsetX offsetY 鼠标点击位置在触发事件的元素内的坐标值,即相对于触发事件的元素左/上边缘的距离
    console.log(e.offsetX, e.offsetY, "点击位置在当前元素内的坐标");
  };
</script>

十八、offset

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>offset</title>
    <style>
      * {
        padding: 0;
        margin: 0;
      }
      .main {
        width: 300px;
        height: 300px;
        background-color: rgb(240, 102, 171);
        margin: 30px;
        padding: 60px;
        border: 20px solid rgb(53, 225, 217);
        /* position: relative;
            top: 30px;
            left: 20px; */
      }
      .item {
        width: 100px;
        height: 120px;
        background-color: orange;
        margin: 20px;
        border: 2px solid red;
        padding: 10px;
      }
    </style>
  </head>
  <body>
    <div class="main">
      <div class="item"></div>
    </div>
    <button>获取</button>
  </body>
</html>
<script>
  /*
        offset 是一个用于获取元素位置和尺寸相关信息的属性
        它包含了以下几个常用的子属性:
            offsetLeft:获取一个元素相对于其最近的具有定位的父元素左侧边缘的距离
            offsetTop:获取一个元素相对于其最近的具有定位的父元素顶部边缘的距离
            offsetWidth:获取一个元素的宽度,包括其内容区域,内边距和边框
            offsetHeight:获取一个元素的高度,包括其内容区域,内边距和边框
    */
  var btn = document.querySelector("button");
  var item = document.querySelector(".item");
  btn.onclick = function () {
    console.log(item.offsetWidth, "盒子的宽度"); // 100+10+10+2+2=124
    console.log(item.offsetHeight, "盒子的高度"); // 120+10+10+2+2=144
    /*
            在祖辈元素有定位的情况下,offset是当前元素距离定位元素的距离
            当前元素的margin+定位元素的内边距
        */
    //    console.log(item.offsetLeft,'左') // 20+60=80
    //    console.log(item.offsetTop,'上') // 20+60=80
    /*
            在祖辈元素没有定位的情况下,offset是当前元素距离浏览器边缘的距离
       */
    console.log(item.offsetLeft, "左"); // 20+60+20+30=130
    console.log(item.offsetTop, "上"); //
  };
</script>

十九、拖拽

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>拖拽</title>
    <style>
      div {
        width: 100px;
        height: 100px;
        background-color: red;
        position: absolute;
        left: 55px;
        top: 50px;
      }
    </style>
  </head>
  <body>
    <div></div>
  </body>
</html>
<script>
  /*
        拖拽三个事件:
            鼠标按下:
                onmousedown
            鼠标移动:
                onmousemove
            鼠标抬起:
                onmouseup
    */
  var oDiv = document.querySelector("div");
  // 鼠标按下触发
  oDiv.onmousedown = function (event) {
    // 鼠标按下的位置在浏览器的坐标
    console.log(event.clientX, event.clientY, "鼠标在当前可视区的位置");
    // 鼠标按下的时div在页面的距离
    console.log(oDiv.offsetLeft, oDiv.offsetTop, "鼠标按下时div在页面的距离");
    // var x = event.clientX - oDiv.offsetLeft
    // var y = event.clientY - oDiv.offsetTop
    var x = event.offsetX;
    var y = event.offsetY;
    // 鼠标移动
    document.onmousemove = function (e) {
      oDiv.style.left = e.clientX - x + "px";
      oDiv.style.top = e.clientY - y + "px";
    };
  };
  // 鼠标抬起的事件
  oDiv.onmouseup = function () {
    // 鼠标抬起时清空移动事件
    document.onmousemove = null;
  };
</script>

二十、拖拽限制

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>拖拽限制</title>
    <style>
      div {
        width: 100px;
        height: 100px;
        background-color: red;
        position: absolute;
        left: 55px;
        top: 50px;
      }
    </style>
  </head>
  <body>
    <div></div>
  </body>
</html>
<script>
  /*
        拖拽三个事件:
            鼠标按下:
                onmousedown
            鼠标移动:
                onmousemove
            鼠标抬起:
                onmouseup
    */
  var oDiv = document.querySelector("div");
  // 鼠标按下触发
  oDiv.onmousedown = function (event) {
    // 鼠标按下的位置在浏览器的坐标
    console.log(event.clientX, event.clientY, "鼠标在当前可视区的位置");
    // 鼠标按下的时div在页面的距离
    console.log(oDiv.offsetLeft, oDiv.offsetTop, "鼠标按下时div在页面的距离");
    var offsetX = event.clientX - oDiv.offsetLeft;
    var offsetY = event.clientY - oDiv.offsetTop;
    // var x = event.offsetX
    // var y = event.offsetY
    // 鼠标移动
    document.onmousemove = function (e) {
      // oDiv.style.left = e.clientX - offsetX +'px'
      // oDiv.style.top = e.clientY - offsetY + 'px'
      var left = e.clientX - offsetX;
      var top = e.clientY - offsetY;

      if (left <= 0) {
        left = 0;
      }
      // 如果left > 浏览器可视宽度 - 盒子本身的宽度
      else if (left > document.documentElement.clientWidth - oDiv.offsetWidth) {
        left = document.documentElement.clientWidth - oDiv.offsetWidth;
      }

      if (top <= 0) {
        top = 0;
      } else if (
        top >
        document.documentElement.clientHeight - oDiv.offsetHeight
      ) {
        top = document.documentElement.clientHeight - oDiv.offsetHeight;
      }

      oDiv.style.left = left + "px";
      oDiv.style.top = top + "px";
    };
  };
  // 鼠标抬起的事件
  oDiv.onmouseup = function () {
    // 鼠标抬起时清空移动事件
    document.onmousemove = null;
  };
</script>

二十一、鼠标跟随提示框

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>鼠标提示框</title>
    <style>
      a {
        display: block;
        font-size: 40px;
        margin: 100px;
        width: 130px;
        background-color: pink;
      }
      .msg {
        width: 600px;
        height: 150px;
        background: gray;
        color: #fff;
        position: absolute;
        display: none;
      }
    </style>
  </head>
  <body>
    <a href="">星期一</a>
    <a href="">星期二</a>
    <a href="">星期三</a>
    <div class="msg"></div>
  </body>
</html>
<script>
  /*
        当鼠标指向的时候显示
        当鼠标离开的时候隐藏
        当鼠标移动的时候让提示框跟随

        1.鼠标移入的时候,我要知道移入的是哪一个,获取当前的下标
        2.在数组中,通过获取的下标将数据取出来,赋值给提示框
        3.鼠标离开的时候隐藏提示框
        4.鼠标移动的时候让提示框跟随
    */
  var arr = ["星期一,晴天", "星期二,多云", "星期三,下雨"];
  var oAs = document.querySelectorAll("a");
  var oMsg = document.querySelector(".msg");
  for (var i = 0; i < oAs.length; i++) {
    /*
        用for循环添加的点击事件,在事件内部不允许使用i
        因为var声明的i会被提升成全局变量,页面加载出来的一瞬间,for循环已经执行完了,i就是最后一次的结果,所以在事件内部使用的时候拿到的i是最后一次的结果
        如果想要使用的话,那就为添加事件的节点添加一个自定义属性
    */
    //给每一个a标签添加一个自定义属性
    oAs[i].setAttribute("index", i);
    // 当鼠标指向的时候 让提示框显示 并且把对应的数据渲染进去
    oAs[i].onmouseover = function () {
      // 获取每一项的自定义属性
      console.log(this.getAttribute("index"));
      // 把对应的数据渲染到提示框中
      oMsg.innerText = arr[this.getAttribute("index")];
      // 让提示框显示
      oMsg.style.display = "block";
    };
    // 当鼠标离开的时候 隐藏提示框
    oAs[i].onmouseout = function () {
      oMsg.style.display = "none";
    };
    // 当鼠标移动的时候 让提示框跟随鼠标移动
    oAs[i].onmousemove = function (e) {
      oMsg.style.top = e.clientY + 30 + "px";
    };
  }
</script>

二十二、模态框

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>模态框</title>
    <style type="text/css">
      body {
        height: 2000px;
      }
      .btn {
        width: 200px;
        height: 200px;
      }
      .box {
        width: 100%;
        height: 100%;
        position: fixed;
        left: 0;
        top: 0;
        background: rgba(0, 0, 0, 0.5);
        opacity: 0;
        z-index: -1;
        transition: all 0.5s;
      }
      .box-matter {
        width: 500px;
        height: 400px;
        background: #fff;
        border-radius: 5px;
        margin: 100px auto;
        transform: scale(0);
        transition: all 0.5s;
      }
      .box-matter img {
        width: 100%;
        height: 100%;
      }
      .box-header {
        text-align: center;
        padding: 8px;
        position: relative;
      }
      .close {
        position: absolute;
        font-size: 30px;
        font-weight: bold;
        right: 10px;
        top: 0;
        cursor: pointer;
      }
    </style>
  </head>
  <body>
    <img src="图片相对路径" alt="" class="btn" />
    <img src="图片相对路径" alt="" class="btn" />
    <div class="box">
      <div class="box-matter">
        <div class="box-header">
          <h3>友情提示</h3>
          <span class="close">X</span>
        </div>
        <img src="" alt="" />
      </div>
    </div>
  </body>
</html>
<script type="text/javascript">
  // 获取小图按钮
  var btn = document.querySelectorAll(".btn");
  // 获取box
  var box = document.querySelector(".box");
  // 获取弹窗
  var box_matter = document.querySelector(".box-matter");
  // 获取弹窗内的大图
  var bigImg = document.querySelector(".box-matter img");
  // 获取关闭按钮
  var close = document.querySelector(".close");
  for (var i = 0; i < btn.length; i++) {
    btn[i].onclick = function () {
      console.log(this);
      // 当我点击时 让模态框显示 模态框里的大图是我当前点击的小图
      box.style.opacity = "1";
      // 让模态框显示 并且层级最高在页面最上方
      box.style.zIndex = "3";
      box_matter.style.transform = "scale(1)";
      bigImg.src = this.src;
    };
  }
  close.onclick = function () {
    box.style.opacity = "0";
    box.style.zIndex = "-1";
    box_matter.style.transform = "scale(0)";
  };
</script>

二十三、移入事件

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>移入事件</title>
    <style type="text/css">
      .box1 {
        width: 300px;
        height: 300px;
        background: #eee;
      }
      .box2 {
        width: 100px;
        height: 100px;
        background-color: orange;
      }
    </style>
  </head>
  <body>
    <div class="box1">
      <div class="box2"></div>
    </div>
  </body>
</html>
<script type="text/javascript">
  /*
        mouseover 和 mouseenter 区别
            mouseover:鼠标指向的时候触发,会产生事件冒泡
            mouseenter:鼠标指向的时候触发,不会产生事件冒泡
    */
  var box1 = document.querySelector(".box1");
  var box2 = document.querySelector(".box2");
  box1.onmouseenter = function () {
    console.log("我是父元素");
  };
  box2.onmouseenter = function () {
    console.log("我是子元素");
  };
</script>

二十四、笔记

js事件是指发生在html元素上的事情 也可以把事件理解成行为

能用css实现的效果,就不用js

点击事件:
dom元素.onclick = funciton(){
    执行的代码
    谁调用这个方法 this就指向谁
}

事件类型:
    一、鼠标事件
        onclick     单击事件
        ondbclick   双击事件
        onmouseover 鼠标移入事件
        onmouseout  鼠标移除事件
        onmousedown 鼠标按下
        onmouseup   鼠标抬起
        onmousemove 鼠标移动
    
    二、键盘事件
        onkeydown       键盘按下的时候
        onkeyup         键盘抬起的时候
    
    三、window事件
        onload      页面加载的时候
        onresize    窗口发生改变的时候
        onscroll    页面滚动的时候

    四、表单事件
        onblur      失去焦点的时候
        onfocus     获取焦点的时候
        onselect    选中文本的时候
        onchange    输入框内容发生变化,并且失去焦点的时候
        oninput     引入的框中用户输入内容的时候


事件冒泡:
    当前节点拥有一个点击事件,父级也有一个点击事件,当我点击当前节点的时候,同时也会触发父级的点击事件,体验不好

阻止事件冒泡的方法:
    e.stopPropagation9
阻止默认行为:
    e.preventDefault()


事件委托的好处
    在js中dom操作是不可避免的,如果一个元素有100个甚至上千个不同的子元素,然后,每一个子元素都要添加点击事件,按照以往的写法,需要获取每一个元素,需要获取到的每一个元素,给每一个元素都添加点击事件,首先从代码数量上,首先从代码量上,代码过于臃肿,其次,频繁地获取添加事件,会对浏览器的性能产生影响,导致页面速度变慢。


事件绑定:可以绑定多个相同的事件
    dom元素.addEventListener('事件名称,'函数名称)'
    dom元素.addEventListener('事件名称',funciton(){

    })

事件移除:
    dom元素.removeEventListener('事件名称',要移除的函数名称)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪花酥01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值