Wicket: tell the browser to scroll to certain tag (anchor)

此生再无相见时 提交于 2019-12-25 15:59:31

问题


We are using Wicket and our generated pages are quiet long (a lot of vertical scrolling). Some links or form's onSubmit methods invoke just perform some actions on the database and show the same page again:

public class MyPage extends WebPage {

    public MyPage(PageParameters parameters) {
        ....

        final Form<Void> form = new StatelessForm<Void>("formId") {
            protected void onSubmit() {
                // some database stuff
                ...
                setResponsePage(getClass(), getPageParameters());
            }
        };
        ...
    }
}

How can I make the setResponsePage invocation cause the browser scroll to the form, so the page is not just showing the top? Maybe some JavaScript-injection?


回答1:


I think a nice Wicket-y solution combines stuff that is already in Michael's answer, with a Behavior, so you can just add this to your form.

form.add( new ScrollToTopBehavior()); 

The behaviour itself would like something like this:

public class ScrollToTopBehavior extends Behavior
{

    @Override
    public void renderHead( Component component, IHeaderResponse response )
    {
        super.renderHead( component, response );
        response.render( JavaScriptHeaderItem.forReference( Application.get().getJavaScriptLibrarySettings().getJQueryReference() ) );

        component.setOutputMarkupId( true );

        String script = String.format("doSomeJavaScriptStuff('%s')", component.getMarkupId());
        response.render( OnDomReadyHeaderItem.forScript( script ) );
    }
}

UPDATE:

For scrolling to a specific ID / ANCHOR only once, you can follow this answer: https://stackoverflow.com/a/3163635/461499




回答2:


JS of course.

This would be something like (with JQuery usage):

var scrollPosition = $('#scrollToMarkupId').offset().top;
$('html, body').animate({ scrollTop: " + scrollPosition + " }, 'slow');

where scrollToMarkupId is wicket component's markup id, which could be obtained by calling component.getMarkupId() method.

I'm not pro in JS, so you can try to google better impl may be.


Now, about wicket:

1) As for me, I prefer AJAX invocations for such behavior ( note that if you use such approach your page won't be stateless ):

// do not override your form's `onSubmit()` method
final Form<Void> form = new Form<Void>("formId");
// adding ajax behavior with `onSubmit()` method overriding.
form.add ( new AjaxFormSubmitBehavior ("submit")
{
    protected void onSubmit ( AjaxRequestTarget target )
    {
        // your submit logic
        // then insert js, descriped above:
        target.appendJavaScript ("..." + componentToScroll.getMarkupId() + "..");
    }
});

This approach won't reload your page at all but also post your data.

/----------------------------------------------------------------------------------------------------------------------------------/

2) You also could execute JS after page loading, by overriding renderHead method:

public class YourPage extends WebPage
{
...
    @Override
    public void renderHead ( final IHeaderResponse response )
    {
        //replace `...` by your script.
        response.render ( OnDomReadyHeaderItem.forScript ( "..." );
    }
...
}

Such script will be invoked after page is renedered (and setResponsePage method will render your page). You can use this approach for any components and panels too.




回答3:


I've now use following JavaScript injecting code:

add(new Behavior() {
    @Override
    public void renderHead(Component component, IHeaderResponse response) {
        super.renderHead(component, response);

        response.render(new HeaderItem() {
            @Override
            public Iterable<?> getRenderTokens() {
                return Collections.singletonList("javascript-anchor");
            }

            @Override
            public void render(Response response) {
                response.write("<script type=\"text/javascript\">\n");
                response.write("window.location.href='#rules';\n");
                response.write("</script>\n");
            }
        });
    }
});

Feel free to comment (I'm a complete JS-noob with only very limited experience in Wicket).



来源:https://stackoverflow.com/questions/27354911/wicket-tell-the-browser-to-scroll-to-certain-tag-anchor

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!