javascript行为中的变量范围

时间:2011-09-14 20:38:21

标签: javascript scope

我有以下javascript函数,它负责根据传递的参数在我的html页面中切换一些元素:

function toggleDeliveryOption(source) {
    if(source.toLowerCase() === "maildeliveryoption") 
    {
        var fs = document.getElementById("mailDeliveryOptionFS");
    }
    else if(source.toLowerCase() === "faxdeliveryoption")
    {
        var fs = document.getElementById("faxdeliveryoptionFS");
    }
    else if(source.toLowerCase() === "emaildeliveryoption")
    {
        var fs = document.getElementById("emaildeliveryoptionFS");
    }
    if(fs)
    {
        if(fs.style.display == "none")
            fs.style.display = "block";
        else
            fs.style.display = "none"
    }
} 

现在我们的行为是,如果source是第一个(maildeliveryoption)它工作,fs将保存id为mailDeliveryOptionFS的元素,但对于其他2个分支中的其他两个元素,fs计算为null,因此它不会进入if条件!我认为这个问题与javascript中的变量范围有关,但我无法弄清楚是什么问题

3 个答案:

答案 0 :(得分:1)

也许您没有找到合适的ID。 ID区分大小写,即使您将条件与小写ID进行比较,真实ID仍然是驼峰大小写(就像第一个元素一样,因为它是唯一被发现的元素)。

function toggleDeliveryOption( source )
{ 
    var source = source.toLowerCase(),
        id,
        fs;

    switch ( source ) 
    {
        case "maildeliveryoption":
            id = "mailDeliveryOptionFS";
            break;

        case "faxdeliveryoption":
            id = "faxDeliveryOptionFS";
            break;

        case "emaildeliveryoption":
            id = "emailDeliveryOptionFS";
            break;
    }

    fs = document.getElementById( id );

    if ( fs )
    {
        if ( fs.style.display == "none" )
        {
            fs.style.display = "block";
        }
    }
} 

答案 1 :(得分:0)

将代码更改为此,以正确声明局部变量fs一次。然后,您可以在代码的最后进行可靠的测试,看看它是否已经设置。您之前的代码可能因变量提升而起作用,但它不是推荐的编码方式。变量的范围是它声明的函数。

function toggleDeliveryOption(source) {
    var fs = null;
    if(source.toLowerCase() === "maildeliveryoption") 
    {
        fs = document.getElementById("mailDeliveryOptionFS");
    }
    else if(source.toLowerCase() === "faxdeliveryoption")
    {
        fs = document.getElementById("faxdeliveryoptionFS");
    }
    else if(source.toLowerCase() === "emaildeliveryoption")
    {
        fs = document.getElementById("emaildeliveryoptionFS");
    }
    if (fs)
    {
        if (fs.style.display == "none") {
            fs.style.display = "block";
        } else {
            fs.style.display = "none";
        }
    }
} 

另一个潜在的问题是,fs.style.display之前可能没有设置为读取样式变量,这样只返回HTML中的显式内联样式(它不返回通过CSS设置的内容)。如果您想知道显示设置的实际状态,则必须使用包含CSS设置的计算样式。获取计算的样式在Windows中是不同的,因此需要更多行代码才能执行此操作。这是我使用像YUI或jQuery这样的框架的原因之一,因为它会为我处理所有这些跨浏览器的混乱。

顺便说一下,您可以像这样简化代码:

function toggleDeliveryOption(source) {
    var fs = document.getElementById(source);
    if (fs) {
        if (fs.style.display == "none") {
            fs.style.display = "block";
        } else {
            fs.style.display = "none";
        }
    }
}

要使这个更简单的版本工作,只需将选项的id传递给toggle:

toggleDeliveryOption("mailDeliveryOptionFS");

如果你想要实际的显示状态,包括CSS设置,那么你需要使用它:

// add IE compatibility function for getComputedStyle
if (!window.getComputedStyle) {
    window.getComputedStyle = function(el, pseudo) {
        this.el = el;
        this.getPropertyValue = function(prop) {
            var re = /(\-([a-z]){1})/g;
            if (prop == 'float') prop = 'styleFloat';
            if (re.test(prop)) {
                prop = prop.replace(re, function () {
                    return arguments[2].toUpperCase();
                });
            }
            return el.currentStyle[prop] ? el.currentStyle[prop] : null;
        }
        return this;
    }
}


function toggleDeliveryOption(source) {
    var fs = document.getElementById(source);
    if (fs) {
        var style = getComputedStyle(fs, null);
        if (style.display == "none") {
            fs.style.display = "block";
        } else {
            fs.style.display = "none";
        }
    }
}

答案 2 :(得分:0)

看起来不错(虽然使用开关会看起来更好)。我不知道这些调用是用于什么,但你确实在第一个和后两个之间存在大写差异。在美丽的驼峰案例中你有“mailDeliveryOptionFS”但是“faxdeliveryoptionFS”和“emaildeliveryoptionFS”却没有。那可能是你的问题?分别将它们更改为“faxDeliveryOptionFS”和“emailDeliveryOptionFS”?