如何在按下HTML表单上的按钮后运行脚本,但在提交表单之前运行?

huangapple go评论72阅读模式
英文:

How do I get a script to run after a button is pressed on an HTML form but before the form is submitted?

问题

Forewarning: 我刚开始理解HTML、JavaScript和PHP的概念和工作原理,所以如果这段代码中存在明显的逻辑问题,我提前道歉。

我目前正在实施来自StudyTonight.com的JavaScript代码,以使用我的网络摄像头拍摄照片。我的目标是将拍摄的照片转换为Base64格式,并将其上传到文本文件中。

以下是照片捕获功能的实现代码片段(完整实现可在超链接中找到):

/* JS comes here */
(function() {
  var width = 320; // 我们将根据这个宽度来缩放照片
  var height = 0; // 这将根据输入流计算

  var streaming = false;

  var video = null;
  var canvas = null;
  var photo = null;
  var startbutton = null;

  function startup() {
    video = document.getElementById('video');
    canvas = document.getElementById('canvas');
    photo = document.getElementById('photo');
    startbutton = document.getElementById('startbutton');

    navigator.mediaDevices.getUserMedia({
        video: true,
        audio: false
      })
      .then(function(stream) {
        video.srcObject = stream;
        video.play();
      })
      .catch(function(err) {
        console.log("An error occurred: " + err);
      });

    video.addEventListener('canplay', function(ev) {
      if (!streaming) {
        height = video.videoHeight / (video.videoWidth / width);

        if (isNaN(height)) {
          height = width / (4 / 3);
        }

        video.setAttribute('width', width);
        video.setAttribute('height', height);
        canvas.setAttribute('width', width);
        canvas.setAttribute('height', height);
        streaming = true;
      }
    }, false);

    startbutton.addEventListener('click', function(ev) {
      takepicture();
      ev.preventDefault();
    }, false);

    clearphoto();
  }

  function clearphoto() {
    var context = canvas.getContext('2d');
    context.fillStyle = "#AAA";
    context.fillRect(0, 0, canvas.width, canvas.height);

    var data = canvas.toDataURL('image/png');
    photo.setAttribute('src', data);
  }

  function takepicture() {
    var context = canvas.getContext('2d');
    if (width && height) {
      canvas.width = width;
      canvas.height = height;
      context.drawImage(video, 0, 0, width, height);

      var data = canvas.toDataURL('image/png');
      photo.setAttribute('src', data);
    } else {
      clearphoto();
    }
  }

  window.addEventListener('load', startup, false);
})();

我尝试使用以下脚本来尝试获取照片的值并保存到一个输入框中。这个脚本应该放在拍照脚本之后,但在提交按钮之前:

<script>
    var photo = document.getElementById("photo");
    var photoBase64 = photo.src;
    document.write("<input type='hidden' name='photo' value='" + photoBase64 + "'>");
</script>

然后,使用PHP,我将输入框中的“photo”保存到一个变量中,并将其写入txt文件:

<?php
    // 为照片创建一个变量
    $photo = $_POST['photo'];

    $file = fopen("log.txt", "a");
    fwrite($file, $photo . "\n");
    fclose($file);
?>

结果是,按下提交按钮后,log.txt文件为空,我猜这是因为照片直到按下提交按钮后才被拍摄,而此时“photo”的值已经被写入log.txt文件,而照片还没有被拍摄。我已经尝试了将保存照片到输入框的脚本放置在代码的不同位置,但得到了类似的结果。我越来越困惑于脚本的声明位置如何影响其行为。

我想知道的是:

  1. 我的怀疑是否正确?
  2. 我使用脚本来保存照片的值的方法是否合理?
  3. 如果合理,是不是脚本位置的问题阻止了代码按预期工作,还是其他原因?

任何帮助都将不胜感激。

英文:

Forewarning: I am new in understanding the concepts and workings of html, javascript, and php so I apologize in advance if there are blaring logic issues with this code.

I am currently implementing javascript from StudyTonight.com to capture a photo with my webcam. My goal is to take the resulting photo, convert it to base64, and uploaded it to a text file.

Below is a snippet of the implementation of the photo capturing feature (Full implementation can be found in the hyperlink)

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

/* JS comes here */
(function() {
var width = 320; // We will scale the photo width to this
var height = 0; // This will be computed based on the input stream
var streaming = false;
var video = null;
var canvas = null;
var photo = null;
var startbutton = null;
function startup() {
video = document.getElementById(&#39;video&#39;);
canvas = document.getElementById(&#39;canvas&#39;);
photo = document.getElementById(&#39;photo&#39;);
startbutton = document.getElementById(&#39;startbutton&#39;);
navigator.mediaDevices.getUserMedia({
video: true,
audio: false
})
.then(function(stream) {
video.srcObject = stream;
video.play();
})
.catch(function(err) {
console.log(&quot;An error occurred: &quot; + err);
});
video.addEventListener(&#39;canplay&#39;, function(ev) {
if (!streaming) {
height = video.videoHeight / (video.videoWidth / width);
if (isNaN(height)) {
height = width / (4 / 3);
}
video.setAttribute(&#39;width&#39;, width);
video.setAttribute(&#39;height&#39;, height);
canvas.setAttribute(&#39;width&#39;, width);
canvas.setAttribute(&#39;height&#39;, height);
streaming = true;
}
}, false);
startbutton.addEventListener(&#39;click&#39;, function(ev) {
takepicture();
ev.preventDefault();
}, false);
clearphoto();
}
function clearphoto() {
var context = canvas.getContext(&#39;2d&#39;);
context.fillStyle = &quot;#AAA&quot;;
context.fillRect(0, 0, canvas.width, canvas.height);
var data = canvas.toDataURL(&#39;image/png&#39;);
photo.setAttribute(&#39;src&#39;, data);
}
function takepicture() {
var context = canvas.getContext(&#39;2d&#39;);
if (width &amp;&amp; height) {
canvas.width = width;
canvas.height = height;
context.drawImage(video, 0, 0, width, height);
var data = canvas.toDataURL(&#39;image/png&#39;);
photo.setAttribute(&#39;src&#39;, data);
} else {
clearphoto();
}
}
window.addEventListener(&#39;load&#39;, startup, false);
})();

<!-- language: lang-html -->

&lt;div class=&quot;contentarea&quot;&gt;
&lt;label for=&quot;Container Image&quot;&gt;Chip Container Images (Take Picture with Chip Exposed for Already Opened Containers):&lt;/label&gt;
&lt;br&gt;&lt;br&gt;
&lt;div class=&quot;camera&quot;&gt;
&lt;video id=&quot;video&quot;&gt;Video stream not available.&lt;/video&gt;
&lt;/div&gt;
&lt;div&gt;&lt;button id=&quot;startbutton&quot;&gt;Take photo&lt;/button&gt;&lt;/div&gt;
&lt;canvas id=&quot;canvas&quot;&gt;&lt;/canvas&gt;
&lt;div class=&quot;output&quot;&gt;
&lt;img id=&quot;photo&quot; alt=&quot;The screen capture will appear in this box.&quot;&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br&gt;&lt;br&gt;
&lt;input type=&quot;submit&quot; value=&quot;submit&quot;&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;

<!-- end snippet -->

I tried to utilize the following script to attempt to take the value of the photo and save it to an input. This script would have been placed directly after the picture-taking script but before the submit button.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

&lt;script&gt;
var photo = document.getElementById(&quot;photo&quot;);
var photoBase64 = photo.src;
document.write(&quot;&lt;input type = &#39;hidden&#39; name = &#39;photo&#39; value = &#39;&quot; + photoBase64 + &quot;&#39;&gt;&quot;);
&lt;/script&gt;

<!-- end snippet -->

Then, utilizing .php, I would save the input, "photo", to a variable and write it to a txt file.

<!-- begin snippet: js hide: false console: true babel: null -->

<!-- language: lang-html -->

&lt;?php
//Create a variable for the photo
$photo = $_POST[&#39;photo&#39;];
$file = fopen(&quot;log.txt&quot;, &quot;a&quot;);
fwrite($file, $photo . &quot;\n&quot;);
fclose($file);
?&gt;

<!-- end snippet -->

The result was that the log.txt file came out after empty after pressing the submit file due to what I assume is the photo not being taken until after the submit button is pressed while the value of 'photo' is being written to the log.txt file before the photo is taken. I've experimented around with the placement of the photo-saved-to-input script around the code but received similar results. I am finding myself more and more confused in understanding the behavior of a script depending on the location of its declaration.

What I would like to know is:

  1. Is my suspicion correct?
  2. Is my approach with utilizing a script to save the value of photo logical to begin with?
  3. If it is logical, is my issue a matter of script placement that is preventing the code from working as intended or something else?

Any and all help would be much appreciated.

答案1

得分: 2

这有点过于复杂,并且并非你所想的那样:

var photo = document.getElementById("photo");
var photoBase64 = photo.src;
document.write("<input type='hidden' name='photo' value='" + photoBase64 + "'>");
  1. 这段代码在页面加载时立即执行,因此它将使用页面加载时存在的 src 值(这个值在页面加载时不存在)。
  2. 这三行代码除了创建一个元素外什么都不做。你可以简单地创建一个元素:
<input type="hidden" name="photo" value="">

只需在页面上创建你想要的元素。至于将元素填充为某个值,你应该在创建值之后进行,这似乎是在 takepicture 函数中进行的:

var data = canvas.toDataURL('image/png');
photo.setAttribute('src', data);

如果 data 是你想要的值,那么你应该在这里使用它:

var data = canvas.toDataURL('image/png');
photo.setAttribute('src', data);
document.querySelector('input[name="photo"]').value = data;
英文:

This is a bit over-engineered, and isn't doing what you think:

var photo = document.getElementById(&quot;photo&quot;);
var photoBase64 = photo.src;
document.write(&quot;&lt;input type = &#39;hidden&#39; name = &#39;photo&#39; value = &#39;&quot; + photoBase64 + &quot;&#39;&gt;&quot;);
  1. This code executes immediately when the page loads, so it will use the src value that exists when the page loads (which doesn't exist).

  2. These three lines of code do nothing but create an element. Which you could do by just... creating an element:

    &lt;input type=&quot;hidden&quot; name=&quot;photo&quot; value=&quot;&quot;&gt;
    

Simply create the element on the page where you want it. As for populating the element with a value, you would want to do that after creating the value, which appears to be in the takepicture function:

var data = canvas.toDataURL(&#39;image/png&#39;);
photo.setAttribute(&#39;src&#39;, data);

If data is the value you want, that's where you'd use it:

var data = canvas.toDataURL(&#39;image/png&#39;);
photo.setAttribute(&#39;src&#39;, data);
document.querySelector(&#39;input[name=&quot;photo&quot;]&#39;).value = data;

huangapple
  • 本文由 发表于 2023年7月20日 21:03:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76730201.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定