在插件 (impress.js) 中覆盖 event.keycode,而不更改插件中的代码

Overwrite event.keycode in plugin (impress.js) without changing code in plugin

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

这就是键码定义在 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 启动后执行):

但是,按键的功能没有改变。

键码可以被覆盖吗?我该如何实现?

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

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

stopImmediatePropagation 将阻止任何其他相同类型的侦听器被执行,这意味着 impress 的 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>

已更新以反映此功能现在也在主 impress.js 分支中。

在 impress.js 的最新版本中,您在这里谈论的关键导航代码已移至单独的 plugin src/plugins/navigation. If you want to disable it and provide your own, you can easily do that in build.js

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

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

最后,我还可以想象导航插件允许用户指定键绑定。但是,由于 impress.js 目前不支持使用配置文件(而且还不清楚应该如何做到这一点),因此每个演示文稿都必须在演示文稿中指定其键绑定。