Why won't an HTML form load into a Javascript-

2019-08-04 20:07发布

问题:

So, in pure HTML, I can create a form that loads its results into an iframe (instead of moving the user to the result url).

<html>
  <head>
    <title>Google Preview</title>
    <style>iframe { width: 800px; height: 600px }</style>
  </head>
  <body>
    <form method='get' action='http://www.google.com/search' target='results'>
      <label for='q'>Google Search:</label>
      <input name='q'/>
    </form>
    <!-- form result loads in this iframe -->
    <iframe name='results'></iframe>
  </body>
</html>

I'm trying to do a similar thing in Greasemonkey, and running into issues.

I have a page with a form that I'd rather have load its results into an iframe, so I create an iframe, and change the form target to match the iframe's name. However, this doesn't load the result page in the iframe, but instead opens the result page in a new tab.

I've traced the problem down to using Javascript to create the iframe. It seems to insert the iframe into the DOM just fine (and looking at firebug, the source generated is nearly identical to that above, except for an extra <script> tag). But when I create the iframe in Javascript, I get the 'open results in a new tab' behaviour.

<html>
  <head>
    <title>Google Preview</title>
    <style>iframe { width: 800px; height: 600px }</style>
  </head>
  <body>
    <form method='get' action='http://www.google.com/search' target='results'>
      <label for='q'>Google Search:</label>
      <input name='q'/>
    </form>
    <script>
      try {
        // form result doesn't load in this iframe, for some reason
        const iframe = document.body.appendChild( document.createElement('iframe') );
        iframe.name = 'results';
      } catch (e) {
        alert(e);
      }
    </script>
  </body>
</html>

What do I need to do to get the results to load in a iframe created by Javascript? (I haven't tried document.write() yet, but I'm not sure that would be very useful from Greasemonkey).

update: So I got around to trying document.write(), and it works. So maybe I'll just have to figure out how to use that from GreaseMonkey (without messing up my multitude of DOM elements I have handles to)

<html>
  <head>
    <title>Google Preview</title>
    <style>iframe { width: 800px; height: 600px }</style>
  </head>
  <body>
    <form method='get' action='http://www.google.com/search' target='results'>
      <label for='q'>Google Search:</label>
      <input name='q'/>
    </form>
    <script>
      try {
        // but form result will load in this iframe
        document.write('<iframe name="results"></iframe>');
      } catch (e) {
        alert(e);
      }
    </script>
  </body>
</html>

I'm still want to know why document.body.appendChild() doesn't work, but document.write() does.

update2: it doesn't seem to be just forms, I can substitute a link in instead of the <form>...</form> and get the same results for all three cases

<div><a target="results" href="http://www.google.com">test</a></div> 

回答1:

Okay, I figured out a satisfactory solution. I need to define the iframe name before I call appendChild().

<html>
  <head>
    <title>Google Preview</title>
    <style>iframe { width: 800px; height: 600px }</style>
  </head>
  <body>
    <div><a target="results" href="http://www.google.com">test</a></div>
    <script>
      try {
        // this works
        const iframe = document.createElement('iframe');
        iframe.name = 'results';
        document.body.appendChild( iframe );
      } catch (e) {
        alert(e);
      }
    </script>
  </body>
</html>

I'm not sure why setting the name after appending it to the document didn't work (and I'd still like to know if anyone out there wants 15pts), but this lets me get on with my GreaseMonkeying, so it's good enough.



回答2:

hmmm i'm thinking because it's still posting back to itself so the frame is never created (because the form is created and rendered on page on every postback)