【问题标题】:Difference between x = document.getElementById("id").className = & x = document.getElementById("id"), x.className =x = document.getElementById("id").className = & x = document.getElementById("id"), x.className = 的区别
【发布时间】:2018-03-26 16:56:40
【问题描述】:

下面的代码有什么区别:

<div class="w3-dropdown-click">
    <button class="w3-btn" onclick="clickDrp()">Hover Over me</button>
    <div class="w3-dropdown-content w3-animate-zoom w3-bar-block" id="cont">        
        <a href="#" class="w3-bar-item w3-button">SomeLink1</a>
        <a href="#" class="w3-bar-item w3-button">SomeLink2</a>
        <a href="#" class="w3-bar-item w3-button">SomeLink3</a>
        <a href="#" class="w3-bar-item w3-button">SomeLink4</a>
    </div>
</div>
<script type="text/javascript">
    function clickDrp(){
        var x = document.getElementById("cont").className;
        if(x.search("w3-show") == -1)
            x += " w3-show";
        else
            x = x.replace(" w3-show","");
    }
</script>

<div class="w3-dropdown-click">
    <button class="w3-btn" onclick="clickDrp()">Hover Over me</button>
    <div class="w3-dropdown-content w3-animate-zoom w3-bar-block" id="cont">        
        <a href="#" class="w3-bar-item w3-button">SomeLink1</a>
        <a href="#" class="w3-bar-item w3-button">SomeLink2</a>
        <a href="#" class="w3-bar-item w3-button">SomeLink3</a>
        <a href="#" class="w3-bar-item w3-button">SomeLink4</a>
    </div>
</div>
<script type="text/javascript">
    function clickDrp(){
        var x = document.getElementById("cont");
        if(x.className.search("w3-show") == -1)
            x.className += " w3-show";
        else
            x.className = x.className.replace(" w3-show","");
    }
</script>

在第二个下拉菜单中工作正常。 首先,即使 x 被设为全局变量,它也不会。

我是 Javascript 新手,我无法弄清楚原因。 有人可以推理吗?

PS:我用过 w3-css

【问题讨论】:

    标签: javascript jquery html javascript-objects dom-events


    【解决方案1】:

    在第一个变体中,您的变量xclassName 字符串的副本。您对x 所做的任何更改都将针对该变量,而不是针对原始className 属性值。

    在第二个变体中,您的变量 xgetElementById 返回的对象引用的副本。只要您不为x 分配新值,它就会指向DOM 对象。对x 进行的任何mutation(即通过分配给它的属性之一,例如className)都会影响 DOM 对象,因此效果将在 Web 文档上可见。

    【讨论】:

    • 如果 x 是一个全局变量呢??
    • @PrajvalM 没有区别。
    • @PrajvalM,这无关紧要。当您将字符串值分配给变量(本地、全局或某个对象的属性 - 没关系)时,您正在分配一个副本。字符串是原始值(不可变)。更改className 属性值的唯一方法是为其分配一个新字符串。您不能通过分配给变量来做到这一点,它必须是 className 属性。
    • 有没有一种方法可以让我在代码的第 1 部分中一步将 x 引用到 document.getElementById("cont").className。
    • 不,这是不可能的。正如我所解释的,当您分配一个字符串时,您不会分配一个引用(这也是不可能的),而是实际的原始值。将其他内容分配给x 永远不会影响分配给x 的内容最后一次分配之前。这适用于 all 分配,无论数据类型如何。克服这个问题的方法正是变体 2 所做的:使用对象引用并分配给对象属性。
    【解决方案2】:

    您的问题表述不正确。区别在于

    x = document.getElementById(“id”).className;
    x = ...;
    

    x = document.getElementById(“id”);
    x.className = ...;
    

    这是一个更简单的问题示例:

    // Case 1
    var a = { foo: "bar" };
    var b = a.foo;
    b += "baz";
    console.log(a.foo); // "bar"
    console.log(b); // "barbaz"
    
    // Case 2
    var a = { foo: "bar" };
    var b = a.foo;
    a.foo += "baz";
    console.log(a.foo); // "barbaz"
    console.log(b); // "bar"
    

    赋值a.foo += "baz"; 在语义上与a.foo = a.foo + "baz"; 相同,或者,在您的情况下:

    x.className = x.className + " w3-show";
    

    通过使用+= operator,您创建了一个新字符串,然后将该字符串分配给x.className。这是因为 x 上的属性“className”是对象属性映射到字符串值“bar”(more on object properties)的键。

    【讨论】:

      【解决方案3】:

      我问这样的问题真是愚蠢。问题是 x 这里返回一个单独副本的字符串,而不是如果我只返回 x 作为 document.getElementById('id') 将返回一个通过引用传递的对象,因此可以修改 x。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-07
        • 2010-11-27
        • 2011-10-23
        相关资源
        最近更新 更多