【问题标题】:Overwrite event.keycode in plugin (impress.js) without changing code in plugin覆盖插件(impress.js)中的event.keycode而不更改插件中的代码
【发布时间】:2018-02-04 20:28:44
【问题描述】:

我正在使用 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 启动后执行代码):

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

    // 绑定键盘事件.. document.addEventListener('keyup', function (event) {

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

    },假);

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

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

【问题讨论】:

    标签: javascript overwrite keycode


    【解决方案1】:

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

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

    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>

    【讨论】:

      【解决方案2】:

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

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

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

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

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

      【讨论】:

      • 感谢您指出这一点!我很好奇,这个分支中是否增加了对移动设备的支持?
      • 是的。我删除了阻止它在手机上加载的代码。我集成了一个“触摸”插件,允许您滑动到下一个/上一个(而上游已经点击了左/右边缘)。还有一个名为“mobile”的插件,它可以让你隐藏除当前、上一个和下一个之外的所有幻灯片。这个想法是使演示文稿更易于渲染。 (这两个其实都是别人做的,不是我自己做的!)
      猜你喜欢
      • 1970-01-01
      • 2018-04-07
      • 1970-01-01
      • 2014-03-01
      • 2014-09-12
      • 2023-03-17
      • 2013-12-28
      • 1970-01-01
      • 2018-09-01
      相关资源
      最近更新 更多