Javascript 在剪辑新div时禁用其他div的样式
我正在建造一台“音乐机器”,但我面临着我无法解决的问题。这台音乐机的所有其他部件都运转良好。只有我想知道,如果你点击(或按相应的键)新的音乐垫,最后一个“激活”它的风格。Etc只有当前播放的声音具有活动pad 我试过这个例子和其他几个例子Javascript 在剪辑新div时禁用其他div的样式,javascript,reactjs,Javascript,Reactjs,我正在建造一台“音乐机器”,但我面临着我无法解决的问题。这台音乐机的所有其他部件都运转良好。只有我想知道,如果你点击(或按相应的键)新的音乐垫,最后一个“激活”它的风格。Etc只有当前播放的声音具有活动pad 我试过这个例子和其他几个例子 document.addEventListener("pause", function(){ var audioDiv = document.getElementsByClassName("clip"); for (var i = 0,
document.addEventListener("pause", function(){
var audioDiv = document.getElementsByClassName("clip");
for (var i = 0, len = audioDiv.length; i < len; i++) {
audioDiv[i].style.backgroundColor = "Grey";
audioDiv[i].style.margin = "50px"
}
}, true)
完整代码:
如果解决方案是JS而不是JQuery,我将不胜感激。我已经用您正在寻找的逻辑编写了一个简单的代码片段:
for(document.getElementsByClassName('box')的变量el){
el.addEventListener('单击',(e)=>{
var activeEl=document.getElementsByClassName('active')[0]
if(activeEl)activeEl.classList.remove('active')
e、 target.classList.add('active')
})
}
.box{
背景颜色:灰色;
边框:1px纯黑;
高度:20px;
宽度:20px;
}
.主动{
背景颜色:蓝色
}
Kobe的答案是正确的,但是React有自己的方法来操作DOM,不建议使用
文档
,而可以使用带有钩子的React.createRef()
或useRef()
。您可以找到文档
REF提供了一种访问DOM节点或对在render方法中创建的元素进行反应的方法
在典型的React数据流中,道具是父组件与其子组件交互的唯一方式。要修改子对象,请使用新道具重新渲染它。然而,在一些情况下,您需要在典型数据流之外强制修改子级。要修改的子级可以是React组件的实例,也可以是DOM元素。对于这两种情况,React都提供了逃生舱口
通过从
SoundPadSide
父组件向子SoundPad
组件提供额外的道具,可以实现所需的行为
我的想法是从它的父组件SoundPadSide
控制SoundPad
的活动状态
基本上,您需要在SoundPadSide
组件中定义state
,以控制当前活动的内容
然后,您需要定义一个回调函数,该函数将更改活动焊盘:
类SoundPadSide扩展React.Component{
建造师(道具){
超级(道具);
此.state={
activeSoundPadId:“无言”
};
this.handleActiveChanged=this.handleActiveChanged.bind(this);
}
handleActiveChanged(id){
this.setState({activeSoundPadId:id});
}
}
在构造函数中,您可以定义activeSoundPadId
的初始状态。例如,我从你的音乐列表中选择了第二个
接下来,您需要将这些属性传递到render()
方法中的SoundPad
组件:
MusicBank=this.props.musicData.map((Obj,i,MusicArr)=>{
返回(
);
}
在声控板组件中有一些变化。因为它现在接收到的道具比我们应该应用的要多。
如果当前SoundPad
y未激活,我在palySound
方法中调用activate
回调:
播放声音(e){
this.props.activate(this.props.clipId);
if(this.state.toPlay){
const sound=document.getElementById(this.props.keyTrigger);
sound.currentTime=0;
声音。播放();
这个.padControl();
this.props.changeDisplay(this.props.clipName);
}否则{
const sound=document.getElementById(this.props.keyTrigger);
sound.currentTime=0;
声音。暂停();
这个.padControl();
this.props.changeDisplay(String.fromCharCode(160));
}
声垫render()
方法中还有一项更改:
返回(
...
我已经对您的代码进行了一些更新。您可以找到demo我同意,但是OP现在处理代码的方式没有帮助。如果他们从一开始就使用ref,我会为其编写一个定制的示例:)当然,我也同意,但我在补充你的回答,以防将来有人看到你的答案,可能会在未来的项目中协助OP。代码很好,但我也需要PAD在按下相应键时以相同的方式动作。我还注意到一件奇怪的事情,有时需要双击才能激活音乐,etc第一次点击激活键盘,第二次点击启动音乐。我看到你将我的代码放在每个鼓垫中。这是个坏主意,因为它会为每个鼓垫创建一个侦听器。这不是你想要的。你可能想将我的代码放在你的应用程序类中。
class SoundPad extends React.Component {
constructor(props) {
super(props);
this.state = {
padStyle: inactiveStyle,
toPlay: true,
};
this.playSound = this.playSound.bind(this);
this.handleKeyPress = this.handleKeyPress.bind(this);
this.padControl = this.padControl.bind(this);
this.stopOther = this.stopOther.bind(this)
}
componentDidMount() {
document.addEventListener("keydown", this.handleKeyPress);
document.addEventListener("play", this.stopOther, true);
document.addEventListener("pause", function(){
var audioDiv = document.getElementsByClassName("clip");
for (var i = 0, len = audioDiv.length; i < len; i++) {
audioDiv[i].style.backgroundColor = "Grey";
audioDiv[i].style.margin = "50px"
}
}, true)
}
componentWillUnmount() {
document.removeEventListener("keydown", this.handleKeyPress);
document.removeEventListener("play", this.stopOther, true);
document.removeEventListener("pause", function(){
var audioDiv = document.getElementsByClassName("clip");
for (var i = 0, len = audioDiv.length; i < len; i++) {
audioDiv[i].style.backgroundColor = "Grey";
audioDiv[i].style.margin = "50px"
}
}, true)
}
handleKeyPress(e) {
if (e.keyCode === this.props.keyCode) {
this.playSound();
}
}
playSound(e) {
if (this.state.toPlay) {
const sound = document.getElementById(this.props.keyTrigger);
sound.currentTime = 0;
sound.play();
this.padControl();
this.props.changeDisplay(this.props.clipName);
} else {
const sound = document.getElementById(this.props.keyTrigger);
sound.currentTime = 0;
sound.pause();
this.padControl();
this.props.changeDisplay(String.fromCharCode(160));
}
}
padControl() {
this.state.toPlay
? this.setState({
padStyle: activeStyle,
toPlay: !this.state.toPlay
})
: this.setState({
padStyle: inactiveStyle,
toPlay: !this.state.toPlay
});
}
stopOther(e) {
var audios = document.getElementsByClassName("clip");
for (var i = 0, len = audios.length; i < len; i++) {
if (audios[i] != e.target) {
audios[i].pause();
}
}
}
render() {
return (
<div
className="drum-pad"
id={this.props.clipId}
onClick={this.playSound}
style={this.state.padStyle}
>
<audio
className="clip"
id={this.props.keyTrigger}
src={this.props.clip}
/>
{this.props.keyTrigger}
</div>
);
}
}
const inactiveStyle = {
backgroundColor: "Grey",
margin: "50px"
};
const activeStyle = {
backgroundColor: "Blue",
margin: "40px"
};