jQuery 和仅 ReactJS 动画
jQuery and ReactJS ONLY animations
我只需要使用 jQuery 动画,请不要提及过渡。
这是我的代码库
var CommentForm = React.createClass({
componentWillUnmount: function(cb) {
console.log('hiding')
jQuery(this.getDOMNode()).slideUp('slow', cb);
console.log((this.getDOMNode()))
},
componentDidMount: function() {
jQuery(this.getDOMNode()).hide().slideDown('slow');
if (this.props.autofocus) {
jQuery(this.refs.commentArea.getDOMNode()).focus();
}
},
render: function() {
return (
<div>
<div className="panel-footer" ref="commentComponent">
<form role="form">
<div className="form-group">
<textarea className="form-control" placeholder="Say something nice!" ref="commentArea"></textarea>
</div>
<div className="pull-right">
<button className="btn btn-default btn-md" type="button"><span className="fa fa-comment"></span> Comment</button>
</div>
<div className="clearfix"></div>
</form>
</div>
</div>
);
}
});
如您所见,我可以在安装组件时添加一个很棒的动画,但我无法像我在代码中提到的那样使用动画卸载组件。
有没有想过如何用 jQuery 做到这一点?和 Reactjs 组件生命周期 ?
这是我尝试使用过于简单的演示来解决这个问题。
JavaScript:
var Container = React.createClass({
onClicked: function() {
console.log('Container.onClicked');
if(this.state.isShowing){
this.refs.myHelloWorld.hide();
} else {
this.setState({ isShowing: true });
}
},
onAnimationComplete: function() {
console.log('Container.onAnimationComplete');
this.setState({ isShowing: false });
},
getInitialState: function() {
return { isShowing: false };
},
render: function() {
var helloWorld = this.state.isShowing ? <Hello name="World!" onComplete={this.onAnimationComplete} ref="myHelloWorld" /> : '';
return (
<div id="container">
<MyButton onButtonClicked={this.onClicked}/>
{helloWorld}
</div>
);
}
});
var MyButton = React.createClass({
render: function() {
return <button onClick={this.props.onButtonClicked}>Toggle</button>;
}
});
var Hello = React.createClass({
hide: function() {
console.log('Hello.hide');
var that = this;
$(React.findDOMNode(this)).stop(true).fadeOut({
duration: 1200,
complete: function() {
that.props.onComplete();
}
});
},
componentDidMount: function() {
console.log('Hello.componentDidMount');
$(React.findDOMNode(this)).stop(true).hide().fadeIn(1200);
},
componentWillUnmount: function() {
console.log('Hello.componentWillUnmount');
},
render: function() {
return <div>Hello { this.props.name }</div>;
}
});
React.render(<Container />, document.body);
正如您已经发现的那样,通过使用 componentDidMount
生命周期事件。
然而,当我们想要从我们的主视图动画化 out 我们的子组件时,做同样的事情是很棘手的,因为相应的componentWillUnmount
life-cycle event triggers after our view has actually un-mounted and there is no event available that we could use before that. And even if there was, we would have then had to manually remove our child component either from within itself or from the main view. I was initially thinking of using React.unmountComponentAtNode
做同样的事情,但后来想出了另一种方法。
解决方法是先从主视图向子组件发送一个回调作为参数,后面会用到。然后我们调用子组件的另一个方法,该方法将动画 out 组件的 DOM 节点本身。最后,当动画完成时,我们将触发我们之前收到的相同回调。
希望这对您有所帮助。
P.S。这种方法不受 jQuery 的 animate()
和相关方法的严格约束,相反,这种方法可以用于任何其他基于 JS 的动画库(我我在看我最喜欢的 GSAP ;)), as long as they trigger a callback when the animation is completed (and GSAP provides a plethora。
更新#1:
哇哇哇!
因此,碰巧的是,我更多地挖掘了 ReactJS,尤其是它的动画部分,看看我发现了什么,他们公开了 low-level API for transition events.
所以我们之前试图用我们自己的回调来完成的事情,我们的 props
对象维护对 etc 的引用,事实证明,它可以使用这个 API 本身来完成。
我不确定我现在是否真的非常喜欢它,因为我还没有在实际项目中实施这两种技术,但我很高兴我们现在有可用的选项。我们可以使用内部 API,或者我们可以按照之前的建议制作我们自己的解决方案。
看看这个修改后的jsFiddle doing the same thing but this time using the internal callbacks such as componentWillEnter and componentWillLeave.
我只需要使用 jQuery 动画,请不要提及过渡。
这是我的代码库
var CommentForm = React.createClass({
componentWillUnmount: function(cb) {
console.log('hiding')
jQuery(this.getDOMNode()).slideUp('slow', cb);
console.log((this.getDOMNode()))
},
componentDidMount: function() {
jQuery(this.getDOMNode()).hide().slideDown('slow');
if (this.props.autofocus) {
jQuery(this.refs.commentArea.getDOMNode()).focus();
}
},
render: function() {
return (
<div>
<div className="panel-footer" ref="commentComponent">
<form role="form">
<div className="form-group">
<textarea className="form-control" placeholder="Say something nice!" ref="commentArea"></textarea>
</div>
<div className="pull-right">
<button className="btn btn-default btn-md" type="button"><span className="fa fa-comment"></span> Comment</button>
</div>
<div className="clearfix"></div>
</form>
</div>
</div>
);
}
});
如您所见,我可以在安装组件时添加一个很棒的动画,但我无法像我在代码中提到的那样使用动画卸载组件。
有没有想过如何用 jQuery 做到这一点?和 Reactjs 组件生命周期 ?
这是我尝试使用过于简单的演示来解决这个问题。
JavaScript:
var Container = React.createClass({
onClicked: function() {
console.log('Container.onClicked');
if(this.state.isShowing){
this.refs.myHelloWorld.hide();
} else {
this.setState({ isShowing: true });
}
},
onAnimationComplete: function() {
console.log('Container.onAnimationComplete');
this.setState({ isShowing: false });
},
getInitialState: function() {
return { isShowing: false };
},
render: function() {
var helloWorld = this.state.isShowing ? <Hello name="World!" onComplete={this.onAnimationComplete} ref="myHelloWorld" /> : '';
return (
<div id="container">
<MyButton onButtonClicked={this.onClicked}/>
{helloWorld}
</div>
);
}
});
var MyButton = React.createClass({
render: function() {
return <button onClick={this.props.onButtonClicked}>Toggle</button>;
}
});
var Hello = React.createClass({
hide: function() {
console.log('Hello.hide');
var that = this;
$(React.findDOMNode(this)).stop(true).fadeOut({
duration: 1200,
complete: function() {
that.props.onComplete();
}
});
},
componentDidMount: function() {
console.log('Hello.componentDidMount');
$(React.findDOMNode(this)).stop(true).hide().fadeIn(1200);
},
componentWillUnmount: function() {
console.log('Hello.componentWillUnmount');
},
render: function() {
return <div>Hello { this.props.name }</div>;
}
});
React.render(<Container />, document.body);
正如您已经发现的那样,通过使用 componentDidMount
生命周期事件。
然而,当我们想要从我们的主视图动画化 out 我们的子组件时,做同样的事情是很棘手的,因为相应的componentWillUnmount
life-cycle event triggers after our view has actually un-mounted and there is no event available that we could use before that. And even if there was, we would have then had to manually remove our child component either from within itself or from the main view. I was initially thinking of using React.unmountComponentAtNode
做同样的事情,但后来想出了另一种方法。
解决方法是先从主视图向子组件发送一个回调作为参数,后面会用到。然后我们调用子组件的另一个方法,该方法将动画 out 组件的 DOM 节点本身。最后,当动画完成时,我们将触发我们之前收到的相同回调。
希望这对您有所帮助。
P.S。这种方法不受 jQuery 的 animate()
和相关方法的严格约束,相反,这种方法可以用于任何其他基于 JS 的动画库(我我在看我最喜欢的 GSAP ;)), as long as they trigger a callback when the animation is completed (and GSAP provides a plethora。
更新#1:
哇哇哇!
因此,碰巧的是,我更多地挖掘了 ReactJS,尤其是它的动画部分,看看我发现了什么,他们公开了 low-level API for transition events.
所以我们之前试图用我们自己的回调来完成的事情,我们的 props
对象维护对 etc 的引用,事实证明,它可以使用这个 API 本身来完成。
我不确定我现在是否真的非常喜欢它,因为我还没有在实际项目中实施这两种技术,但我很高兴我们现在有可用的选项。我们可以使用内部 API,或者我们可以按照之前的建议制作我们自己的解决方案。
看看这个修改后的jsFiddle doing the same thing but this time using the internal callbacks such as componentWillEnter and componentWillLeave.