wjv*_*vic 6 html javascript css
我最近一直在学习更多的 JavaScript,因为我将在即将到来的实习中大量使用它。公司推荐了很多不同的资源给我看,但我的一个朋友也推荐了这个网站:
我决定试一试,昨天开始了第一个项目,它是一个 JavaScript 架子鼓。
所以整个项目并不难,但我注意到发生了一个小错误。因此,该项目将一个“keydown”事件侦听器附加到几个不同的 HTML 元素,这些元素在按下任一 ASDFGHJKJL 时触发。除了播放声音之外,侦听器还为元素附加了一个类,为按下的键增加了一点效果。
为了移除这个类,我们在元素上附加了一个 transitionend 监听器。因此,当按下键后 CSS 属性完成转换时,类将被删除,图形在浏览器中恢复正常。
现在,如果您缓慢按下按键,它就可以正常工作。但我注意到,如果你按住一个键一两秒钟,看起来好像添加的类永远不会被删除并且图形是永久的。然后我检查了控制台,注意到 transitionend 事件一旦像那样卡住就永远不会触发。
这是来自完成文件的代码。
function removeTransition(e)
{
if (e.propertyName !== 'transform')
return;
e.target.classList.remove('playing');
}
function playSound(e)
{
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
const key = document.querySelector(`div[data-key="${e.keyCode}"]`);
if (!audio)
return;
key.classList.add('playing');
audio.currentTime = 0;
audio.play();
}
Run Code Online (Sandbox Code Playgroud)
这就是我们附加 transitionend 侦听器的方式,不确定这是否与它有关
const keys = Array.from(document.querySelectorAll('.key'));
keys.forEach(key => key.addEventListener('transitionend', removeTransition));
Run Code Online (Sandbox Code Playgroud)
所以我们在 removeTransition 函数中加入了 if 循环,这样它就不会删除每个正在转换的属性的类,但我注意到当你删除 if 循环时,页面工作得很好。
所以我不完全确定 transitionend 事件发生了什么,以及为什么它一旦像那样卡住就完全停止触发。而且,为什么它在 if 循环被删除时有效。也许当它循环遍历所有属性时,它有更多机会删除该类?没有线索。想知道这里是否有人可能知道发生了什么。
编辑:
我稍微改变了 playSound 函数,试图找到它的底部。
function playSound(e)
{
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
const key = document.querySelector(`.key[data-key="${e.keyCode}"]`);
if(!audio)
{
return;
}
if(key.classList.contains("playing"))
{
console.log("True");
key.classList.remove("playing");
}
audio.currentTime = 0;
audio.play();
console.log("adding");
key.classList.add("playing");
}
Run Code Online (Sandbox Code Playgroud)
因此,我添加了一个 if 语句,用于检查元素一旦卡住就已包含“播放”类。我还添加了一个 classList.remove 调用以尝试在同一分支中摆脱它。我发现一旦它卡住了,我再次按下该键,它就会分支到 if 语句并打印控制台消息,但仍然不会删除“播放”类。
造成无法删除 CSS 类问题的原因有 2 个:
playing,这也是打开/关闭动画的关键。这样的设定让问题变得非常复杂。playing。这是一个 DOM 操作,会花费比必要的时间更多的时间。为了解决这个问题,最好将标志/标记信息存储在内存中(作为变量),如果转换未完成,则停止键盘事件侦听器。
将标志/标记信息存储在变量中:
var keysUnderTransition = {
"65": 0,
"83": 0,
"68": 0,
"70": 0,
"71": 0,
"72": 0,
"74": 0,
"75": 0,
"76": 0
};
Run Code Online (Sandbox Code Playgroud)
因为每个元素在一个周期内都会有 2 次转换。0意味着元素不在转换中(没有剩余转换),2意味着它处于第一个转换(剩余 2 个转换需要完成),并且1意味着它处于最后一个转换(剩余 1 个转换需要完成)。
在函数 中playSound,检查并标记标志:
if (keysUnderTransition[e.keyCode]) {
return;
}
keysUnderTransition[e.keyCode] = 2;
Run Code Online (Sandbox Code Playgroud)
在函数 中removeTransition,恢复标志/标记:
var dataKey = this.getAttribute('data-key');
var underTransitionVal = keysUnderTransition[dataKey];
if (underTransitionVal === 2) {
setTimeout(function() {
keysUnderTransition[dataKey] = 1;
}, 50);
} else if (underTransitionVal === 1) {
keysUnderTransition[dataKey] = 0;
}
Run Code Online (Sandbox Code Playgroud)
我50在上面的代码中使用在第二次转换结束之前更改标志。
这是一个工作的jsfiddle。
| 归档时间: |
|
| 查看次数: |
1139 次 |
| 最近记录: |