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

她的代码是这样写的:

 <!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. django中的ORM与 应用与补充

    目录 django中的ORM与 应用与补充 ORM与数据的对应关系 ORM 常用字段 ORM 其他字段 自定义字段 字段参数 Model Meta参数 常用13中查询(必会) 单表查询的双下划线应用 ...

  2. pytest框架(三)

    pytharm运行三种方式 代码示例: # coding=utf-8 import pytest class TestClass: def test_one(self): x = "this ...

  3. urllib2基础操作

    Urllib2基础操作 1.打开网页(urlopen) 打开一个网页 import urllib2 response = urllib2.urlopen('http://www.baidu.com') ...

  4. linux 02 基础命令

    linux 02 基础命令 1.alias 别名 pyvip@Vip:~/demo$ alias lh="ls -lh" #将ls -lh的功能赋给lh(lh原来并没有意义)这个赋 ...

  5. bzoj1095: [ZJOI2007]Hide 捉迷藏 动态点分治学习

    好迷啊...感觉动态点分治就是个玄学,蜜汁把树的深度缩到logn (静态)点分治大概是递归的时候分类讨论: 1.答案经过当前点,暴力(雾)算 2.答案不经过当前点,继续递归 由于原树可以长的奇形怪状( ...

  6. Codeforces Round #431 (Div. 2) B

    Connect the countless points with lines, till we reach the faraway yonder. There are n points on a c ...

  7. MySQL数据库(3)

    外键的变种(三种关系),数据的增删改,单表查询,多表查询 一.外键的变种(三种关系) 本节重点: 如何找出两张表之间的关系 表的三种关系 一.介绍 因为有foreign key的约束,使得两张表形成了 ...

  8. MySQL 实现字符串换行

    target_describe字段值中包含 :[ 这两个特殊的字符 ,想要在字符之间加换行 需要插入CHAR(10) ),'[')) UPDATE ew_pm_project_red_detail S ...

  9. P4874 回形遍历 —模拟

    思路: 写完后信心满满,结果超时. 我很不解,下了个数据结果——,z竟然是大于1e10的,跟题目给的不一样啊 原来如此,正解是一行一行的走的... 注意当到两边一样近时,应优先向下和右!!!!!! 这 ...

  10. Get和Post的初步探究

    Get请求和Post请求这两种基本请求类型,大部分开发者心里大概都有所谓的"标准答案",但博主最近用Postman测试接口的时候,遇到传参的问题:用post请求,参数放在reque ...