2011-04-06 3 views
3

PopupPanel은 오래전에 작성된 (akhem) GWT 클래스입니다. (너무 빨기 때문입니다.) 팝업으로 내용을 표시 할 수 있습니다. 옵션 중 하나는 autoHide입니다. 팝업 외부에 특정 이벤트가 있으면 팝업이 닫힙니다. 그것은 Safari Mobil (SM)을 제외하고는 모두 잘 작동합니다. SM은 터치시 클릭 이벤트를 발생시키지 않습니다. 그것은 터치 이벤트를 발생시킵니다. PopupPanel은 ClickEvents를 찾기 위해 하드 코딩되어 있습니다.GWT 2.2.0 팝업 이벤트에 자동 팝업 숨기기

특히, 코드가 말한다 :

case Event.ONMOUSEDOWN: 
    ... 
    if (!eventTargetsPopupOrPartner && autoHide) { 
     hide(true); 
    ... 

을 분명히 이것은 완전하지 않습니다 그리고 그것은 또한

문제는, 모든 메소드와 필드는 개인 그래서 나는이를 추가 할 수 없습니다 Event.ONTOUCHSTART을 포함해야 기능. 그것은 GWT 팀의 큰 우우입니다 만, 내 자신의 클래스를 만들고 PopupPanel의 내용을 복사 할 수 있기 때문에 정말로 걱정하지 않아도됩니다. 큰 문제는 nativeEventPreview가 Touch Events를 캡처하지 않는다는 것입니다.

나는 다음과 같은 이벤트 미리보기에 다음을 추가하는 시도 :

'팝업'나는 터치 이벤트 외부에 닫 얻기 위해 노력하고있어 PopupPanel입니다
private static NativePreviewHandler nativePreviewHandler = new NativePreviewHandler() { 
    public void onPreviewNativeEvent(NativePreviewEvent event) { 
     Event nativeEvent = Event.as(event.getNativeEvent()); 
     switch (nativeEvent.getTypeInt()) {   
     case Event.ONTOUCHSTART:   
     case Event.ONMOUSEDOWN: 
      EventTarget target = nativeEvent.getEventTarget(); 
      if (!Element.is(target) || !popup.getElement().isOrHasChild(Element.as(target))) {     
       popup.hide(); 
      } break; 
     }  
      } 
}; 

. 지구상의 다른 브라우저에서 테스트 할 때 마우스가 아래쪽으로 움직이는 것은 슬픈 일이지만 iPad에서는 테스트되지 않습니다.

내가 시도한 또 다른 한가지는 TouchStartHandler를 PopupPanel (그 뒤에 보이는 회색) 유리에 추가하는 것입니다. 내가 터치 이벤트를 그런 식으로 잡을 수 있기를 바란다.하지만 재미있는 방법으로 DOM에 붙어 있기 때문에 유리에 불을 지르는 이벤트를 얻을 수 없었다. 내 코드 :

private static class ProperPopupPanel extends PopupPanel { 

    public ProperPopupPanel() { 
     super();    
}   

    void setHideOnGlassTouch() { 
     setGlassEnabled(true); 

     TouchableLabeThatDoesntCrashOnWrap glass = new TouchableLabeThatDoesntCrashOnWrap(getGlassElement()); 
     glass.addTouchStartHandler(new TouchStartHandler() { 

      @Override 
      public void onTouchStart(TouchStartEvent event) {     
       hide();     
      } 

     }); 
     glass.addClickHandler(new ClickHandler() { 

      @Override 
      public void onClick(ClickEvent event) { 
       hide();      
      }    
     }); 
    }  

    private class TouchableLabeThatDoesntCrashOnWrap extends Label { 
     public TouchableLabeThatDoesntCrashOnWrap(Element element) { 
      super(element); 
      super.onAttach(); 
     } 
    } 
} 

제 생각에는 정상적으로 작동하지만 작동하지 않습니다. 나는 이유를 모른다. 어떤 아이디어 나 제안도 환영합니다. 감사. 여기

답변

7

충분하지 GWT 사용자 ... 물론 나는 JSNI를 통해 터치 핸들러를 추가하는 내 자신의 클래스를 ... 만든

/** 
* Overwrite of the usual PopupPanel with a modification that this one 
* works well on touch-enabled browsers. 
* @author McTrafik 
*/ 
public class ProperPopupPanel extends PopupPanel { 

    //////////////////////////////////////////////////////////// 
    /////////// OVERRIDES ////////////////////////////////////// 
    //////////////////////////////////////////////////////////// 

    public ProperPopupPanel() { 
     super(); 
     setTouchListener(); 
    } 

    @Override 
    public void hide() { 
     super.hide(); 
     removeTouchListener(); 

    } 

    @Override 
    public void show() { 
     super.show(); 
     addTouchListener(); 
    } 

    //////////////////////////////////////////////////////////// 
    /////////// NANDLERS /////////////////////////////////////// 
    //////////////////////////////////////////////////////////// 

    protected JavaScriptObject touchHandler; 

    /** 
    * Handle a touch event that happened while the popup is open. 
    * @param event - The event to handle 
    */ 
    protected void handleTouchEvent(Event event) { 
     // Check to see if the events should be firing in the first place. 
     if (!isShowing()) { 
      removeTouchListener(); 
      return; 
     } 
     // Check if the event happened within the popup 
     EventTarget target = event.getEventTarget(); 
     if (!Element.is(target) || !getElement().isOrHasChild(Element.as(target))) { 
      // Stop event if the popup is modal 
      if (isModal()) event.preventDefault(); 
      // Close the popup if the event happened outside 
      if (isAutoHideEnabled()) { 
       hide(true); 
       removeTouchListener(); 
      } 
     } 
    }; 


    /** 
    * Create a touchHandler that knows how to point to this instance. 
    * Without it there's a cast exception that happens. 
    */ 
    protected native void setTouchListener() /*-{ 
     var caller = this; 
     [email protected][package].ProperPopupPanel::touchHandler = function(event) { 
      [email protected][package].ProperPopupPanel::handleTouchEvent(Lcom/google/gwt/user/client/Event;)(event); 
     } 
    }-*/; 


    /** 
    * Add a touch listener that will listen to touch events. 
    */ 
    protected native void addTouchListener() /*-{ 
     $doc.addEventListener(
      "touchstart", 
      [email protected][package].ProperPopupPanel::touchHandler, 
      true 
     ); 
     $doc.addEventListener(
      "MozTouchDown", 
      [email protected][package].ProperPopupPanel::touchHandler, 
      true 
     ); 
    }-*/; 


    /** 
    * Remove the touch listeners 
    */ 
    protected native void removeTouchListener() /*-{ 
     $doc.removeEventListener(
      "touchstart", 
      [email protected][package].ProperPopupPanel::touchHandler, 
      true 
     ); 
     $doc.removeEventListener(
      "MozTouchDown", 
      [email protected][package].ProperPopupPanel::touchHandler, 
      true 
     ); 
    }-*/; 


}