今天在群里看见一个人在问"点击按钮使图片产生旋转为什么要使用计时器来实现",我自己操作了一遍她的代码才发现里面的逻辑实现很有意思,所以写出来分享一下。

她的代码是这样写的:

 <!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<style>
#myImg {
width: 60%;
}
.myShow {
animation: rotate 1s;
}
@keyframes rotate {
ftom {transform: rotate(0deg);}
to {transform: rotate(180deg);}
}
</style>
</head>
<body>
<div>
<img
id='myImg'
src='http://www.8090.com/uploads/allimg/141204/3-141204134GJ95.jpg'
/>
<p id='demo'></p>
<button onclick='myBtn()'>click</button>
</div>
<script>
function myBtn() {
var rotate = document.getElementById('myImg');
var myAttr = function(){
rotate.setAttribute('class','myShow');
}
setTimeout(myAttr,30);
rotate.setAttribute('class','');
} </script>
</body>
</html>

在这里,通过点击按钮触发myBtn函数,先执行计时器setTimeout, 调用myAttr函数添加了class属性'myShow',再移除了这个class属性。和‘myShow'绑定了rotate这个CSS动画,从而实现图片旋转。

回到她的问题:"为什么要使用计时器来实现图片旋转?"

按照她的想法,不使用计时器,只要再次点击按钮,不一样会产生click事件么,那计时器有什么用?

下面去掉计时器,直接使用setAttribute属性看看是否可以达到同样效果。js代码如下:

 <script>
function myBtn() {
var rotate = document.getElementById('myImg');
// var myAttr = function(){
// rotate.setAttribute('class','myShow');
// console.log('hello')
// }
rotate.setAttribute('class','myShow');
// setTimeout(myAttr,30);
rotate.setAttribute('class','');
} </script>

然而,点击按钮没有产生任何反应。原因是因为js的运行逻辑是至上而下的顺序,当我们点击按钮后,myBtn函数从上而下执行,执行完后class属性已被删除,就不会对HTML产生DOM效果。

那同样在前面的代码里,js函数的最后一行也是rotate.setAttribute('class',''),为什么可以正常产生DOM效果?

通过加入console.log后,我发现计时器的原理是它改变了函数的运行顺序。

通过添加计时器,函数的执行顺序变成了:’执行setTimeout方法' => ‘删除class属性' => (30毫秒后)'添加class属性'。因为函数的运行结果是添加class属性,所以保留了class='myShow',从而引用了CSS动画效果。

 <script>
function myBtn() {
var rotate = document.getElementById('myImg');
var myAttr = function(){
rotate.setAttribute('class','myShow'); //设置class属性值为myShow
console.log(document.getElementById('myImg').className)
}
setTimeout(myAttr,30);
rotate.setAttribute('class','None'); //设置class属性值为None
console.log(document.getElementById('myImg').className)
} </script>

执行页面后,发现console.log打印结果先是'None',再是'myShow',说明了每次点击按钮都是先"删除"class属性,在添加class属性。这样每次className都是被保留了下来,而再次点击按钮,则又先删掉了class属性,以此类推。

20181111 计时器影响DOM点击事件的逻辑的更多相关文章

  1. 动态生成的DOM做点击事件无效

    有时候我们的标签都是从后台获取的数据,然后利用JS添加到页面上,当我们写生成的标签的点击事件(click)时没有效果. 例如: <section> 测试动态生成的DOM点击事件 <b ...

  2. 为dom添加点击事件,由此引发this指向的思考

    下午没有任务,闲来无事仿个小网页巩固下基础知识.由于公司安全规定,原网页截图不便上传(也没法上传),回家后做了个简单的菜单以图示: 目标:点击某选项时,该选项底边加粗 1.首先定义click方法,然后 ...

  3. position布局影响点击事件以及冒泡获取事件目标

    在编写功能时总是会出现很多意想不到的问题,现在就讲讲我遇到的两个问题,通过举一个相似的例子来解说. <1> 元素互相独立,不存在包含于被包含 选择城市的按钮,为它绑定点击事件,点击后就弹出 ...

  4. javascript总结35:DOM之给a注册点击事件, 阻止a标签的默认行为

    给a注册点击事件时,有默认行为,阻止默认行为的方式: retrun false <!DOCTYPE html> <html lang="zh-CN"> &l ...

  5. React 的 DOM 添加多个点击事件

    第一直觉代码如下:后果是写在后面的事件函数覆盖前面的事件函数,只执行第二条(弹出 222). import React, { Component, Fragment } from 'react' ex ...

  6. [前端][自定义DOM事件]不使用setTimeout实现双击事件或n击事件

    使用setTimeout实现双击事件 例如,这样: let div = document.getElementById("div"); doubleClick(div, funct ...

  7. fastclick.js解决移动端(ipad)点击事件反应慢问题

    参考http://blog.csdn.net/xjun0812/article/details/64919063 http://www.jianshu.com/p/16d3e4f9b2a9 问题的发现 ...

  8. angularJs 多文件动态上传(删除其中一个文件的时候,要么file没被删除,要么删除了之后,点击事件失效)

    <div cacModule.controller('CacScriptEditCtrl', CacScriptEditCtrl); CacScriptEditCtrl.$inject = [' ...

  9. tips 前端 点击事件

    新手总是时不时会纠结一下 点击事件 我们都知道这些小东西不难 但是偶尔难道不会想想我们可能对这些即使小kiss的问题的认知其实不够清晰 一个认识不清晰的东西使用时 总会有油然而生的不安感 从而用的不放 ...

随机推荐

  1. Vue多环境配置

    Vue多环境配置 大家都知道,使用vue-cli脚手架生成的Vue项目只有开发环境和生产环境,然而在实际开发中,用到的不止这些环境,还包括测试环境,准生产环境等等.所以需要自己添加没有的环境. 以测试 ...

  2. 制作windows启动盘

    ·首先:不要使用“老毛桃,大白菜,u深度,电脑店,u大师”等工具,国产流氓软件了解下. ·工具:UltraISO (自行下载)环境:Windows ·Windows 7微软原版无修改的系统镜像下载地址 ...

  3. 《SQL 进阶教程》 case:在 UPDATE 语句里进行条件分支

    1.对当前工资为30万日元以上的员工,降薪10%:2.对当前工资为25万日元以上且不满28万日元的员工,加薪20% update salaries set salary = case when sal ...

  4. NSPhotoLibraryAddUsageDescription解决办法

    图片并保存到本地的功能,一点发现闪退了.发现 Xcode 报以下错误: The app's Info.plist must contain an NSPhotoLibraryAddUsageDescr ...

  5. Mac OS X

    Mac OS X 除了微软自家的Windows平台, .NET Core针对Mac OS以及各种Linux(RHEL.Ubuntu.Debian.Fedora.CentOS和SUSE等)都提供了很好的 ...

  6. Spring创建对象的几种方法

    一.通过构造器 无参构造器 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=" ...

  7. SpringMVC对HTTP报文体的处理

     客户端和服务端HTTP报文传递消息,而HTTP报文包含报文头和报文体.通常,解析请求参数以及返回页面都不需要我们关心HTTP报文体的读取和生成过程.但在某些特定场景下需要直接到请求报文中读取报文体, ...

  8. P3818 小A和uim之大逃离 II

    题目背景 话说上回……还是参见 https://www.luogu.org/problem/show?pid=1373 吧 小a和uim再次来到雨林中探险.突然一阵南风吹来,一片乌云从南部天边急涌过来 ...

  9. AJPFX浅析Java数组

    数组(array)是相同类型变量的集合,可以使用共同的名字引用它.数组可被定义为任何类型,可以是一维或多维.数组中的一个特别要素是通过下标来访问它.数组提供了一种将有联系的信息分组的便利方法.注意:如 ...

  10. this的那点事

    对于很多初学者,this总是搞得我们晕头转向. 现在,我就简单的总结一下关于this的那点事. this在函数定义时经常是不能确定的,只有在函数执行的时候才能最终确定this的归属.this总是指向最 ...