Wicket:告诉浏览器滚动到特定标记(锚定)

Wicket:告诉浏览器滚动到特定标记(锚定),wicket,Wicket,我们使用的是Wicket,生成的页面很长(很多垂直滚动)。某些链接或表单的onSubmit方法调用只需在数据库上执行一些操作并再次显示相同的页面: public class MyPage extends WebPage { public MyPage(PageParameters parameters) { .... final Form<Void> form = new StatelessForm<Void>("formId"

我们使用的是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());
            }
        };
        ...
    }
}
公共类MyPage扩展网页{
公共MyPage(页面参数){
....
最终表格=新的无状态表格(“formId”){
受保护的void onSubmit(){
//一些数据库的东西
...
setResponsePage(getClass(),getPageParameters());
}
};
...
}
}

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

当然是JS

这类似于(使用JQuery时):

var scrollPosition=$('#scrollToMarkupId').offset().top;
$('html,body').animate({scrollTop:“+scrollPosition+”},'slow');
其中,
scrollToMarkupId
是wicket组件的标记id,可以通过调用
component.getMarkupId()
方法获得

我不支持JS,所以你可以试着用谷歌搜索更好的impl


现在,关于wicket:

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

//不要重写表单的`onSubmit()`方法
最终表格=新表格(“表格”);
//使用'onSubmit()`方法重写添加ajax行为。
添加表格(新的AjaxFormSubmitBehavior(“提交”)
{
提交时受保护的void(AjaxRequestTarget目标)
{
//提交逻辑
//然后插入js,如上所述:
target.appendJavaScript(“…”+componentToScroll.getMarkupId()+”);
}
});
这种方法根本不会重新加载页面,但也会发布数据

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

2) 您还可以在页面加载后通过重写
renderHead
方法执行JS:

public类YourPage扩展网页
{
...
@凌驾
公共无效渲染头(最终IHeaderResponse响应)
{
//用脚本替换“…”。
response.render(OnDomReadyHeaderItem.forScript(“…”);
}
...
}

这样的脚本将在页面重新排序后被调用(并且
setResponsePage
方法将呈现您的页面)。您也可以对任何组件和面板使用这种方法。

JS当然

这类似于(使用JQuery时):

var scrollPosition=$('#scrollToMarkupId').offset().top;
$('html,body').animate({scrollTop:“+scrollPosition+”},'slow');
其中,
scrollToMarkupId
是wicket组件的标记id,可以通过调用
component.getMarkupId()
方法获得

我不支持JS,所以你可以试着用谷歌搜索更好的impl


现在,关于wicket:

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

//不要重写表单的`onSubmit()`方法
最终表格=新表格(“表格”);
//使用'onSubmit()`方法重写添加ajax行为。
添加表格(新的AjaxFormSubmitBehavior(“提交”)
{
提交时受保护的void(AjaxRequestTarget目标)
{
//提交逻辑
//然后插入js,如上所述:
target.appendJavaScript(“…”+componentToScroll.getMarkupId()+”);
}
});
这种方法根本不会重新加载页面,但也会发布数据

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

2) 您还可以在页面加载后通过重写
renderHead
方法执行JS:

public类YourPage扩展网页
{
...
@凌驾
公共无效渲染头(最终IHeaderResponse响应)
{
//用脚本替换“…”。
response.render(OnDomReadyHeaderItem.forScript(“…”);
}
...
}

该脚本将在页面重新排序后调用(并且
setResponsePage
方法将呈现页面)。您也可以对任何组件和面板使用此方法。

我认为一个好的Wicket-y解决方案将Michael答案中已有的内容与
行为相结合,因此您可以将其添加到表单中

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/定位一次,您可以按照以下答案操作:
我认为一个好的Wicket-y解决方案将Michael答案中已有的内容与
行为相结合,因此您可以
将其添加到表单中

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/定位一次,您可以按照以下答案操作:

我现在使用了以下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");
            }
        });
    }
});
添加(新行为(){ @凌驾 public void renderHead(组件组件,IHeaderResponse响应){ super.renderHead(组件、响应); response.render(新HeaderItem(){ @凌驾 公共Iterable getRenderTokens(){ returncollections.singletonList(“javascript锚”); } @凌驾 公共无效呈现(响应){ 响应。写入(“\n”); response.write(“window.location.href='#rules';\n”); 响应。写入(“\n”); } }); } });
请随意评论(我是一个完全的JS noob,在Wicket方面的经验非常有限)。