2017-08-27 32 views
0

我使用impress.js作为插件,我试图在不更改impress.js本身的情况下覆盖键码定义(否则在下次更新期间更改将被覆盖)在插件(impress.js)中覆盖event.keycode而不更改插件中的代码

这是键码的定义如何在impress.js实现:

// KEYBOARD NAVIGATION HANDLERS 

    // Prevent default keydown action when one of supported key is pressed. 
    document.addEventListener("keydown", function(event) { 
     if (event.keyCode === 9 || 
      (event.keyCode >= 32 && event.keyCode <= 34) || 
      (event.keyCode >= 37 && event.keyCode <= 40)) { 
      event.preventDefault(); 
     } 
    }, false); 


     if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) { 
      return; 
     } 

     if (event.keyCode === 9 || 
      (event.keyCode >= 32 && event.keyCode <= 34) || 
      (event.keyCode >= 37 && event.keyCode <= 40)) { 
      switch (event.keyCode) { 
       case 33: // Page up 
       case 37: // Left 
       case 38: // Up 
         api.prev(); 
         break; 
       case 9: // Tab 
       case 32: // Space 
       case 34: // Page down 
       case 39: // Right 
       case 40: // Down 
         api.next(); 
         break; 
      } 

      event.preventDefault(); 
     } 
    }, false); 

这是我正在试图改写它们的定义(在一个单独的js文件,但代码在impress.js启动后执行):

  • 空格键应该调用暂停
  • 其他键应该没有效果。

    //绑定键盘事件.. document.addEventListener( 'KEYUP',函数(事件){

    if (event.keyCode === 9 || (event.keyCode >= 32 && event.keyCode <= 34) || (event.keyCode >= 37 && event.keyCode <= 40)) { 
        switch (event.keyCode) { 
        // ..left key arrow, go to previous slide 
        case 37: 
         return deck.prev(); 
         break; 
         // ..right key arrow, go to previous slide 
        case 39: 
         return deck.next(); 
         break; 
        case 32: // Space 
         return deck.pause(); 
         break; 
        case 9: // Tab 
        case 33: // Page up 
        case 38: // Up 
        case 34: // Page down 
        case 40: // Down 
         return; 
        } 
    
        event.preventDefault(); 
    } 
    

    },假);

然而,键的功能没有改变。

可以覆盖密钥,我该如何实现?

回答

1

addEventListener不覆盖以前添加的事件侦听器,这是使用on * event属性/属性的优势之一。

为了做你想做的事情,你需要添加你自己的impress:init事件监听器,在通过impress添加之前,执行与库相同的设置,更改需要更改的内容,然后调用stopImmediatePropagation()

stopImmediatePropagation将防止同类型的其他听众被执行,这意味着没话说的impress:init事件监听器不会被触发。

//code executed before impress.js is loaded 
(function(document,window){ 
    "use strict"; 
    var throttle = function(fn, delay) { 
    var timer = null; 
    return function() { 
     var context = this, args = arguments; 
     clearTimeout(timer); 
     timer = setTimeout(function() { 
     fn.apply(context, args); 
     }, delay); 
    }; 
    }; 

    document.addEventListener("impress:init", function(event) { 
    event.stopImmediatePropagation(); 

    //parts of init code 

    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 37: 
      return deck.prev(); 
      break; 
      case 39: 
      return deck.next(); 
      break; 
      case 32: // Space 
      return deck.pause(); 
      break; 
      case 9: // Tab 
      case 33: // Page up 
      case 38: // Up 
      case 34: // Page down 
      case 40: // Down 
      return; 
     } 
     event.preventDefault(); 
     } 
    }, false); 

    //other part of init code 
    }); 

})(document, window) 

演示

<script> 
 
(function(document, window) { 
 
    "use strict"; 
 
    var throttle = function(fn, delay) { 
 
     var timer = null; 
 
     return function() { 
 
      var context = this, args = arguments; 
 
      clearTimeout(timer); 
 
      timer = setTimeout(function() { 
 
       fn.apply(context, args); 
 
      }, delay); 
 
     }; 
 
    }; 
 

 
    document.addEventListener("impress:init", function(event) { 
 
     event.stopImmediatePropagation(); 
 
     var api = event.detail.api; 
 
     document.addEventListener("keydown", function(event) { 
 
      if (event.keyCode === 9 || 
 
       (event.keyCode >= 32 && event.keyCode <= 34) || 
 
       (event.keyCode >= 37 && event.keyCode <= 40)) { 
 
       event.preventDefault(); 
 
      } 
 
     }, false); 
 
     document.addEventListener("keyup", function(event) { 
 
      if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) { 
 
       return; 
 
      } 
 

 
      if (event.keyCode === 9 || (event.keyCode >= 32 && event.keyCode <= 34) || (event.keyCode >= 37 && event.keyCode <= 40)) { 
 
       switch (event.keyCode) { 
 
       // ..left key arrow, go to previous slide 
 
       case 37: 
 
        //return deck.prev(); 
 
        console.log("deck.prev() would have been called"); 
 
        break; 
 
        // ..right key arrow, go to previous slide 
 
       case 39: 
 
        //return deck.next(); 
 
        console.log("deck.next() would have been called"); 
 
        break; 
 
       case 32: // Space 
 
        //return deck.pause(); 
 
        console.log("deck.pause() would have been called"); 
 
        break; 
 
       case 9: // Tab 
 
       case 33: // Page up 
 
       case 38: // Up 
 
       case 34: // Page down 
 
       case 40: // Down 
 
        return; 
 
       } 
 

 
       event.preventDefault(); 
 
      } 
 
     }, false); 
 

 
     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); 
 

 
     document.addEventListener("click", function(event) { 
 
      var target = event.target; 
 

 
      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() { 
 
      api.goto(document.querySelector(".step.active"), 500); 
 
     }, 250), false); 
 
    
 
    }, false); 
 
})(document, window); 
 
</script> 
 
<link rel="styleshee" href="https://cdn.rawgit.com/impress/impress.js/master/css/impress-demo.css"> 
 

 
<div id="impress"> 
 
    <div id="bored" class="step slide" data-x="-1000" data-y="-1500"> 
 
     <q>Aren’t you just <b>bored</b> with all those slides-based presentations?</q> 
 
    </div> 
 
    <div class="step slide" data-x="0" data-y="-1500"> 
 
     <q>Don’t you think that presentations given <strong>in modern browsers</strong> shouldn’t <strong>copy the limits</strong> of ‘classic’ slide decks?</q> 
 
    </div> 
 
    <div class="step slide" data-x="1000" data-y="-1500"> 
 
     <q>Would you like to <strong>impress your audience</strong> with <strong>stunning visualization</strong> of your talk?</q> 
 
    </div> 
 
    <div id="title" class="step" data-x="0" data-y="0" data-scale="4"> 
 
     <span class="try">then you should try</span> 
 
     <h1>impress.js<sup>*</sup></h1> 
 
     <span class="footnote"><sup>*</sup> no rhyme intended</span> 
 
    </div> 
 
    <div id="its" class="step" data-x="850" data-y="3000" data-rotate="90" data-scale="5"> 
 
     <p>It’s a <strong>presentation tool</strong> <br/> 
 
     inspired by the idea behind <a href="http://prezi.com">prezi.com</a> <br/> 
 
     and based on the <strong>power of CSS3 transforms and transitions</strong> in modern browsers.</p> 
 
    </div> 
 
    <div id="big" class="step" data-x="3500" data-y="2100" data-rotate="180" data-scale="6"> 
 
     <p>visualize your <b>big</b> <span class="thoughts">thoughts</span></p> 
 
    </div> 
 
    <div id="tiny" class="step" data-x="2825" data-y="2325" data-z="-3000" data-rotate="300" data-scale="1"> 
 
     <p>and <b>tiny</b> ideas</p> 
 
    </div> 
 
    <div id="ing" class="step" data-x="3500" data-y="-850" data-rotate="270" data-scale="6"> 
 
     <p>by <b class="positioning">positioning</b>, <b class="rotating">rotating</b> and <b class="scaling">scaling</b> them on an infinite canvas</p> 
 
    </div> 
 
    <div id="imagination" class="step" data-x="6700" data-y="-300" data-scale="6"> 
 
     <p>the only <b>limit</b> is your <b class="imagination">imagination</b></p> 
 
    </div> 
 
    <div id="source" class="step" data-x="6300" data-y="2000" data-rotate="20" data-scale="4"> 
 
     <p>want to know more?</p> 
 
     <q><a href="http://github.com/bartaz/impress.js">use the source</a>, Luke!</q> 
 
    </div> 
 
    <div id="one-more-thing" class="step" data-x="6000" data-y="4000" data-scale="2"> 
 
     <p>one more thing...</p> 
 
    </div> 
 
    <div id="its-in-3d" class="step" data-x="6200" data-y="4300" data-z="-100" data-rotate-x="-40" data-rotate-y="10" data-scale="2"> 
 
     <p><span class="have">have</span> <span class="you">you</span> <span class="noticed">noticed</span> <span class="its">it’s</span> <span class="in">in</span> <b>3D<sup>*</sup></b>?</p> 
 
     <span class="footnote">* beat that, prezi ;)</span> 
 
    </div> 
 
    <div id="overview" class="step" data-x="3000" data-y="1500" data-scale="10"></div> 
 
</div> 
 

 
<script src="https://cdn.rawgit.com/impress/impress.js/master/js/impress.js"></script> 
 
<script>impress().init();</script>

1

更新以反映这一事实,这个功能是现在还在主impress.js分支。

在最近的impress.js版本中,您在这里讨论的关键导航代码移至单独的plugin src/plugins/navigation。如果你想禁用它并提供你自己的,你可以很容易地在build.js中做到这一点。

没有运行时间的方式来禁用插件,但如果你想发送这样的拉请求,我很乐意合并它。这可能采取以下形式:

<div id="impress" data-navigation="off" ... > 

最后,我还可以想象导航插件允许用户指定键绑定。但是,因为印象深刻。js目前不支持使用配置文件(并且它不会立即清楚它应该如何执行),因此每个演示文稿必须在演示文稿中指定其键绑定。

我希望你会发现这些选项比试图从外部破解不可插入的上游版本更清洁。

+0

感谢您指出这一点!我很好奇,有没有在这个叉子增加移动支持? – TheRed

+1

是的。我删除了阻止在手机上加载的代码。我整合了一个“touch”插件,可以让你滑动下一个/上一个(而上游已经在左/右边缘敲击)。还有一个叫做“mobile”的插件,可以让你隐藏所有的幻灯片,但是当前,上一个和下一个。这个想法是让演示文稿更加轻松。 (这两个实际上都是由他人完成的!) –