使用.each()函数并不允许我使用.on()函数

时间:2016-12-11 11:40:26

标签: jquery css css-transitions jquery-on

我想就.each().on()的使用提供一些指导。

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

  

jquery.min.js:2未捕获的TypeError:key.on不是函数

我的代码:

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

4 个答案:

答案 0 :(得分: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>

答案 1 :(得分:0)

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>

答案 2 :(得分:0)

试试这个,使用TEMPLATE = app CONFIG += console c++11 CONFIG -= app_bundle CONFIG -= qt SOURCES += main.cpp QMAKE_CXXFLAGS += -Wall -Wextra -pedantic 代替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;
}

答案 3 :(得分:-1)

这个案例的关键是元素,而不是jQuery对象。你需要用jQuery对象包装它,就像这样。

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