переменная область действия в поведении JavaScript - PullRequest
0 голосов
/ 15 сентября 2011

У меня есть следующая функция 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 будет содержать элемент с идентификатором mailDeliveryOptionFS, но для двух других элементов в 2 других ветвях else fs оценивается как ноль, так что он не ' не попасть в условие if! Я думаю, что эта проблема как-то связана с переменной областью в javascript, но я не могу понять, в чем проблема

Ответы [ 3 ]

1 голос
/ 15 сентября 2011

Возможно, вы не ищете правильный идентификатор.Идентификаторы чувствительны к регистру, даже если вы сравните условие с идентификатором нижнего регистра, реальный идентификатор все равно будет регистром (как и для первого элемента, поскольку он единственный, который обнаруживается).

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";
        }
    }
} 
0 голосов
/ 15 сентября 2011

выглядит хорошо (хотя использование переключателя будет выглядеть лучше).Я не знаю, для чего используются эти звонки, но у вас есть разница в капитализации между первым и последним двумя.У вас есть «mailDeliveryOptionFS» в красивом верблюжьем футляре, но «faxdeliveryoptionFS» и «emaildeliveryoptionFS» - нет.Это может быть вашей проблемой?Измените их на "faxDeliveryOptionFS" и "emailDeliveryOptionFS" соответственно?

0 голосов
/ 15 сентября 2011

Измените свой код на это, чтобы правильно объявить локальную переменную 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";
        }
    }
}

Чтобы сделать эту более простую версию работоспособной, просто передайте идентификатор опции для переключения:

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";
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...