最近一直在忙项目,很少有时间回顾之前的知识,今天刚好要做一个轮播,因为对兼容性有一定的要求,使用了各种插件和库中的轮播,效果都不是很理想,一怒之下,使用原生JS封装了一个轮播组件,其中重要的功能就是一个动画,看了一下以前封装的函数,千疮百孔,又进行了重新封装,先上代码,有详细的备注。

function animate(el, target, step, dtime) {
/**
* 参数说明:
* - el 表示操作的元素对象
* - target 表示移动的目标距离 单位 px
* - step 表示步长,即每次移动的距离 单位 px
* - dtime 表示移动的间隔时间 单位 ms
*/ // 步长和间隔时间设置了默认值
step = step || 10;
dtime = dtime || 30; // 判断是否开启定时器,如果有就清除
if (el.timeId) {
clearInterval(el.timeId);
el.timeId = null;
}; // 开启一个定时器,并将定时器挂载道当前元素上
el.timeId = setInterval(function () {
/**
* 获取盒子移动前的水平方向的位置(当前位置) - 偏移的位置
* - 可以使用 el.offsetLeft 获取,但会将外边距也获取到,不精准,不采用
* - 这里移动实现方式是改变 left的值,保持统一,还是使用 el.style.left 获取
* - 使用 el.style.left 有个弊端是,若元素对象上最初没有 left 属性时,获取返回的是 NAN
* - 这种情况只有在第一次会出现,故最开始的时候,还需要判断返回的值,若为 NAN,则重置为 0;如下
*/
var current = parseInt(el.style.left);
current = current ? current : 0; // 判断目标距离是否小于当前位置,若小于将 步长 变为 负数,让元素反着移动
if (current > target) {
step = -Math.abs(step);
} // 当目标距离与当前位置的差距小于步长时,直接当目标的水平位置设置为目标距离,并清除定时器后跳出函数
if (Math.abs(current - target) < Math.abs(step)) {
clearInterval(el.timeId);
el.style.left = target + 'px';
return;
} // 定时器每执行一次,就让元素移动一个 步长
el.style.left = current + step + 'px';
}, dtime)
}

有两个地方需要特别说明:

  1. 计时器的是直接挂载到被操作的元素对象上的 el.timeID 方便复用
  2. 获取当前水平偏移位置时,没使用 offsetLeft,因为当元素存在外边距时会产生误差,故还时使用原生获取left 的,并对不存在的问题做了判断处理。

若有不足或有更好建议的,欢迎留言交流。

使用原生JS封装一个动画函数的更多相关文章

  1. 原生JS封装简单动画效果

    原生JS封装简单动画效果 一致使用各种插件,有时候对原生JS陌生了起来,所以决定封装一个简单动画效果,熟悉JS原生代码 function animate(obj, target,num){ if(ob ...

  2. 原生Js封装的动画类

    算法用的是Tween类,需要研究的参考这篇文章: http://www.cnblogs.com/cloudgamer/archive/2009/01/06/Tween.html 网页里常用的动画 放大 ...

  3. Js封装的动画函数实现轮播图

    ---恢复内容开始--- 效果图说明:当鼠标移到哪一个按钮上的时候会自动跳转到某一张图片上,并且按钮会以高亮显示 项目目录结构 用到的js封装的animate()动画         function ...

  4. JS21. 使用原生JS封装一个公共的Alert插件(HTML5: Shadow Dom)

    效果预览 Shadow DOM Web components  的一个重要属性是封装--可以将标记结构.样式和行为隐藏起来,并与页面上的其他代码相隔离,保证不同的部分不会混在一起,可使代码更加干净.整 ...

  5. 原生JS封装时间运动函数

    /*讲时间运动之前先给大家复习一下运动函数 通常大家都会写运动框架,一个定时器(Timer),一个步长(step 就是每次运动的距离),一个当前位置(current)一个目标位置(target),然后 ...

  6. 使用原生JS封装一个ajax

    function ajax(data){ //第一步,创建XHR对象 var xhr = null; if(window.XMLHttpRequest){ xhr = new XMLHttpReque ...

  7. 原生JS封装ajax方法

    http://blog.sucaijiayuan.com/article/89 jquery框架的ajax方法固然好用,但是假如某天我们的项目不能引入jquery或项目需求很简单,没有很多交互功能,只 ...

  8. 原生JS封装创建多级菜单函数

    手写一个使用原生JS封装的多级菜单的函数,满足以下几点需求. 子类层级不确定,可根据数据自动生成多级菜单. 操作便捷,只需传入一个HTML标签. 缺点: 需要满足特定的数据结构 废话不多说,展示代码. ...

  9. 原生JS封装_new函数,实现new关键字的功能

    1.前言 众所周知:没有对象怎么办?那就new一个! 那么在JS中,当我们new一个对象的时候,这个new关键字内部都干了什么呢? 现在我们就来剖析一下原生JS中new关键字内部的工作原理. 2.原生 ...

随机推荐

  1. 使用fast-json-stringify代替JSON.stringify

    使用JSON.stringify的思考 使用过JSON对象的程序员最常做的一项工作便是,将JSON对象转化为字符串.该字符串的用途很多,例如可以使用在WEB的URL中,在多个页面间进行传递. cons ...

  2. LeetCode136 Single Number, LeetCode137 Single Number II, LeetCode260 Single Number III

    136. Single Number Given an array of integers, every element appears twice except for one. Find that ...

  3. C++程序设计教材目录思维导图(增C++Primer)

    正在做C++思维导图,大工程,比较艰苦. 先做了三个C++教材目录的思维导图.C++教材不等于C++,这个容易些.看思维导图,整理所学知识,这个可以会. 给出三张图,对应三种教材: 谭浩强. C++程 ...

  4. Asterisk 代码架构概述

    from:http://blog.csdn.net/yetyongjin/article/details/7594447 近日分析Asterisk 1.8源码.Asterisk trunk上有这篇架构 ...

  5. python 通过.pth文件修改搜索路径

  6. Leetcode812.Largest Triangle Area最大三角形面积

    给定包含多个点的集合,从其中取三个点组成三角形,返回能组成的最大三角形的面积. 示例: 输入: points = [[0,0],[0,1],[1,0],[0,2],[2,0]] 输出: 2 解释: 这 ...

  7. Myeclipse自定义注释

    1.设置模板 Windows—Preference—Java—Code Style—Code Templates 图中, Configure generated code and comments中的 ...

  8. thinkphp5.0中英文切换

    首先来看下它的配置: // 是否开启多语言 'lang_switch_on' => true, //语音列表 'lang_list' => ['zh-cn','en-us'], // 获取 ...

  9. 2019-4-10-VisualStudio-2019-尝试使用-C#-8.0-新的方式

    title author date CreateTime categories VisualStudio 2019 尝试使用 C# 8.0 新的方式 lindexi 2019-04-10 10:41: ...

  10. SaaS加速器 I 商业中心:提供商业助力 共享商业成功

    摘要: 商业中心:通过阿里商业生态(如阿里云市场.钉钉市场.淘宝市场.B2B等)帮助合作伙伴实现商业变现和闭环, 思考:今天我们一起换个视角,从平台的角度考虑如何去构建生态,如何制定平台的规则以及如何 ...