impress.js进修

引子

   断断续续用了好几天,终究把 impress.js 源码看完,作为刚入门的前端菜鸟,这是我第一次看 js 源码,最初照样比较痛楚的。不过还好,impress.js源码的解释相称清晰,每一个函数和事宜的作用都写得很细致,这让源码读起来更轻易邃晓,此处手动给大神送糖果~~~

   接下来就由我给人人分享下 impress.js 效果是怎样完成的、以及我们怎样利用它来完成殊效。

impress.js的完成

我们在用 impress.js完成殊效时,会用到相似下面的代码:

<div id="its" class="step" data-x="900" data-y="3000" data-rotate="90" data-scale="4">

我们看到代码中有data-x,data-y等属性,实际上我们就是经由过程转变这些属性的值来完成PPT的跳转的。这些属性离别代表:

  • data-x:幻灯片的X坐标

  • data-y:幻灯片的Y坐标

  • data-scale:幻灯片显现的缩放比例

  • data-rotate:幻灯片扭转的度数

  • data-rotate-x:3D运用,设置它相对X轴扭转多少度

  • data-rotate-y:3D运用,设置它相对Y轴扭转多少度

  • data-rotate-z:3D运用,设置它性对Z轴扭转多少度
    我们来看看impress源码中的 rotate函数:

//'rotate'对给定数据组织扭转变更
//默许扭转递次为X,Y,Z,能够将参数设定为true来倒转递次
var rotate = function( r, revert ) {
 var rX = " rotateX(" + r.x + "deg) ",
 rY = " rotateY(" + r.y + "deg) ",
 rZ = " rotateZ(" + r.z + "deg) ";
return revert ? rZ + rY + rX : rX + rY + rZ;
 };​

rotate函数的作用是将rotate对象转换成css运用的字符串。
用户自定义的数据经由过程data属性读取,并初始化给step对象。对应源码以下

:var data = el.dataset,
 step = {
 translate: {//对给定数据组织平移变更
 x: toNumber( data.x ),
 y: toNumber( data.y ),
 z: toNumber( data.z )
 },
 rotate: {//对给定数据组织扭转变更
 x: toNumber( data.rotateX ),
 y: toNumber( data.rotateY ),
 z: toNumber( data.rotateZ || data.rotate )
 },
 scale: toNumber( data.scale, 1 ),//对给定数据组织缩放变更
 el: el
 };​     

我们在编写HTML时,经由过程转变data的属性值完成页面切换,那末在源码中,又是怎样来完成的呢?
在impress.js源码中,重要经由过程三个事宜来完成impress的运转,它们离别是impress:init,impress:stepenter和impress:stepleave,在相识这些事宜之前,先邃晓 step 这个观点,一个step就相称于PPT中的一页,每切换一页就相称于切换一个step。每一次切换都邑触发上面所提到的两个事宜:impress:stepenter和impress:stepleave,从而到达页面跳转的效果。

我们在运用 impress.js的时刻,须要挪用impress.js中的impress().init()函数:`

<script type="text/javascript">impress().init();</script>

init() 函数是 impress 的主初始化函数,它的作用是初始化 impress API ,从而运转impress。在 init() 函数的末端触发 impress:init事宜,如许绑定上去的函数就会悉数触发了。以下代码等于触发 impress:init事宜:

triggerEvent( root, "impress:init", { api: roots[ "impress-root-" + rootId ] } );
 };       

Triggerevent()要领:触发指定对象的指定事宜,而且马上实行该事宜中的剧本。
Triggerevent组织一个事宜,该事宜以 ‘eventnam’定名,用detail处置惩罚数据,并在el上实行。源码以下:

var triggerEvent = function( el, eventName, detail ) {
 var event = document.createEvent( "CustomEvent" );
 event.initCustomEvent( eventName, true, true, detail );
 el.dispatchEvent( event );
 };​

接下来我们看看 impress:init事宜上绑定了哪些函数:
(1)为step增加一些有效的类:

root.addEventListener( "impress:init", function() {
// STEP CLASSES
 steps.forEach( function( step ) {
 step.classList.add( "future" );//一切还没有展现的 steps 都增加到都增加 `future` 类
 } );
root.addEventListener( "impress:stepenter", function( event ) {
 event.target.classList.remove( "past" );
 event.target.classList.remove( "future" );
 event.target.classList.add( "present" ); // 当某个step 被展现,`future`类会被移除,并被增加上 `present`类
 }, false );
root.addEventListener( "impress:stepleave", function( event ) {
 event.target.classList.remove( "present" );
 event.target.classList.add( "past" );//当某个step完毕时, `present` 又会被替换成`past`类
 }, false );
}, false );​ 

经由过程上面的要领,每一个 step 都邑处于 future, presentpast三个状况中的一个,如许使得我们在切换PPT的时刻能够前后恣意切换。
上面代码顶用到了addEventListener() 要领,该要领用于向指定元素增加事宜句柄。语法以下:element.addEventListener(event,function,useCapture);
参数 event:必须,指定事宜名,不要运用”on”前缀;
function:指定事宜要触发时实行的函数;
useCapture:可选(布尔值),指定事宜是不是在捕捉或许冒泡时实行。
可运用 removeEventListener() 要领来移除 addEventListener() 要领增加的事宜句柄。

(2)增加hash变化支撑:

root.addEventListener("impress:init", function(){
 
  var lastHash = "";  // 将lasthash清空
 // `#step-id`将被替换成`#/step-id`以防备浏览器在默许状况下转动至hash表中所保留元素所在位置
 //
 // 而且增加hash的操纵必须在动画完毕今后举行, 由于在Chrome里会致使动画耽误
 // BUG: http://code.google.com/p/chromium/issues/detail?id=62820
 root.addEventListener("impress:stepenter", function (event) {
 window.location.hash = lastHash = "#/" + event.target.id;
 }, false);
 
 window.addEventListener("hashchange", function () {
 // 当某一step被展现时,location里的hash已更新(就在上面几行)
 // 所以hash change事宜被触发,我们将在统一step上再一次挪用`goto`要领。
 // 为了防止这一状况,我们将存储上一次 hash 的效果并比较.
 if (window.location.hash !== lastHash) {
 goto( getElementFromHash() );
 }
 }, false);
 
 // 最先
 // 挑选记录在url中的step地点,或许演示文稿的第一张step
 goto(getElementFromHash() || steps[0], 0);
 }, false);​

window.location.hash: hash 属性是一个可读可写的字符串,该字符串是 URL 的锚部份(从 # 号最先的部份)。
location.hash能够用来猎取或设置页面的标签值。
经由过程 window.location.hash=hash这个语句来调解地点栏的地点,使得浏览器里边的“行进”、“退却”按钮能一般运用。

(3)导航事宜
键盘处置惩罚导航:
按键被按下时:

// 防备不允许被按下的键被不测按下
 document.addEventListener("keydown", function ( event ) {
 if ( event.keyCode === 9 || ( event.keyCode >= 32 && event.keyCode <= 34 ) || (event.keyCode >= 37 && event.keyCode <= 40) ) {
 event.preventDefault();
 }
 }, false);​

preventDefault() 要领阻挠元素发作默许的行动。

按键弹起时,触发impress行动(下一张或上一张):

    document.addEventListener("keyup", function ( event ) {
     if ( event.keyCode === 9 || ( event.keyCode >= 32 && event.keyCode <= 34 ) || (event.keyCode >= 37 && event.keyCode <= 40) ) {
     switch( event.keyCode ) {
     case 33: // 上翻页
     case 37: // 小键盘左
     case 38: // 小键盘上
     api.prev();
     break;
     case 9: // tab键
     case 32: // 空格
     case 34: // 下翻页
     case 39: // 小键盘右
     case 40: // 小键盘下
     api.next();
     break;
     }
     
     event.preventDefault();
     }
     }, false);​
 处置惩罚在当前演示 steps 上发生的单击事宜(当前step上是不是存在超链接):

document.addEventListener("click", function ( event ) {
     // 事宜冒泡处置惩罚
     // 搜检单击的目的(及其先人级容器)是不是是超链接
     var target = event.target;
     while ( (target.tagName !== "A") &&
     (target !== document.documentElement) ) {
     target = target.parentNode;
     }
     
     if ( target.tagName === "A" ) {
     var href = target.getAttribute("href");
     
     // 假如指向某一衔接,跳转至这一衔接
     if ( href && href[0] === '#' ) {
     target = document.getElementById( href.slice(1) );
     }
     }
     
     if ( api.goto(target) ) {
     event.stopImmediatePropagation();//假如目的对象件被实行,将阻挠剩下事宜实行
     event.preventDefault();
     }
     }, false);​
event.stopImmediatePropagation() 要领阻挠剩下的事宜处置惩罚顺序被实行,该要领阻挠事宜在 DOM 树中向上冒泡。
处置惩罚在当前演示 steps 上发生的单击事宜:

    document.addEventListener("click", function ( event ) {
     var target = event.target;
     // 查找距当前活泼step近来的不活泼step
     while ( !(target.classList.contains("step") && !target.classList.contains("active")) &&
     (target !== document.documentElement) ) {
     target = target.parentNode;
     }
     
     if ( api.goto(target) ) {
     event.preventDefault();
     }
     }, false);     
处置惩罚触摸屏上上轻击屏幕左侧或许右侧的事宜:document.addEventListener("touchstart", function ( event ) {
 if (event.touches.length === 1) {
 var x = event.touches[0].clientX,
 width = window.innerWidth * 0.3,
 result = null;
 
 if ( x < width ) {
 result = api.prev();
 } else if ( x > window.innerWidth - width ) {
 result = api.next();
 }
 
 if (result) {
 event.preventDefault();
 }
 }
 }, false);

当窗口大小转变时,从新盘算窗口大小:

window.addEventListener("resize", throttle(function () {
 // 强迫激活当前step
 api.goto( document.querySelector(".step.active"), 500 );
 }, 250), false);   

impress总共有4个API,离别是goto(), init(), next(), prev()。
impress的切换重要经由过程 goto()来完成,goto API 跳转至以el参数(索引,id或元素名)标记的step 。prev API 按文档递次跳回上一 step ,next API 按文档递次跳向下一 step 。




    原文作者:readyGo
    原文地址: https://segmentfault.com/a/1190000007317043
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞