代码审查:高效?它会起作用吗?

时间:2010-10-26 21:10:28

标签: javascript

澄清

这是一个脚本的一部分,用于检查用户是否在表单中更改了和值。如果用户在更改值后尝试离开页面,则会通过onbeforeunload收到警报,并显示离开页面或停留的选项。

棘手的部分是确定(多个)选择列表的更改状态...这是该问题适用的地方。我只是想知道是否有人能够发现任何潜在的问题。

有人提到总是使用默认值进行比较可能没有意义。但是,在这种情况下确实有意义。如果用户更改了值,然后在离开页面之前将其更改回原始值,他们可能不希望“您在页面上更改了soemthing,离开还是留下?”警报弹出。


以下代码旨在检查选择列表(<select>),以查看“selected”属性是否与默认的“selected”属性相同。它应该适用于多选列表以及单选项选择列表。

如果所选选项与默认选项相同,则函数IsSelectChanged' should return为真if the selected option(s) are not the same as the default and为false。

代码:

<select>
    <option selected="selected">Opt 1</option>
    <option>Opt 2</option>
</select>
<script>
    // the code:
    function IsSelectChanged(select){
        var options = select.options,
            i = 0,
            l = options.length;
        // collect current selected and defaultSelected
        for (; i < l; i++) {
            var option = options[i];
            // if it was selected by default but now it is not
            if (option.defaultSelected && !option.selected) {
                return true;
            }
            // if it is selected now but it was not by default
            if (option.selected && !option.defaultSelected) {
                return true;
            }
        }
        return false;
    }

    // implementation:
    $("select").change(function(){
        doSomethingWithValue( IsSelectChanged(this) );
    });
</script>

代码应该适用于允许多个选择/初始选择的select列表以及单选变体(如上所示)。

有人能发现任何潜在的错误或效率低下吗?或者知道更好的方法吗?

由于

3 个答案:

答案 0 :(得分:5)

好吧,我不知道会有多么“高效”,但是你基本上在循环体中做了一个XOR(2 if语句),那么为什么不使用一个呢? IIRC,JS没有明确的XOR只有一个按位(更多信息)[^ https://developer.mozilla.org/en/JavaScript/Reference/Operators/Bitwise_Operators]。通过使用三元运算符传递值1或0,可以使用按位^来模拟实际的XOR,例如:

if ((option.defaultSelected ? 1 : 0) ^ (option.selected ? 1 : 0)) { return true }

如果您的目的是为了简洁(感谢@some的想法,请参阅此答案下方的评论以获取详细信息);

if (option.defaultSelected ^ option.selected) { return true }

将与代码中的两个if语句达到相同的效果。

答案 1 :(得分:1)

为什么要遍历选择器中的所有选项,你不能只选择所选的一个或默认的选择一个

$("select option:selected").doSomething();
$("select option.defaultSelected").doSomething();

我不知道你想用这些东西做什么。

答案 2 :(得分:1)

由于您正在测试false && truetrue && false,因此您应该能够使用!==,因为想法似乎是您希望return true不匹配。

if(option.defaultSelected !== option.selected) {
    return true;
}

此外,由于循环的顺序似乎并不重要,您应该能够使用while循环,这应该更有效。

var options = select.options,
    l = options.length;
while ( l-- ) {
   ...

这样就无需进行比较。