【问题标题】:using the .each() function doesn't allow me to use the .on() function使用 .each() 函数不允许我使用 .on() 函数
【发布时间】:2016-12-11 11:40:25
【问题描述】:

我想获得一些有关使用.each().on() 的指导。

我正在尝试在它们结束转换后从包含它们的元素中删除类 playing。但是,在输入下面的代码时,控制台会喷出:

jquery.min.js:2 Uncaught TypeError: key.on is not a function

我的代码:

$(document).ready(function(){
 function removeTransition(e) {
      if (e.propertyName !== 'transform') return;
      e.target.classList.remove('playing');
  }


  function playSound(e){
    const audio = $(`audio[data-key="${e.keyCode}"]`);
    const key = $(`div[data-key="${e.keyCode}"]`);
    key.addClass('playing');
    if (!audio) return;
    audio[0].currentTime = 0;
    audio[0].play();
  }
      const keys = $("[class=key]");
    keys.each(key => key.on('transitionend', removeTransition));
    $('body').on("keydown", playSound);

})

HTML:

<!DOCTYPE HTML>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>JS Drum Kit</title>
        <link rel="stylesheet" href="styles.css">
    </head> 
    <body>
        <div class="keys">
            <div data-key="65" class="key">
                <kbd>A</kbd>
                <span class="sound">clap</span>
            </div>
            <div data-key="83" class="key">
                <kbd>S</kbd>
                <span class="sound">hihat</span>
            </div>
            <div data-key="68" class="key">
                <kbd>D</kbd>
                <span class="sound">kick</span>
            </div>
            <div data-key="70" class="key">
                <kbd>F</kbd>
                <span class="sound">openhat</span>
            </div>
            <div data-key="71" class="key">
                <kbd>G</kbd>
                <span class="sound">boom</span>
            </div>
            <div data-key="72" class="key">
                <kbd>H</kbd>
                <span class="sound">ride</span>
            </div>
            <div data-key="74" class="key">
                <kbd>J</kbd>
                <span class="sound">snare</span>
            </div>
            <div data-key="75" class="key">
                <kbd>K</kbd>
                <span class="sound">tom</span>
            </div>
            <div data-key="76" class="key">
                <kbd>L</kbd>
                <span class="sound">tink</span>
            </div>

        </div>

        <audio data-key="65" src="sounds/clap.wav"></audio>
        <audio data-key="83" src="sounds/hihat.wav"></audio>
        <audio data-key="68" src="sounds/kick.wav"></audio>
        <audio data-key="70" src="sounds/openhat.wav"></audio>
        <audio data-key="71" src="sounds/boom.wav"></audio>
        <audio data-key="72" src="sounds/ride.wav"></audio>
        <audio data-key="74" src="sounds/snare.wav"></audio>
        <audio data-key="75" src="sounds/tom.wav"></audio>
        <audio data-key="76" src="sounds/tink.wav"></audio>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="script.js"></script>

    </body>
</html>

CSS:

html{
    font-size: 12px;
    background:url(http://cdn.wallpapersafari.com/95/30/yYO1JG.jpg);
    background-size: cover;
    font-family: 'Nunito Sans', sans-serif;
}

.keys{
    display: flex;
    flex: 1;
    min-height:100vh;
    align-items: center;
    justify-content: center;
}

.key{
    border: 3px solid black;
    border-radius:5px;
    margin:1rem;
    font-size: 1.5rem;
    padding:1rem .5rem;
    width:100px;
    text-align: center;
    color:black;
}

.playing {
    transform:scale(1.1);
    border-color:#9C2A00;
}

【问题讨论】:

  • 请贴出完整代码
  • 添加了完整代码

标签: jquery css css-transitions jquery-on


【解决方案1】:

有些事情你需要改变:

• 您分配每个功能的方式不正常

keys.each(function(){$(this).on('transitionend', removeTransition)});

• 转换中对属性的引用不正确

if (e.originalEvent.propertyName !== 'transform') return;

• 您分配键值的方式造成了一些冲突

const audio = $('audio[data-key="' + e.keyCode + '"]');
const key = $('div[data-key="' + e.keyCode + '"]');

• 最重要的可能是CSS 中没有过渡,因此在transitionend 上没有回调

transition: transform .5s ease;

JSFiddle

$(document).ready(function() {
  function removeTransition(e) {
    if (e.originalEvent.propertyName !== 'transform') return;
    e.target.classList.remove('playing');
  }

  function playSound(e) {
    const audio = $('audio[data-key="' + e.keyCode + '"]');
    const key = $('div[data-key="' + e.keyCode + '"]');
    key.addClass('playing');
    if (!audio) return;
    audio[0].currentTime = 0;
    audio[0].play();
  }
  const keys = $("[class=key]");
  keys.each(function(){$(this).on('transitionend', removeTransition)});
  $('body').on("keydown", playSound);

})
html {
  font-size: 12px;
  background: url(http://cdn.wallpapersafari.com/95/30/yYO1JG.jpg);
  background-size: cover;
  font-family: 'Nunito Sans', sans-serif;
}

.keys {
  display: flex;
  flex: 1;
  min-height: 100vh;
  align-items: center;
  justify-content: center;
}

.key {
  border: 3px solid black;
  border-radius: 5px;
  margin: 1rem;
  font-size: 1.5rem;
  padding: 1rem .5rem;
  width: 100px;
  text-align: center;
  color: black;
}

.playing {
  transform: scale(1.1);
  border-color: #9C2A00;
  transition: transform .5s ease;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="keys">
  <div data-key="65" class="key">
    <kbd>A</kbd>
    <span class="sound">clap</span>
  </div>
  <div data-key="83" class="key">
    <kbd>S</kbd>
    <span class="sound">hihat</span>
  </div>
  <div data-key="68" class="key">
    <kbd>D</kbd>
    <span class="sound">kick</span>
  </div>
  <div data-key="70" class="key">
    <kbd>F</kbd>
    <span class="sound">openhat</span>
  </div>
  <div data-key="71" class="key">
    <kbd>G</kbd>
    <span class="sound">boom</span>
  </div>
  <div data-key="72" class="key">
    <kbd>H</kbd>
    <span class="sound">ride</span>
  </div>
  <div data-key="74" class="key">
    <kbd>J</kbd>
    <span class="sound">snare</span>
  </div>
  <div data-key="75" class="key">
    <kbd>K</kbd>
    <span class="sound">tom</span>
  </div>
  <div data-key="76" class="key">
    <kbd>L</kbd>
    <span class="sound">tink</span>
  </div>

</div>

<audio data-key="65" src="sounds/clap.wav"></audio>
<audio data-key="83" src="sounds/hihat.wav"></audio>
<audio data-key="68" src="sounds/kick.wav"></audio>
<audio data-key="70" src="sounds/openhat.wav"></audio>
<audio data-key="71" src="sounds/boom.wav"></audio>
<audio data-key="72" src="sounds/ride.wav"></audio>
<audio data-key="74" src="sounds/snare.wav"></audio>
<audio data-key="75" src="sounds/tom.wav"></audio>
<audio data-key="76" src="sounds/tink.wav"></audio>

【讨论】:

    【解决方案2】:

    function TestCtrl($) {
      $btns = $('.test');
      
      
      // the callback will be invoked with index and node
      $btns.each((index, node) => {
        $(node).click(() => console.log(index, node));
      })
    }
    
    
    jQuery(document).ready(TestCtrl);
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <button class="test">Test</button>
    <button class="test">Test</button>
    <button class="test">Test</button>
    <button class="test">Test</button>
    <button class="test">Test</button>
    <button class="test">Test</button>

    编辑

    只是想满足您的代码案例:

    function TestCtrl($) {
      let test = $('#Test');
      let $keys = $('.key');
      
      test.click(() => $keys.toggleClass('testing'));
      
      function onKeyTransitionEnd(event, $key, nodeIndex) {
        console.log("transitionend", nodeIndex);
      }
      
      $keys.each((i, node) => {
        let $node = $(node)
        .on(
          'transitionend', 
          e => onKeyTransitionEnd(e, $node, i)
        ); 
      });
    }
    
    
    jQuery(document).ready(TestCtrl);
    .keys {
      display: flex;
      flex-wrap: wrap;
    }
    .key {
      width: 100px;
      height: 50px;
      margin: 5px;
      background: yellow;
      transition: 500ms all linear;
    }
    
    .key.testing {
      background: cyan;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <button id="Test">Test It</button>
    <hr />
    
    <div class="keys">
      <div class="key"></div>
      <div class="key"></div>
      <div class="key"></div>
      <div class="key"></div>
      <div class="key"></div>
      <div class="key"></div>
      <div class="key"></div>
      <div class="key"></div>  
    </div>

    【讨论】:

    • 嗯?我不太确定。
    • 您应该点击blue button [Run code snippet]并自行尝试。
    • 我不确定如何将其应用于我的代码。
    • 抱歉,您能进一步解释一下吗?
    【解决方案3】:

    试试这个,用addEventListener代替on

    keys.each(function(key) 
        {
        keys[key].addEventListener("transitionend", removeTransition);
        });
    

    html {
      font-size: 12px;
      background: url(http://cdn.wallpapersafari.com/95/30/yYO1JG.jpg);
      background-size: cover;
      font-family: 'Nunito Sans', sans-serif;
    }
    .keys {
      display: flex;
      flex: 1;
      min-height: 100vh;
      align-items: center;
      justify-content: center;
    }
    .key {
      border: 3px solid black;
      border-radius: 5px;
      margin: 1rem;
      font-size: 1.5rem;
      padding: 1rem .5rem;
      width: 100px;
      text-align: center;
      color: black;
    }
    .playing {
      transform: scale(1.1);
      border-color: #9C2A00;
      transition: transform 1s ease;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <!DOCTYPE HTML>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <title>JS Drum Kit</title>
      <link rel="stylesheet" href="styles.css">
    </head>
    
    <body>
      <div class="keys">
        <div data-key="65" class="key">
          <kbd>A</kbd>
          <span class="sound">clap</span>
        </div>
        <div data-key="83" class="key">
          <kbd>S</kbd>
          <span class="sound">hihat</span>
        </div>
        <div data-key="68" class="key">
          <kbd>D</kbd>
          <span class="sound">kick</span>
        </div>
        <div data-key="70" class="key">
          <kbd>F</kbd>
          <span class="sound">openhat</span>
        </div>
        <div data-key="71" class="key">
          <kbd>G</kbd>
          <span class="sound">boom</span>
        </div>
        <div data-key="72" class="key">
          <kbd>H</kbd>
          <span class="sound">ride</span>
        </div>
        <div data-key="74" class="key">
          <kbd>J</kbd>
          <span class="sound">snare</span>
        </div>
        <div data-key="75" class="key">
          <kbd>K</kbd>
          <span class="sound">tom</span>
        </div>
        <div data-key="76" class="key">
          <kbd>L</kbd>
          <span class="sound">tink</span>
        </div>
    
      </div>
    
      <audio data-key='65' src="sounds/clap.wav"></audio>
      <audio data-key="83" src="sounds/hihat.wav"></audio>
      <audio data-key="68" src="sounds/kick.wav"></audio>
      <audio data-key="70" src="sounds/openhat.wav"></audio>
      <audio data-key="71" src="sounds/boom.wav"></audio>
      <audio data-key="72" src="sounds/ride.wav"></audio>
      <audio data-key="74" src="sounds/snare.wav"></audio>
      <audio data-key="75" src="sounds/tom.wav"></audio>
      <audio data-key="76" src="sounds/tink.wav"></audio>
    
    
    </body>
    
    </html>
    <script>
      $(document).ready(function() {
        function removeTransition(e) {
          if (e.propertyName !== 'transform') return;
          e.target.classList.remove('playing');
        }
    
    
        var key;
    
        function playSound(e) {
          const audio = $(`audio[data-key="${e.keyCode}"]`);
          const key = $(`div[data-key="${e.keyCode}"]`);
          key.addClass('playing');
          if (audio.length == 0) return;
          audio[0].currentTime = 0;
          audio[0].play();
        }
        $('body').on("keydown", playSound);
        const keys = $("[class=key]");
        keys.each(function(key) {
          keys[key].addEventListener("transitionend", removeTransition);
        });
    
    
      });
    </script>

    【讨论】:

    • 按下一个键时会发生一个过渡。
    • 这是transitionend,当播放器过渡结束时transitionend自动触发,并自动调用removeTransition函数
    • 是的,但是根据您提供的输入,转换结束时它不会执行。
    【解决方案4】:

    这种情况下的关键是元素,而不是 jQuery 对象。你需要用 jQuery 对象包装它,像这样。

    keys.each((index, key) => $(key).on('transitionend', removeTransition));
    

    【讨论】:

    • 通过更改代码,控制台输出:jquery.min.js:3 Uncaught TypeError: Object.defineProperty called on non-object(...)
    • keys.each(key =&gt; ...) => keys.each((index, key) =&gt; ...)
    • 哦,是的,jQuery 先给出键(这里是索引),然后是值(这里是键),抱歉。更新了我的答案,现在应该是正确的。
    • 不。它仍然不起作用,控制台没有给出错误但它没有应用 removeTransition
    • 那么你的选择器是错误的。另外,当我查看选择器时,您应该重构它,$("[class=key]") 可以而且应该写成$('.key')
    猜你喜欢
    • 2014-08-31
    • 2017-04-04
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 2017-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多