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

她的代码是这样写的:

 <!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. 使用CCProxy代理遇到的问题

    第一种:打开CCProxy后,客户端电脑无法连接上. 解决方案:主机是否开启了360里面的局域网隐藏,这个一定要关闭,否则客户端无法找到主机.另外一种情况,主机关闭局域网隐藏之后,一直遭受ARP攻击, ...

  2. 【面试】迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)

    常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HTTP接口拿到详情数据,然后使用适合的视图展示详情数据. 如果网速很慢,代码发起一个HTTP请求后,就卡住不动了,直到十几秒后才拿到HTT ...

  3. 一个线性表中的元素为整数,设计一个算法,将正整数和负整数分开,使线性表的前一半为负整数,后一半为正整数。(C语言)

    以下为完整可运行示例代码: #include <stdio.h> #include <stdlib.h> typedef struct LNode{ int data; str ...

  4. CCPC吉林站

    A.The Fool #include <bits/stdc++.h> using namespace std; inline int read() { ,f=;char ch=getch ...

  5. swift 广告轮播图

    import UIKit import Kingfisher class BannerView: UIView,UIScrollViewDelegate{ enum ImageType{ case I ...

  6. High waits on control file sequential read

    High waits on control file sequential read (文档 ID 2277867.1) In case we run into an issue where cont ...

  7. Linux清空屏幕和清空当前输入的快捷键

    Linux清空屏幕和清空当前输入的快捷键 但是实际上...放弃当前的命令,命令行提示符跳到下一行的有效命令是ctrl + c

  8. Uncaught Error: Bootstrap's JavaScript requires jQuery

    在写bootstarp的时候,一直报 Uncaught Error: Bootstrap's JavaScript requires jQuery 查看了自己引入的文件路径是对的,也可以使用jquer ...

  9. go实现set

    package main import ( "fmt" "sync" ) type object interface{} type Set struct { m ...

  10. Android 网络提交数据(使用Asynchronous Http Client)

    项目主页及简单使用方法http://loopj.com/android-async-http/ 页面布局就不复制了,把主要的Activity记录下来,供自己以后使用: package com.exam ...