Wicket:告诉浏览器滚动到某个标签(锚点)

时间:2014-12-08 09:26:25

标签: wicket

我们正在使用Wicket,我们生成的页面很长(很多垂直滚动)。某些链接或表单的onSubmit方法仅调用数据库上的某些操作并再次显示相同的页面:

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());
            }
        };
        ...
    }
}

如何使setResponsePage调用导致浏览器滚动到表单,因此页面不仅仅显示在顶部?也许是一些JavaScript注入?

3 个答案:

答案 0 :(得分:3)

我认为一个不错的Wicket-y解决方案将已经在迈克尔答案中的内容与Behavior结合起来,因此您只需add这样就可以了。

form.add( new ScrollToTopBehavior()); 

行为本身就像这样:

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 ) );
    }
}

更新:

仅滚动到特定ID / ANCHOR一次,您可以按照以下答案操作: https://stackoverflow.com/a/3163635/461499

答案 1 :(得分:2)

JS当然

这就像(使用JQuery):

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

其中scrollToMarkupId是wicket组件的标记ID,可以通过调用component.getMarkupId()方法获得。

我不是JS的专业人士,所以你可以尝试更好地使用google。


现在,关于检票口:

1)至于我,我更喜欢AJAX调用这种行为(请注意,如果你使用这种方法,你的页面将不会是无状态的):

// 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() + "..");
    }
});

此方法根本不会重新加载您的网页,但也会发布您的数据。

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

2)你也可以在页面加载后通过覆盖renderHead方法执行JS:

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

在重新加入页面后将调用此类脚本(并且setResponsePage方法将呈现您的页面)。您也可以将此方法用于任何组件和面板。

答案 2 :(得分:0)

我现在使用以下JavaScript注入代码:

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");
            }
        });
    }
});

随意评论(我是一个完整的JS-noob,只有非常有限的Wicket经验)。