2011-11-02 6 views
0

В приведенном ниже коде я передаю элемент HMTL и проверяю, был ли переданный параметр пустым или не использовался тернарный оператор. Если это не null, я изменяю className переданного элемента.Проверка нулевого значения с помощью тройного оператора

var changeColorTo = { 

    grey: function(e){ 
    e ? (e.className = "grey") : "" ; 
    }, 
    red: function(e){ 
    e ? (e.className = "red") : "" ; 
    }, 
    green: function(e){ 
    e ? (e.className = "green") : "" ; 
    }, 
    blue: function(e){ 
    e ? (e.className = "blue") : "" ; 
    } 
}; 

Приведенный выше код работает отлично, за исключением, когда я прохожу любую случайную строку как

changeColorTo.grey("random"); 

Это не вызывает никакого вреда. Но мне интересно, правильно ли код? Мне что-то не хватает? или есть лучший способ добиться такого же результата?

спасибо.

+0

Если вы хотите быть коротким и кратким, вы можете написать 'e && e.className && (e.className =" gray ");' без тройного. – david

+0

Если «короче» означает меньше кода, тогда это не 43 символа против 32 в OP. И меньше кода само по себе не является серьезной причиной для чего-либо. – RobG

ответ

3

Вы можете расширить свое состояние от e до (e && e.className). Это должно предотвратить ошибки сценария, возникающие при передаче в случайном нежелательном или даже неэлементном узлах.

Лучше, используйте это условие как function hasClassName(e) { return ... } и используйте hasClassName(e) как ваш тест.

РЕДАКТИРОВАТЬ: Заменено несовместимо (typeof e=="object") && ('className' in e) состояние, за комментарии. См. Также How do I check if an object has a property in JavaScript?

+0

Если * e * - объект-хост, нет оснований полагать, что он вернет «объект» для теста типа (объекты-хосты не должны соответствовать ECMA-262, а во многих случаях этого не делать). Таким образом, вышеприведенный тест скорее подвержен ошибкам, чем что-то вроде 'if (e && e.className) ...', если * e * уже имеет свойство * className *. – RobG

+0

Интересно. Раньше я не сталкивался с объектами-объектами, не относящимися к объекту, но мы были сосредоточены исключительно на популярных браузерах для ПК/Mac. Но не могли ли они затем решить, чтобы исключить исключение из поиска члена или вернуть значение, которое взрывается в булевом тесте? –

+0

Неверные хост-объекты являются общими, те, которые реализованы с использованием ActiveX в IE, являются печально известными (или печально известными) для него. Хотя браузеры начинают стандартизоваться на JavaScript ™, согласованно с ECMA-262 и внедрять наследование прототипов для объектов DOM, намерение DOM должно быть нейтральным по отношению к языку, поэтому ожидая, что объекты-хосты для реализации поведения и особенностей одного цветного языка не будут дух Интернета (хотя HTML5, похоже, в значительной степени обошлось без этого). – RobG

1

Код в его нынешнем виде будет работать, если вы передадите строку. Тем не менее, если вы хотите быть уверены, что вы передаете только в элемент DOM (лучше быть строгим), вы можете изменить свой код к этому:

function isNode(o){ 
    return (
    typeof Node === "object" ? o instanceof Node : 
    typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName==="string" 
); 
}  

function isElement(o){ 
    return (
    typeof HTMLElement === "object" ? o instanceof HTMLElement : //DOM2 
    typeof o === "object" && o.nodeType === 1 && typeof o.nodeName==="string" 
); 
} 

var changeColorTo = { 
    grey: function(e) { 
     isNode(e) || isElement(e) ? (e.className = "grey") : "" ; 
    }, 
    ... 
} 

Для получения дополнительной информации о том, как isNode и isElement работы , взгляните на this stackoverflow answer. Этот код также будет гарантировать, что вы не будете пытаться изменить атрибут переменной null или undefinedclassName с первым условием в каждом из этих функций (o instanceof Node и o instanceof HTMLElement) потерпит неудачу, которая гарантирует, что isNode и isElement возвратят ложь для null и undefined значений.

+0

@RobG Есть ли у вас конкретные примеры того, какие браузеры, в которых это произойдет? Я использовал это раньше (см. Связанный ответ), и он работал над основными браузерами (FF, Chrome, IE, Opera) без проблем. –

+0

Я все еще пытаюсь расшифровать вышеупомянутые функции. Для меня это немного сложно. Но мой первоначальный тест показывает, что Chrome возвращает false для (** typeof Node === "object" ** и ** typeof HTMLElement === "object") ** обе функции. Но я понятия не имею, почему это так. Он работает для моей проблемы, но делает больше, чем я хочу. Ответ RobG очень короткий. Спасибо – indusBull

+0

@indusBull Работает ли 'isElement' для вас в Chrome? –

Смежные вопросы