我正在尝试编写一个小的javascript函数,它从OpenSignal中获取数据,然后将其显示在html表中。
这个工作正常,直到我试图通过添加html表单来接受邮政编码输入来使用户友好。我试图避免使用PHP来执行此操作,因为我的客户端没有安装此功能。
我在提交按钮中添加了一个事件监听器,以检测表单数据的提交时间。我接着这个并验证字符串包含有效的邮政编码。如果他们无效,该程序会发出一条警告,表示"抱歉,但您似乎输入了错误的邮政编码。"。
如果没有,那么我将采用邮政编码并将它们传递给我的函数processPostcodesOnServer()。问题是,这在事件监听器内部不起作用。当我使用javascript数组手动传递postcode并在事件监听器之外调用函数时,一切正常。当我把它放在事件监听器中时,它根本不起作用。我检查了函数的所有输入都是正确的并且已经多次遍历整个程序并且无法找出导致问题的原因。在我看来,这只是Javascripts随机行为的另一个案例。
任何人都可以帮忙吗?这是我的HTML和Javascript文件(我正在使用一些JQuery,所以如果你想运行它,你必须链接到最新版本。)
<!DOCTYPE html>
<html>
<head>
<title>Mobile Signals</title>
<script src="jquery-1.11.3.min.js"></script>
<script src="NetworkStats.js"></script>
</head>
<body>
<form id="postcodeForm">
Enter postcodes separated by commas<br>
<input type="text" id="postcodes" name="postcodes">
</br></br>
<input type="submit" value="Submit" id="submitButton">
</form>
<div id="theDiv">
</div>
<div id ="secondDiv"> </div>
<table id="theTable" border="1">
</table>
和Javascript
$( document ).ready(function() {
document.getElementById('submitButton').addEventListener('click', function() {
var input = $('#postcodeForm').serializeArray();
var postcodeString = input[0]["value"];
var output = postcodeString.split(",");
var postcodeString = "";
// check each postcode to see if there is any false postcodes
for (var postcode in output) {
var newPostcode = checkPostCode(output[postcode]);
if (newPostcode) {
postcodeString += " true ";
} else {
postcodeString += " false ";
}
}
if (postcodeString.indexOf("false") >= 0) {
// string contains a false so output an error message
window.alert("Sorry but you seem to have entered an incorrect postcode.")
} else {
// all the postcodes are correct, proceed to perform operations on them
processPostcodesOnServer(output);
}
}, false);
function processPostcodesOnServer(output) {
var apiKey = "c590c63f5b3818271a87a3e89fa215ae";
var distance = 10;
var tableNumber = 0;
//var output = ["WR141NE"];
for (var postcode in output) {
strippedPostcode = output[postcode].replace(/ /g,'');
getLatAndLong(strippedPostcode);
}
function googleCallback(latitude, longitude, postcode) {
contactServer(latitude, longitude, postcode);
}
/* Function to contact google and convert the postcode to lat long */
function getLatAndLong(postcode) {
var latitude;
var longitude;
var googleXmlHttp = new XMLHttpRequest();
var googleUrl = "http://maps.googleapis.com/maps/api/geocode/json?address="+ postcode + "&sensor=false";
googleXmlHttp.onreadystatechange = function() {
if (googleXmlHttp.readyState == 4 && googleXmlHttp.status == 200) {
var latLong = JSON.parse(googleXmlHttp.responseText);
latitude = latLong.results[0].geometry.location.lat;
longitude = latLong.results[0].geometry.location.lng;
googleCallback(latitude, longitude, postcode);
}
}
googleXmlHttp.open("GET", googleUrl, true);
googleXmlHttp.send();
}
function contactServer(latitude, longitude, postcode) {
var xmlhttp = new XMLHttpRequest();
var networkStatsUrl = "http://api.opensignal.com/v2/networkstats.json?lat="+latitude+"&lng="+longitude+"&distance=" + distance + "&apikey=" + apiKey;
/*
Functions to contact server and read JSON response back for NetworkStats
*/
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var myArr = JSON.parse(xmlhttp.responseText);
sortTableData(myArr, postcode);
//displayData(myArr);
}
}
xmlhttp.open("GET", networkStatsUrl, true);
xmlhttp.send();
var functionCount = -1;
function sortTableData(arr, postcode) {
tableNumber++;
$("body").append("</br>" + postcode + "</br>");
theTable = "<table id='table"+ tableNumber + "' border='1'> </table>"
$("body").append(theTable);
var column1 = new Array();
var column2 = new Array();
var column3 = new Array();
var column4 = new Array();
var column5 = new Array();
var column6 = new Array();
var column7 = new Array();
//var output = '<table border="1">';
//var output = "";
for (var obj in arr) {
// find all the networks
if ((typeof arr[obj] === 'object') && (obj == "networkRank")) {
var networks = new Object();
networks = arr[obj];
var allNetworkKeys = Object.keys(networks);
//console.log(allNetworkKeys);
var networksArray = new Array();
$.each(networks, function(networkKey, networkValue){
//Do something with your key and value.
column1.push(networkKey);
if (networkKey.substring(0, 7) == "network") {
$.each(networkValue, function(networkTypeKey, networkTypeValue){
if (networkTypeKey == "type2G") {
column2.push('');
column3.push(networkTypeKey);
for (var variable in networkTypeValue) {
column2.push(variable);
column3.push(networkTypeValue[variable]);
}
} else if (networkTypeKey == "type3G") {
column4.push('');
column5.push(networkTypeKey);
for (var variable in networkTypeValue) {
column4.push(variable);
column5.push(networkTypeValue[variable]);
}
} else if (networkTypeKey == "type4G") {
column6.push('');
column7.push(networkTypeKey);
for (var variable in networkTypeValue) {
column6.push(variable);
column7.push(networkTypeValue[variable]);
}
}
});
//console.log(column1);
}
//console.log(column1, column2, column3, column4);
displayTable(column1, column2, column3, column4, column5, column6, column7);
column1 = []; column2 = []; column3 = []; column4 = []; column5 = []; column6 = []; column7 = [];
});
}
}
}
var counter = 0;
function displayTable(column1, column2, column3, column4, column5, column6, column7) {
var output = ""
//console.log(counter);
counter++;
var column1Length = column1.length;
var column2Length = column2.length;
var column3Length = column3.length;
var column4Length = column4.length;
var column5Length = column5.length;
var column6Length = column6.length;
var column7Length = column7.length;
var highestNumber = Math.max(column1Length, column2Length, column3Length, column4Length, column5Length, column6Length, column7Length);
for (var i=0; i<highestNumber; i++) {
var column1Reference = column1[i];
var column2Reference = column2[i];
var column3Reference = column3[i];
var column4Reference = column4[i];
var column5Reference = column5[i];
var column6Reference = column6[i];
var column7Reference = column7[i];
if (column1Reference === void 0) {
column1Reference = " "
}
if (column2Reference === void 0) {
column2Reference = " "
}
if (column3Reference === void 0) {
column3Reference = " "
}
if (column4Reference === void 0) {
column4Reference = " "
}
if (column5Reference === void 0) {
column5Reference = " "
}
if (column6Reference === void 0) {
column6Reference = " "
}
if (column7Reference === void 0) {
column7Reference = " "
}
output += "<tr>";
output += "<td>" + column1Reference + "</td>";
output += "<td>" + column2Reference + "</td>";
output += "<td>" + column3Reference + "</td>";
output += "<td>" + column4Reference + "</td>";
output += "<td>" + column5Reference + "</td>";
output += "<td>" + column6Reference + "</td>";
output += "<td>" + column7Reference + "</td>";
output += "</tr>";
}
//output += "</table>";
//var table = document.getElementById('theTable');
//console.log(output);
//oldOutput = table.innerHTML;
//table.innerHTML = oldOutput + output;
$("#table" +tableNumber).append(output);
console.log(output);
}
}
}
});
答案 0 :(得分:1)
好吧,我明白了。
如果只提交表单不会重新加载页面,那么实际上会显示该表。
有两种解决方法:
click
处理程序更改为submit
处理程序并取消活动!替换
document.getElementById('submitButton').addEventListener('click', function() {
// ...
}, false);
通过
document.getElementById('postcodeForm').addEventListener('submit', function(event) {
event.preventDefault();
// ...
}, false);
这就像从HTML代码中删除<form id="postcodeForm">
和</form>
一样简单,但由于您在JS中使用$('#postcodeForm')
,因此您将不得不进行更改
var input = $('#postcodeForm').serializeArray();
var postcodeString = input[0]["value"];
var output = postcodeString.split(",");
到
var output = document.getElementById('postcodes').value.split(",");
使它工作。
(内联postcodeString
实际上并不是必需的,但我建议,见下文。)
如果您选择此选项,我建议您从name
删除#postcodes
属性,因为它没有用处。
但无论您选择哪个选项,都应该修复所有</br>
:HTML 5中的<br>
(HTML 4中为<br/>
,但是永远不会</br>
)
(不要忘记你的JS中的那些!)
如果googleCallback
函数只将参数传递给具有完全相同参数列表的函数,那么contactServer
函数的优点是什么?为什么不直接使用var postcodeString = "";
// check each postcode to see if there is any false postcodes
for(var postcode in output)
{
var newPostcode = checkPostCode(output[postcode]);
if(newPostcode)
{
postcodeString += " true ";
}
else
{
postcodeString += " false ";
}
}
if(postcodeString.indexOf("false") >= 0)
{
// string contains a false so output an error message
window.alert("Sorry but you seem to have entered an incorrect postcode.")
}
else
{
// all the postcodes are correct, proceed to perform operations on them
processPostcodesOnServer(output);
}
?
这段代码效率很低:
// check each postcode to see if there is any invalid postcodes
for(var postcode in output)
{
if(checkPostCode(output[postcode]) === false)
{
// current postcode is invalid so output an error message and return
window.alert("Sorry but you seem to have entered an incorrect postcode.");
return;
}
// at this point, all the postcodes are valid, proceed to perform operations on them
processPostcodesOnServer(output);
我的意思是,字符串,真的吗?考虑:
var column1Length = column1.length;
var column2Length = column2.length;
var column3Length = column3.length;
var column4Length = column4.length;
var column5Length = column5.length;
var column6Length = column6.length;
var column7Length = column7.length;
var highestNumber = Math.max(column1Length, column2Length, column3Length, column4Length, column5Length, column6Length, column7Length);
此外,您只使用了很多变量一次,导致相当大的开销 例如,这个:
var highestNumber = Math.max(column1.length, column2.length, column3.length, column4.length, column5.length, column6.length, column7.length);
可以缩短到这一点:
displayTable
当然这会让线条变长一点,但是对于7个额外的字符,你可以节省7行!
或者,您的function displayTable()
{
var output = '';
var highestNumber = Math.max(arguments[0].length, arguments[1].length, arguments[2].length, arguments[3].length, arguments[4].length, arguments[5].length, arguments[6].length);
for(var i = 0; i < highestNumber; i++)
{
output += '<tr>';
for(var j = 0; j < 7; j++)
{
output += '<td>' + arguments[j][i] + '</td>';
}
output += '</tr>';
}
$('#table' + tableNumber).append(output);
}
功能可以真正缩短为:
{1}
然后,您的RegEx中有很多[0-9]{1}
- 为什么? [0-9]
等于\d
(或\
,但如果在字符串中使用它,请小心转义<input id="hm" type="tel" size="4" maxlength="3" onchange="changeHandler(this)"/>
。
最后,我建议你通过JSHint或类似的东西来运行代码以消除不一致性(小心JS L int虽然,那个人有非常积极和不合理的约定)。
答案 1 :(得分:0)
你有var postcodeString
两次。
var
关键字每个范围只能使用一次。