减少全局变量并保持功能流

时间:2013-03-04 09:17:55

标签: javascript google-maps google-maps-api-3 javascript-objects

Javascript不是我选择的第一语言,也不是我精通的所有语言。 功能性的东西很好,对象,而不是。

我希望看看是否有人可以建议处理以下情况的选项。

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();
    ...

当调用初始化函数时,它会使它成为位并使地图变好。邮政编码/位置输入完美无缺。事实上,这一切都有效,没有问题。

我的问题是,当一些信息被拍摄到邮政编码表格时,从该表格返回到geoLoc或calcRoute函数。这当然意味着我失去了与初始化函数中设置的任何东西的联系。

这意味着我必须使用相当多的全局变量,包括但不限于所示脚本段中的每个项目。

我正在尝试更多地了解这种语言,并且更加熟练地使用它。因此,我希望(主要是出于纯粹的固执)尝试将全局变为无(如果可能的话)或尽可能少。

有什么方法可以解决这个问题吗?我不太了解javascript对象,但我一直在学习,所以不知何故将初始化函数转换为一个对象,然后包含所有其他对象? (考虑到我目前对javascript对象知之甚少,实际上可能完全疯了)

1 个答案:

答案 0 :(得分:1)

当我需要做这样的事情时,我通常会使用构造函数/原型(忘记正确的术语)方法。

例如

// 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);
    }
}

然后,您可以创建一个初始化对象,如下所示:

var obj = new initialise();

并像这样调用公共函数:

obj.alertFoo();

这只是这种方法的一个简单例子。你需要自己实现你的代码,但为了简要介绍一下你如何做到这一点,这就是我要做的。

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.destination.coords属性。

至于HTML代码,我建议你尽量避免使用JS注入HTML代码。这不是一个好习惯。

此外,我也不建议将PHP代码混合到JS代码中。最好将它们分开,并在需要从PHP提供JS代码时使用data- *属性。

我希望这会有所帮助。

编辑:在回答有关如何处理表单提交事件的问题时,您可以执行以下操作:

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
    },
    ....
};