问题
I would like my GWT widget to be notified when its CSS animation is over.
In plain HTML/Javascript this is easily done by registering an event handler like so:
elem.addEventListener("webkitAnimationEnd", function(){
// do something
}, false);
// add more for Mozilla etc.
How can I do this in GWT?
This type of event is unknown to GWT's DOMImpl
classes, so I keep getting an error "Trying to sink unknown event type webkitAnimationEnd".
Thanks!
回答1:
You can always write some of the native (JavaScript) code yourself:
public class CssAnimation {
public static native void registerCssCallback(
Element elem, AsyncCallback<Void> callback) /*-{
elem.addEventListener("webkitAnimationEnd", function() {
$entry(@CssAnimation::cssCallback(Lcom/google/gwt/user/client/rpc/AsyncCallback;)(callback));
}, false);
}-*/;
protected static void cssCallback(AsyncCallback<Void> callback) {
callback.onSuccess(null);
}
}
I haven't tried the code above. Let me know if it works as expected.
You can use GWT's Animation class to achieve the same effect. For example,
new com.google.gwt.animation.client.Animation() {
final com.google.gwt.dom.client.Style es = widget.getElement().getStyle();
@Override
protected void onUpdate(double progress) {
setOpacity(1 - interpolate(progress));
}
private void setOpacity(double opacity) {
es.setProperty("opacity", Double.toString(opacity));
es.setProperty("filter", "alpha(opacity=" + 100 * opacity + ")");
}
@Override
protected void onComplete() {
/* ... run some code when animation completes ... */
}
}.run(2000, 5000);
回答2:
Based on Darthenius' answer and Clay Lenhart's Blog, I finally settled for this solution:
private native void registerAnimationEndHandler(final Element pElement,
final CbAnimationEndHandlerIF pHandler)
/*-{
var callback = function(){
pHandler.@fully.qualified.CbAnimationEndHandlerIF::onAnimationEnd()();
}
if (navigator.userAgent.indexOf('MSIE') < 0) { // no MSIE support
pElement.addEventListener("webkitAnimationEnd", callback, false); // Webkit
pElement.addEventListener("animationend", callback, false); // Mozilla
}
}-*/;
The CbAnimationEndHandlerIF
is a simple custom EventHandler
interface:
public interface CbAnimationEndHandlerIF extends EventHandler
{
void onAnimationEnd();
}
Works like a charm! Thanks Darthenius!
If anyone can spot a weakness in this, of course I'd be happy to know.
回答3:
I expanded a bit on the solution from Darthenius. This code also includes a mechanism to remove the event handler when it is finished. This is what I needed for my application but may not be what you want in all contexts. YMMV!
My final code looks like this:
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.rpc.AsyncCallback;
public class CssAnimation {
public static native void registerCssCallback(Element elem, AsyncCallback<Void> callback) /*-{
var eventListener = function () {
$entry(@CssAnimation::cssCallback(Lcom/google/gwt/user/client/rpc/AsyncCallback;)(callback));
elem.removeEventListener("webkitAnimationEnd", eventListener);
};
elem.addEventListener("webkitAnimationEnd", eventListener, false);
}-*/;
protected static void cssCallback(AsyncCallback<Void> callback) {
callback.onSuccess(null);
}
}
来源:https://stackoverflow.com/questions/8249880/how-to-add-css-animationend-event-handler-to-gwt-widget