Some final thoughts and a follow up.
First up, the post-back and round trip. As noted by Bruce, we STILL have a post-back, and thus we can't run the client side code first, since if we have save this code:
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<main>
<asp:UpdatePanel ID="upd1" runat="server">
<ContentTemplate>
<asp:Button ID="btn1" runat="server"
Text="Scroll"
OnClick="btn1_Click"
OnClientClick="Scroll()"
/>
</ContentTemplate>
</asp:UpdatePanel>
<div style="background-color: aquamarine; height: 500px;">
</div>
<div id="div1">
Scrolled here
</div>
<script>
function Scroll() {
//debugger;
document.getElementById("div1").scrollIntoView();
}
</script>
</main>
</asp:Content>
Note for above, I have included the FULL page markup, only minus the page directive. (so this is a child page of master).
Code behind:
protected void btn1_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(2000);
}
So, what will occur? Well, the button will be clicked, the client side code will run (and scroll), and then we have the server side code wait 2 seconds, and then the WHOLE NEW fresh part of the update panel will come down the network pipe, and refresh the screen, and that will un-scroll the effects of the scroll.
Hence, even before we run the code, we should see the page scroll(), and then un-scroll after the server side code is complete.
And this is exactly what we expect and see:
Ok, so the suggesting (at least by me), is let's have the code run AFTER we finish the server round trip and post-back (and to be 100% clear, it is called a partial page post back when using a update panel, but it is STILL a post back, and round trip, and even the page load event fires each time before the button click server stub runs).
So, we can remove the server side click event, and inject (run) the JavaScript code AFTER the update panel round trip to the server. However, JavaScript often runs asyncrioues, or often is threaded. That means the Scroll() function runs, but the browser UI thread and plotting is not YET quite done! So, the Scroll() function triggers, but runs before the UI threading of the browser is complete, and thus does not work!
However, in JavaScript, there is a way to force (trick) the rendering engine to run, and when the UI threads are done, then we run pending JavaScript code. (this is a 1000 + page conept and whole books are dedicated to how this works, but suffice to say, pushing the pending code into the program stack as opposed to the UI rendering stack (browsers have both types of threads), then this all works by introduction of setTimer().
So, now the newly updated code is thus:
client side:
<asp:UpdatePanel ID="upd1" runat="server">
<ContentTemplate>
<asp:Button ID="btn1" runat="server"
Text="Scroll"
OnClick="btn1_Click"
/>
</ContentTemplate>
</asp:UpdatePanel>
<div style="background-color: aquamarine; height: 500px;">
</div>
<div id="div1">
Scrolled here
</div>
<script>
function Scroll() {
//debugger;
document.getElementById("div1").scrollIntoView();
}
</script>
And our server side code (with script injection to run scroll after the server side code).
protected void btn1_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(2000);
string sJava = "setTimeout(Scroll,250);";
ScriptManager.RegisterStartupScript(upd1, upd1.GetType(), "my code", sJava, true);
}
So, now the effect will be a 2 second wait, then the page (update panel) refresh occurres, and then we run our scroll(), but only after a delay. In fact a delay of 1 will work, since as noted, this pushed Scroll function into a stack of pending routines to run, and they do so AFTER the UI up dateing of the browser is complete (UI threads are complete).
Hence, the result is now this:
And if we 100% remove the delay (server side!!), the scroll function will of course still work just fine.
So, in fact, with the update panel, we have to run the JavaScript code AFTER the update panel, since as noted, while the update panel "looks like" there is no post-back and round trip to the server, there is in fact a round trip occurring!
However, the browser after receiving the updated content, and we inject the script? Well, the injected script does not really wait until "on page ready" for that injected code to run. Hence, there are two ways to address this issue. The above - use setTimer(), and the 2nd way would be to attached code to NOT the page "on ready", but to a event that runs AFTER the update panel, and this is also rather possible, and I can post the code on how to do this, but for now, the above setTimer looks to be a good solution.
And this is thus not due to having bootstrap directly, but only that bootstrap puts extra UI workloads on the browser, and once again, the Scroll() code was running before the UI bits and parts are complete, and thus it looked like it was not working. So, while "sort of" the issue might be fixed by removing bootstrap, it really that the UI workloads are being increased, and thus Scroll() was running before that other threaded UI code was not completed.
As for the script manager errors? It not at all clear why or how you were receiving as such, but we would need to see the FULL page markup used in that case - including the page header (as above shows, we did not need to add a ScriptManager to the page, since as noted, it is already in the master page).
Regardless, adopting the above approach (script injection + setTimer()) looks to make all the moving parts work correct.