我的HTML文档中有一个脚本,用于检测何时检测到其中一个箭头键,然后更改了iframe的URL。释放密钥后,iframe会再次更改。
除了在按下按键期间,它仍然可以重复动作以设置iframe的url。
有没有办法让它按住它只会改变iframe网址一次?然后当它被释放时它会改回网址?
附加: Iv创建了一个页面来控制网络上的遥控车。除了这个问题,它的效果很好。基本上,它将iframe网址更改为PHP页面,每个箭头键都有一个不同的get变量。然后,PHP页面使用PHP Serial根据从iframe发送的变量(使用GET)将数据发送到串行端口。
感谢您的帮助!!!
编辑:这是汽车的照片。 http://oi41.tinypic.com/21cimms.jpg
编辑2
继承index.html
<!doctype html>
<html lang="en">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript">
function pause(ms) {
ms += new Date().getTime();
while (new Date() < ms){}
}
var keyBeingHeld = new Array();
keyBeingHeld[0] = false;//left
keyBeingHeld[1] = false;//right
keyBeingHeld[2] = false;//up
keyBeingHeld[3] = false;//down
function setControllerState(action){
leftPressState="up";
rightPressState="up";
upPressState="up";
downPressState="up";
if (keyBeingHeld[0]){
leftPressState="down";
}
if (keyBeingHeld[1]){
rightPressState="down";
}
if (keyBeingHeld[2]){
upPressState="down";
}
if (keyBeingHeld[3]){
downPressState="down";
}
var stateStr = "?upPressState="+upPressState+"&downPressState="+downPressState+"&leftPressState="+leftPressState+"&rightPressState="+rightPressState;
iframe = document.getElementById('stateFrame');
iframe.src = "BackEnd.php"+stateStr+"&action="+action;
}
$(document).keydown(function(event) {
if (!event) var event = window.event;
switch (event.keyCode) {
case 37:
if (!keyBeingHeld[0]){
keyBeingHeld[0] = true;
setControllerState ("leftArrowPress");
}
break;
case 38:
if (!keyBeingHeld[2]){
keyBeingHeld[2] = true;
setControllerState ("upArrowPress");
}
break;
case 39:
if (!keyBeingHeld[1]){
keyBeingHeld[1] = true;
setControllerState ("rightArrowPress");
}
break;
case 40:
if (!keyBeingHeld[3]){
keyBeingHeld[3] = true;
setControllerState ("downArrowPress");
}
break;
}
});
$(document).keyup(function(event) {
if (!event) var event = window.event;
switch (event.keyCode) {
case 37:
if (keyBeingHeld[0]){
keyBeingHeld[0] = false;
setControllerState ("leftArrowRelease");
}
break;
case 38:
if (keyBeingHeld[2]){
keyBeingHeld[2] = false;
setControllerState ("upArrowRelease");
}
break;
case 39:
if (keyBeingHeld[1]){
keyBeingHeld[1] = false;
setControllerState ("rightArrowRelease");
}
break;
case 40:
if (keyBeingHeld[3]){
keyBeingHeld[3] = false;
setControllerState ("downArrowRelease");
}
break;
}
});
</script>
</head>
<body>
<p>Press one of the arrow keys.</p>
<iframe id="stateFrame" name="stateFrame" style="width:160px;height:180px;" src="BackEnd.php?upPressState=up&downPressState=up&leftPressState=up&downPressState=up&action=none"></iframe>
<p>Thanks vdbuilder!</p>
</body>
</html>
继承人backend.php
<?php
$opened = false;
$upPressState = cleanupSpecialChars($_GET['upPressState']) or $upPressState = 'up';
$downPressState = cleanupSpecialChars($_GET['downPressState']) or $downPressState = 'up';
$leftPressState = cleanupSpecialChars($_GET['leftPressState']) or $leftPressState = 'up';
$rightPressState = cleanupSpecialChars($_GET['rightPressState']) or $rightPressState = 'up';
$action = cleanupSpecialChars($_GET['action']) or $action = 'none';
// build your message from states and action, and send to serial port here
//the rest is to display the state
$pressedColor = "bbffbb";
$releasedColor = "bbbbbb";
$upArrowColor = $releasedColor;
$downArrowColor = $releasedColor;
$leftArrowColor = $releasedColor;
$rightArrowColor = $releasedColor;
if($upPressState == "down"){
sendCMD(25);
$upArrowColor = $pressedColor;
}
if($downPressState == "down"){
sendCMD(24);
$downArrowColor = $pressedColor;
}
if($leftPressState == "down"){
sendCMD(28);
$leftArrowColor = $pressedColor;
}
if($rightPressState == "down"){
sendCMD(29);
$rightArrowColor = $pressedColor;
}
//--- Up
if($upPressState == "up"){
sendCMD(15);
$upArrowColor = $releasedColor;
}
if($downPressState == "up"){
sendCMD(14);
$downArrowColor = $releasedColor;
}
if($leftPressState == "up"){
sendCMD(18);
$leftArrowColor = $releasedColor;
}
if($rightPressState == "up"){
sendCMD(19);
$rightArrowColor = $releasedColor;
}
echo("<html><head><style>");
echo("body{background-color:#000000;}
div#container{position:absolute;left:10px;top:10px;background-color:#eeeeee;
font-size:20px;padding:20px;width:100px;height:92px;text-align:center;}
div.arrow{position:absolute;width:30px;padding-top:2px;padding-bottom:2px;}
div#upArrow{left:55px;top:20px;background-color:#".$upArrowColor.";}
div#downArrow{left:55px;top:82px;background-color:#".$downArrowColor.";}
div#leftArrow{left:20px;top:50px;background-color:#".$leftArrowColor.";}
div#rightArrow{left:90px;top:50px;background-color:#".$rightArrowColor.";}
div#lastAction{position:absolute;left:0px;bottom:2px;font-size:14px;color:#ffffee;}");
echo("</style></head><body>");
echo("<div id='container'>
<div class='arrow' id='upArrow'>↑</div><div class='arrow' id='downArrow'>↓</div>
<div class='arrow' id='leftArrow'>←</div><div class='arrow' id='rightArrow'>→</div>
</div><div id='lastAction'>Last Action:<br />".$action."</div>");
echo("</body></html>");
//cleanup input
function cleanupSpecialChars($inStr){
$tempStr = htmlentities(stripslashes($inStr));
$retStr = str_replace(array('\\','/'), '', $tempStr);
return $retStr;
}
function sendCMD($cmd){
if($opened == false){
$fp =fopen("com4", "wb");
}
fwrite($fp,$cmd);
fclose($fp);
}
?>
答案 0 :(得分:2)
在keydown上设置一个标志,在keyup上清除它。 仅在未设置标志时才触发操作。
答案 1 :(得分:1)
简短回答:
设置一个标志并在发送请求之前测试它是否已设置。
答案很长:
需要两个文件。
以下两个文件的工作原理如下:
您导航到FrontEnd.html。它维护状态并包含iframe。 iframe加载了BackEnd.php(其状态变量设置为默认值并通过get方法传递)。当按下或释放键时,FrontEnd.html使用BackEnd.php重新加载iframe(通过get方法传递状态)。
BackEnd.php将消息发送到串行端口,并根据从FrontEnd.html传递给它的变量显示箭头键的状态。
<!doctype html>
<html lang="en">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript">
var controllerIsReady = false;
var keyEventBuffer = new Array();
var keyBeingHeld = new Array();
keyBeingHeld[0] = false;//left
keyBeingHeld[1] = false;//right
keyBeingHeld[2] = false;//up
keyBeingHeld[3] = false;//down
function controllerReady(){
controllerIsReady = false;
if(keyEventBuffer.length > 0){
bufferDiv = document.getElementById('eventBuffer');
buffHtmlStr = " ";
for (i=0;i<keyEventBuffer.length;i++){
tempStr = keyEventBuffer[i];
index = tempStr.indexOf("action", 0)+7;
keyEventStr = tempStr.substr(index,(tempStr.length-index));
buffHtmlStr = buffHtmlStr + "<br />" + keyEventStr;
}
bufferDiv.innerHTML = buffHtmlStr;
//shift event off and make request
stateStr = keyEventBuffer.shift();
iframe = document.getElementById('stateFrame');
iframe.src = "http://www.vdstudios.net/robotics/BackEnd.php"+stateStr;
}
else{
controllerIsReady = true;//alert("ready");
bufferDiv = document.getElementById('eventBuffer');
bufferDiv.innerHTML = "empty";
}
}
function setControllerState(action){
leftPressState="up";
rightPressState="up";
upPressState="up";
downPressState="up";
if (keyBeingHeld[0]){
leftPressState="down";
}
if (keyBeingHeld[1]){
rightPressState="down";
}
if (keyBeingHeld[2]){
upPressState="down";
}
if (keyBeingHeld[3]){
downPressState="down";
}
var stateStr = "?upPressState="+upPressState+"&downPressState="+downPressState+"&leftPressState="+leftPressState+"&rightPressState="+rightPressState+"&action="+action;
//add stateStr to fifo and if controllerIsReady call controllerReady
keyEventBuffer.push(stateStr);
if(controllerIsReady){
controllerReady();
}
}
$(document).keydown(function(event) {
if (!event) var event = window.event;
switch (event.keyCode) {
case 37:
if (!keyBeingHeld[0]){
keyBeingHeld[0] = true;
setControllerState ("leftArrowPress");
}
break;
case 38:
if (!keyBeingHeld[2]){
keyBeingHeld[2] = true;
setControllerState ("upArrowPress");
}
break;
case 39:
if (!keyBeingHeld[1]){
keyBeingHeld[1] = true;
setControllerState ("rightArrowPress");
}
break;
case 40:
if (!keyBeingHeld[3]){
keyBeingHeld[3] = true;
setControllerState ("downArrowPress");
}
break;
}
});
$(document).keyup(function(event) {
if (!event) var event = window.event;
switch (event.keyCode) {
case 37:
if (keyBeingHeld[0]){
keyBeingHeld[0] = false;
setControllerState ("leftArrowRelease");
}
break;
case 38:
if (keyBeingHeld[2]){
keyBeingHeld[2] = false;
setControllerState ("upArrowRelease");
}
break;
case 39:
if (keyBeingHeld[1]){
keyBeingHeld[1] = false;
setControllerState ("rightArrowRelease");
}
break;
case 40:
if (keyBeingHeld[3]){
keyBeingHeld[3] = false;
setControllerState ("downArrowRelease");
}
break;
}
});
</script>
</head>
<body>
<p>Press one of the arrow keys.</p>
<iframe id="stateFrame" name="stateFrame" style="width:160px;height:180px;" src="http://www.vdstudios.net/robotics/BackEnd.php?upPressState=up&downPressState=up&leftPressState=up&rightPressState=up&action=none"></iframe>
<div style="width:160px;padding:2px;padding-top:5px;background-color:#cccccc;text-align:center;">Event buffer<hr /><div id="eventBuffer" style="width:100%;">text</div></div>
</body>
</html>
BackEnd.php
<?php
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
// HTTP/1.0
header("Pragma: no-cache");
$upPressState = cleanupSpecialChars($_GET['upPressState']) or $upPressState = 'up';
$downPressState = cleanupSpecialChars($_GET['downPressState']) or $downPressState = 'up';
$leftPressState = cleanupSpecialChars($_GET['leftPressState']) or $leftPressState = 'up';
$rightPressState = cleanupSpecialChars($_GET['rightPressState']) or $rightPressState = 'up';
$action = cleanupSpecialChars($_GET['action']) or $action = 'none';
//send message to serial port
if($action == "upArrowPress"){
sendCMD(25);
}
else if($action == "downArrowPress"){
sendCMD(24);
}
else if($action == "leftArrowPress"){
sendCMD(28);
}
else if($action == "rightArrowPress"){
sendCMD(29);
}
else if($action == "upArrowRelease"){
sendCMD(15);
}
else if($action == "downArrowRelease"){
sendCMD(14);
}
else if($action == "leftArrowRelease"){
sendCMD(18);
}
else if($action == "rightArrowRelease"){
sendCMD(19);
}
//the rest is to display the state
$pressedColor = "bbffbb";
$releasedColor = "bbbbbb";
$upArrowColor = $releasedColor;
$downArrowColor = $releasedColor;
$leftArrowColor = $releasedColor;
$rightArrowColor = $releasedColor;
if($upPressState == "down"){
$upArrowColor = $pressedColor;
}
if($downPressState == "down"){
$downArrowColor = $pressedColor;
}
if($leftPressState == "down"){
$leftArrowColor = $pressedColor;
}
if($rightPressState == "down"){
$rightArrowColor = $pressedColor;
}
echo("<html><head><style>");
echo("body{background-color:#000000;}
div#container{position:absolute;left:10px;top:10px;background-color:#eeeeee;
font-size:20px;padding:20px;width:100px;height:92px;text-align:center;}
div.arrow{position:absolute;width:30px;padding-top:2px;padding-bottom:2px;}
div#upArrow{left:55px;top:20px;background-color:#".$upArrowColor.";}
div#downArrow{left:55px;top:82px;background-color:#".$downArrowColor.";}
div#leftArrow{left:20px;top:50px;background-color:#".$leftArrowColor.";}
div#rightArrow{left:90px;top:50px;background-color:#".$rightArrowColor.";}
div#lastAction{position:absolute;left:0px;bottom:2px;font-size:14px;color:#ffffee;}");
echo("</style></head><body onload='parent.controllerReady();'>");
echo("<div id='container'>
<div class='arrow' id='upArrow'>↑</div><div class='arrow' id='downArrow'>↓</div>
<div class='arrow' id='leftArrow'>←</div><div class='arrow' id='rightArrow'>→</div>
</div><div id='lastAction'>Last Action:<br />".$action."</div>");
echo("</body></html>");
//cleanup input
function cleanupSpecialChars($inStr){
$tempStr = htmlentities(stripslashes($inStr));
$retStr = str_replace(array('\\','/'), '', $tempStr);
return $retStr;
}
function sendCMD($cmd){
if($fp =fopen("com4", "wb")){//windows server
fwrite($fp,$cmd);
usleep(15000);
fclose($fp);
}
else if($fp =fopen("/dev/ttyS3", "wb")){//linux server
fwrite($fp,$cmd);
usleep(15000);
fclose($fp);
}
}
?>
您可以在我的服务器上看到它们正在运行: http://www.vdstudios.net/robotics/FrontEnd.html
如果您向我提供设备所需内容的详细信息,我可以帮助您构建串口消息。
编辑:
添加了构建/发送消息到串行端口的代码。还使用相同的更新运行示例。您可以在上面的链接中看到它。
编辑2:
添加了缓冲keyEvents的代码 添加了用于同步后端和前端状态的代码。