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

她的代码是这样写的:

 <!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. echarts3.0 实例容器不实时更新页面的问题

    var instanceId = document.getElementById(option.echartId).getAttribute('_echarts3_instance_'); if (i ...

  2. 免打包:简单、灵活、便捷的APP渠道统计方法

    相信做过APP运营推广的小伙伴们应该对APP渠道统计并不陌生吧.APP推广运营人员需要根据数据来评估渠道推广的效果,找到最适合自家APP的渠道,有针对性的投放,不断完善推广策略,这样才能更加精准.有效 ...

  3. 3、CreateJS介绍-SoundJS

    需要在html5文件中引入的CreateJS库文件是soundjs-0.5.2.min.js HTML5文件如下: <!DOCTYPE html> <html lang=" ...

  4. codeforces540E-树状数组求逆序对

    1-1e9的数据范围 但有1e5个区间 所以可以考虑把没有涉及到的区间缩成一个点 然后树状数组求逆序对 #include<bits/stdc++.h> #define inf 0x3f3f ...

  5. C# 序列化与反序列化json

    与合作伙伴讨论问题,说到的c++与c#数据的转换调用,正好就说到了序列化与反序列化,同样也可用于不同语言间的调用,做了基础示例,作以下整理: using System.Data; using Syst ...

  6. Java 数字数组随机数工具类 NumberUtils、ArrayUtils、RandomUtils用法

    commons-lang3-3-3.8.1 //----------------------------------------------------------------------- /** ...

  7. idea远程debug:tomcat

    在tomcat的bin/startup.sh中添加: 27780debug的端口 declare -x CATALINA_OPTS="-server -Xdebug -Xnoagent -D ...

  8. 使用javaMail发送简单邮件

    参考网页:http://blog.csdn.net/xietansheng/article/details/51673073package com.bfd.ftp.utils; import java ...

  9. java中循环的不同终止方式

    1.break:直接强行跳出当前循环,不再执行剩余代码.但在多重循环的情况下,若break在内层循环中,则仅仅终止了内层循环,外循环照常执行. 2.continue:仅仅终止此次循环. 3.retur ...

  10. 就来推荐一本2018年研究的Web书《移动Web前端高效开发实战》

    一线互联网公司Web前端团队实战经验总结,涵盖移动Web前端开发各个关键技术环节,包括移动开发核心技术.常用布局方案.MV*类新时代框架.预编译技术.性能优化.开发调试.混合式应用.单元测试.工程化等