问题
Javascript is not my first language of choice, nor is it one I am all that well versed in. Functional stuff fine, objects, not so much.
I am looking to see if anyone can suggest options for dealing with the following scenario.
function postcodeEntry(destination,postcode) {
"use strict";
document.getElementById('googlemappostcode').innerHTML = <?php if ($_GET['page']==="fun") echo "<div id=\"map\"></div>' + ";?>'<form id="postcodeEntry" method="post" action="/" onsubmit="calcRoute(\'driving\',this.postcode.value,' + destination.hb + ',' + destination.ib + ',\'' + postcode + '\');return false;">'
+ '<h2>Get directions</h2>'
+ '<fieldset>'
+ '<input type="hidden" name="action" value="gmap-directions" />'
+ '<p class="where"><a href="/contact/" onclick="geoLoc();return false;">Where am I?</a></p>'
+ '<label for="postcode">Enter your postcode for directions</label>'
+ '<input type="text" name="postcode" id="postcode" onfocus="checkthis(this,\'Your Postcode/Address:\')" onblur="checkthis(this,\'Your Postcode/Address:\')" value="Your Postcode/Address:" />'
+ '<input type="submit" name="submitTravelType" value="Driving" id="gms_driving" onclick="calcRoute(\'driving\',document.getElementById(\'postcode\').value,' + destination.hb + ',' + destination.ib + ',\'' + postcode + '\');return false;" />'
+ '<input type="submit" name="submitTravelType" value="Walking" id="gms_walking" onclick="calcRoute(\'walking\',document.getElementById(\'postcode\').value,' + destination.hb + ',' + destination.ib + ',\'' + postcode + '\');return false;" />'
+ '<input type="submit" name="submitTravelType" value="Public Transport" id="gms_transit" onclick="calcRoute(\'transit\',document.getElementById(\'postcode\').value,' + destination.hb + ',' + destination.ib + ',\'' + postcode + '\');return false;" />'
+ '<input type="submit" name="submitTravelType" value="Cycling" id="gms_bicycling" onclick="calcRoute(\'bicycling\',document.getElementById(\'postcode\').value,' + destination.hb + ',' + destination.ib + ',\'' + postcode + '\');return false;" />'
+ '</fieldset>'
+ '</form>'
+ '<div id="directions"></div>';
}
function initialize() {
"use strict";
var contentString, destination, el, entryPanoId, i, image, infowindow, links, mapOptions, panoId, panoOptions, radius, shadow, shape;
/* Destination becomes a four part array. 1st being lat, 2nd being long, 3rd being a google maps latlng and the 4th being postcode */
destination = [<?php echo $venue['latlong']?>];
destination[2] = new google.maps.LatLng(destination[0], destination[1]);
destination[3] = '<?php echo $venue['postcode']?>';
postcodeEntry(destination[2], destination[3]);
directionsService = new google.maps.DirectionsService();
directionsDisplay = new google.maps.DirectionsRenderer();
trafficLayer = new google.maps.TrafficLayer();
streetviewService = new google.maps.StreetViewService();
...
When the initialising function is called it does it's bit and makes the map fine. The postcode/location entry works perfectly. In fact it all works, no problems with that.
My question is being as some info is shot off to the postcode form, the return from that form goes to either the geoLoc or calcRoute functions. This of course means I lose contact with anything set up in the initialization function.
This means I have to use quite a number of global variables including but not limited to every one of those items in the shown script segment.
I am trying to learn more about the language and become more proficient in it's use. As a result, I would like (mostly out of pure stubbornness) to try and reduce the globals to none (if that's possible) or as few as possible.
Is there some way to solve this? I do not know much about javascript objects but I am learning all the time so somehow turn the initialize function into an object that then contains all the other objects? (Considering how little I know about javascript objects currently, that might actually be completely mad)
回答1:
I'd normally use a constructor/prototype (forgot what the proper term is) approach when I need to do something like this.
eg.
// This is the constructor
function initialise(){
// Add various settings values here
this.foo = 'bar';
}
// These are some publicly accessible methods
initialise.prototype = {
alertFoo: function(){
alert(this.foo); // The value of foo can be accessed via this.foo
},
consolelogFoo: function(){
console.log(this.foo);
}
}
You can then create an initialise object, like so:
var obj = new initialise();
and call the public functions like so:
obj.alertFoo();
This is just a brief example of this approach. You'll need to implement your code yourself, but to give you a brief idea of how you can go about doing this, here's what I would have done.
function initialize(options){ // options can be an object with stuff from data-* attributes
this.destination = {};
this.destination.coords = new google.maps.LatLng(options.lat, options.long);
this.destination.postcode = options.postcode;
this.directionsService = new google.maps.DirectionsService();
this.directionsDisplay = new google.maps.DirectionsRenderer();
this.trafficLayer = new google.maps.TrafficLayer();
this.streetviewService = new google.maps.StreetViewService();
....
}
initialize.prototype = {
geoLoc: function(){
// do stuff
},
calcRoute: function(){
// do stuff
}
}
This way, when you need to update the value for eg. destination coordinates, you only have to tell your public method to update the this.destination.coords property.
As for the HTML code, I'd advise you to avoid injecting HTML code using JS as far as possible. It's just not a good practice.
Additionally, I also don't recommend mixing PHP code into your JS code. It's better to keep them separate, and use data-* attributes when you need to supply your JS code something from PHP.
I hope this helps.
EDIT: In answering your question about how to handler the form submit event, you can do something like this:
function initialize(){
....
this.form = document.form1; // Assuming you have a form called form1
this.init();
}
initialize.prototype = {
init: function(){ // I usually use this approach for attaching event handlers and other stuff so as keep the constructor clean, and separate the concerns
this.form.onsubmit = this.formHandler;
},
....
formHandler: function(){ // This is the form handler
alert(this.textField1.value); // Assuming form1 has a field called textField1
return false; // This will prevent the form from being submitted via traditional page POST request
},
....
};
来源:https://stackoverflow.com/questions/15198102/reducing-global-variables-and-maintaining-function-flow