最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to prevent the Focus() method from scrolling the page to the top - Stack Overflow

programmeradmin9浏览0评论

I have set of textboxes in a gridview and I use the Focus() method to restore the focus after losing to the intended text box. The problem is :

The page (scrollable) and when I call the Focus method, in the text changed event, the page jump to the top. It's such a confusing behavior.

My question is:

Is there some way to prevent the Focus() method from jumping the page to the top?

My code:

protected void txt_evaluateWeights_TextChanged(object sender, EventArgs e)
        {

            calc();
            int index = ((System.Web.UI.WebControls.GridViewRow)(((RadTextBox)sender).Parent.NamingContainer)).DataItemIndex;

            ((RadTextBox)gv_Evaluation.Rows[index + 1].Cells[3].FindControl("txt_evaluateWeights")).Focus();//Here is the problem. 
        }

Note:

  • I use the asp:TextBox, and the same problem.

  • My grid view in an update panel


EDIT :

Javascript workaround:

var lastFocusedControlId = "";

function focusHandler(e) {
    document.activeElement = e.originalTarget;
}

function appInit() {
    if (typeof (window.addEventListener) !== "undefined") {
        window.addEventListener("focus", focusHandler, true);
    }
    Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(pageLoadingHandler);
    Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoadedHandler);
}

function pageLoadingHandler(sender, args) {
    lastFocusedControlId = typeof (document.activeElement) === "undefined"
        ? "" : document.activeElement.id;
}

function focusControl(targetControl) {
    if (Sys.Browser.agent === Sys.Browser.InternetExplorer) {
        var focusTarget = targetControl;
        if (focusTarget && (typeof (focusTarget.contentEditable) !== "undefined")) {
            oldContentEditableSetting = focusTarget.contentEditable;
            focusTarget.contentEditable = false;
        }
        else {
            focusTarget = null;
        }
        try {
            targetControl.focus();
            if (focusTarget) {
                focusTarget.contentEditable = oldContentEditableSetting;
            }
        }
        catch (err) { }
    }
    else {
        targetControl.focus();
    }

}

function pageLoadedHandler(sender, args) {
    if (typeof (lastFocusedControlId) !== "undefined" && lastFocusedControlId != "") {
        var newFocused = $get(lastFocusedControlId);
        if (newFocused) {
            focusControl(newFocused);
        }
    }
}

Sys.Application.add_init(appInit);

I have set of textboxes in a gridview and I use the Focus() method to restore the focus after losing to the intended text box. The problem is :

The page (scrollable) and when I call the Focus method, in the text changed event, the page jump to the top. It's such a confusing behavior.

My question is:

Is there some way to prevent the Focus() method from jumping the page to the top?

My code:

protected void txt_evaluateWeights_TextChanged(object sender, EventArgs e)
        {

            calc();
            int index = ((System.Web.UI.WebControls.GridViewRow)(((RadTextBox)sender).Parent.NamingContainer)).DataItemIndex;

            ((RadTextBox)gv_Evaluation.Rows[index + 1].Cells[3].FindControl("txt_evaluateWeights")).Focus();//Here is the problem. 
        }

Note:

  • I use the asp:TextBox, and the same problem.

  • My grid view in an update panel


EDIT :

Javascript workaround:

var lastFocusedControlId = "";

function focusHandler(e) {
    document.activeElement = e.originalTarget;
}

function appInit() {
    if (typeof (window.addEventListener) !== "undefined") {
        window.addEventListener("focus", focusHandler, true);
    }
    Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(pageLoadingHandler);
    Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoadedHandler);
}

function pageLoadingHandler(sender, args) {
    lastFocusedControlId = typeof (document.activeElement) === "undefined"
        ? "" : document.activeElement.id;
}

function focusControl(targetControl) {
    if (Sys.Browser.agent === Sys.Browser.InternetExplorer) {
        var focusTarget = targetControl;
        if (focusTarget && (typeof (focusTarget.contentEditable) !== "undefined")) {
            oldContentEditableSetting = focusTarget.contentEditable;
            focusTarget.contentEditable = false;
        }
        else {
            focusTarget = null;
        }
        try {
            targetControl.focus();
            if (focusTarget) {
                focusTarget.contentEditable = oldContentEditableSetting;
            }
        }
        catch (err) { }
    }
    else {
        targetControl.focus();
    }

}

function pageLoadedHandler(sender, args) {
    if (typeof (lastFocusedControlId) !== "undefined" && lastFocusedControlId != "") {
        var newFocused = $get(lastFocusedControlId);
        if (newFocused) {
            focusControl(newFocused);
        }
    }
}

Sys.Application.add_init(appInit);
Share Improve this question edited Sep 26, 2011 at 8:11 Anyname Donotcare asked Aug 8, 2011 at 10:26 Anyname DonotcareAnyname Donotcare 11.4k72 gold badges228 silver badges408 bronze badges
Add a comment  | 

6 Answers 6

Reset to default 4 +50

Rather than trying to fix the way the Focus method behaves, there is an alternative. I haven't tried it, but this page has a discussion of the problem, and some client-side javascript to remember which control had the focus, and then put the focus back on that object after the UpdatePanel gets refreshed. Be sure to read the comment for some updates to the script.

If you use this method, you would remove the call to Focus on in your codebehind, and let this script deal with it on the client.

Provided that you're using update panels and jquery, the solution is quite straightforward. Let's say your textbox ID is tbDeliveryCost. Instead of using tbDeliveryCost.Focus(), do this:

string script = string.Format("$('#{0}').focus();", tbDeliveryCost.ClientID);
ScriptManager.RegisterStartupScript(this, this.GetType(), "SetFocus", script, true);

You can try to use maintainScrollPositionOnPostBack option:

<%@ Page MaintainScrollPositionOnPostback="true" %> 

This question has been asked a zillion times.

It's a bug in ASP.NET's JS library and the workaround is hacky:

var oldScroll = window.scrollTo;
window.scrollTo = function(){};

//... the ugly ASP.NET stuff

window.scrollTo = oldScroll;

The definitive solution to this is to stop using Microsoft ASP.NET and start using a decent technology that allows you to script the client side.

You can try this after you set focus

Response.Write("<script type='text/javascript'>$(...).scollTo( $('<%= txt_evaluateWeights.ClientID %>') )
</script>");

You could use this jQuery plugin to scroll to your textbox:

$(...).scrollTo( $('<%= txt_evaluateWeights.ClientID %>') )
发布评论

评论列表(0)

  1. 暂无评论