The script does load the new <iframe>. The problem is that the <form> is also submitted (if the browser supports implicit form submission) which then reloads the page with the original <iframe>.
One simple solution is to remove the <form> element. Without a <form> element, there can be no form submission:
<!--form--> <button onclick="changeIframeSrc()">Click here</button> <iframe id="myFrame" src="test1.html"></iframe> <!--/form-->
Another is to prevent the default action of the <button> by returning false from the onclick handler:
<form> <button onclick="changeIframeSrc(); return false;">Click here</button> <iframe id="myFrame" src="test1.html"></iframe> </form>
However, there is a problem with these solutions. If the browser doesn't execute the script, or the script fails in some unanticipated way, the user is left with a dead button. Ideally, the button should submit the form in a useful way when the script doesn't run. Eg.:
<form> <button name=frame value=2 onclick="changeIframeSrc(); return false;">Click here</button> <iframe id="myFrame" src="test1.html"></iframe> </form>
The add some server-side code that outputs the form, but with src="test2.html" as the default <iframe> source if the page is requested with the form data frame=2.