I'm guessing that you're doing incremental loading - that as soon as the 
user reaches the bottom of the current content, you get more?

You could remove the scroll handler when you start to load the HTML, and 
then restore it when the HTML has been received. Or have the loading 
mechanism set a flag and unset it when done, and the scroll handler checks 
that flag before doing anything (maybe better to use an integer count, 
increment when starting load, decrement when complete, and scrolll handler 
only works when it's zero.  But, if there are images in the received 
content, they will be loading asynchronously after that, which will affect 
the size of the content.  The best* way I can think of to handle that is to 
scan the received HTML looking for img tags, and then add a native JS 
load/error handler to each one, and keep a running count.  the load handler 
would decrement the count, and, when it reaches 0, all images will be 
loaded.  You might still need a deferred command, since just because the 
image has loaded doesn't mean that the DOM has reflowed.

*Maybe the second best way.  If you used an iframe as your loader instead 
of GWT's Ajax mechanism, you could set a readystatechange handler.  
ReadyState 4 is supposed to mean that everything has been received, 
including images.  But, I don't know how well supported that is across 
browsers.


On Friday, October 17, 2014 8:34:25 AM UTC-4, sch wrote:
>
> I am working on an application which fetches HTML content from the server 
> and displays it to the user. The content fetched from the server is a 
> complete HTML document. I have used UiBinder to specify UI for the view.
>
> <g:HTMLPanel ui:field="mainPanel" styleName="ap-mainPanel"></g:HTMLPanel>
>
> In the view I have setViewerContent(String content) method and also a 
> member panel for holding content[contentPanel]
>
> public void setViewerContent(String content){
>     contentPanel = new HTMLPanel(content);
>     contentPanel.setStyleName("ap-mainPanel ap-scrollPanel"); //$NON-NLS-1$
>     contentPanel.addAttachHandler(new AttachEvent.Handler() {
>
>         @Override
>         public void onAttachOrDetach(AttachEvent event) {
>             if(event.isAttached())
>             {
>                 System.out.println("<-- rendering complete -->");
>                 isRenderComplete = true;                    
>             }
>
>         }
>     });
>     mainPanel.clear();
>     mainPanel.add(contentPanel);
>     addScrollHandler();}
>
> I add a scroll handler to the contentPanel which listens to the 
> ScrollEvent and onScroll() calls the appropriate methods to fetch content 
> from the server based on whether scroll is at the top or bottom.
>
> public void addScrollHandler() {
>     Event.sinkEvents(contentPanel.getElement(), Event.ONSCROLL);
>     contentPanel.addHandler(this, ScrollEvent.getType());}
> public void onScroll( ScrollEvent event ){
>     if( HelperUtils.isScrollAtBottom( event.getSource() ) )
>     {
>         if(isRenderComplete)
>         {
>           System.out.println("<-- Process Down scroll START-->");
>           isRenderComplete = false;
>           getUiHandlers().reachedMaxVerticalScrollPostion();
>
>           System.out.println("<-- Process Down scroll END-->");
>         }
>     }
>
>     if( HelperUtils.isScrollAtTop( event.getSource() ) )
>     {
>         if(isRenderComplete)
>         {  
>           System.out.println("<-- Process Up scroll START-->");
>           isRenderComplete = false;                
>           getUiHandlers().reachedMinVerticalScrollPostion();
>           System.out.println("<-- Process Up scroll END -->");
>         }
>
>     }}
>
> The problem I was facing was as we render the content I see calls made to 
> the server to fetch content continuously. New scroll events are being fired 
> while the content fetched from the server is being rendered. We would not 
> want this i.e while the content is being rendered we do not want the 
> ScrollEvent to be fired. I tried the above code where I have attached 
> AttachEvent.Handler() to contentPanel. A flag isRenderComplete is 
> maintained which is turned true on contentPanel attach. This flag is used 
> in the onScroll method before triggering any server call.This approach 
> seems to work. 
>
> But I am not sure if this is the correct one. Does anyone has any better 
> solution[s] ?If the content has images and other external stuff will they 
> be loaded before AttachEvent is fired ?
>
> Also since we are creating new contentPanel everytime each fetch takes the 
> scrollbar to the top. I tried to add a new HTMLPanel markerPanel with 
> couple of line breaks to the contentPanel. Then in the onAttachOrDetach() 
> of contentPanel tried to scroll to the markerPanel. This did not work.
>
> public void setViewerContent(String content){
>     contentPanel = new HTMLPanel(content);
>     markerPanel = new HTMLPanel(" <br> <br> ");
>     contentPanel.setStyleName("ap-mainPanel ap-scrollPanel"); //$NON-NLS-1$
>     contentPanel.addAttachHandler(new AttachEvent.Handler() {
>
>         @Override
>         public void onAttachOrDetach(AttachEvent event) {
>             System.out.println("<-- rendering complete -->");
>             if(event.isAttached())
>             {
>                 markerPanel.getElement().scrollIntoView();
>                 isRenderComplete = true;                    
>             }
>
>         }
>     });
>     mainPanel.clear();
>     contentPanel.add(markerPanel);
>     mainPanel.add(contentPanel);
>     addScrollHandler();}
>
> Any suggestions ? we want the scroll to be at the bottom when we fetch new 
> content and the scroll event should not be fired till the content fetched 
> is rendered completely.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.

Reply via email to