【问题标题】:How to change all elements except clicked element?如何更改除单击元素之外的所有元素?
【发布时间】:2019-05-01 17:24:15
【问题描述】:

我正在使用 Javascript 和 D3.js 进行世界地图可视化。当您单击一个国家/地区时,所有其他国家/地区都会获得一个 inactiveCountry 类,它会添加一个 opacity: 0.3,它会突出显示所选国家/地区。我想要的是,当您再次单击突出显示的国家/地区时,所有其他国家/地区都失去了 inactiveCountry 类,因此他们再次拥有 opacity: 1

这是地图:

选择国家时:

以下是绘制地图并为其着色的代码:

        g.selectAll("path").data(countries.features)
            .enter().append("path")
            .attr("d", pathGenerator)
            .attr("class", "country")
            .attr("id", function (d){
                return d.properties.name
            })
            .attr("fill", function (d) {
                return colorScaleWorldmap(colorValue(d))
            })
            .on("click", function (d) {
                changeCountry(d.properties.name);
            })
            .append("title")
            .text(function (d) {
                return d.properties.name + ": " + colorValue(d);
            });

如您所见,当您单击一个国家/地区时,它会运行函数changeCountry();,即:

function changeCountry(countryName) {

    country = countryName;
    console.log(country);

    let totalCountries = document.getElementsByClassName("country");

    // Remove class countryActive from previous selection
    for (let i = 0; i < totalCountries.length; i++) {
        if (totalCountries[i].classList.contains("countryActive")) {
            totalCountries[i].classList.replace("countryActive", "countryInactive")
        }
    }

    // Add class countryActive to selected country
    let element = document.getElementById(country);
    element.classList.add("countryActive");

    for (let i = 0; i < totalCountries.length; i++) {
        if (totalCountries[i].classList.contains("countryActive")) {
            totalCountries[i].classList.remove("countryInactive")
        } else {
            totalCountries[i].classList.add("countryInactive")
        }
    }
}

我将如何添加一个交互,当您再次单击所选国家/地区时,所有国家/地区都变得可见(从而失去了countryInactive 类)?我尝试过使用 JQuery .click.data 组合:

    $("#" + country).click(function(){
        $(this).data('clicked', true);
    });

    if($("#" + country).data('clicked')) {
        alert('yes');
    }

这段代码的问题是,一旦我至少点击了一个国家/地区,它似乎会保留true 语句,所以即使我在它处于非活动状态时点击它,我也会收到yes 警报.

【问题讨论】:

    标签: javascript function d3.js click


    【解决方案1】:

    试试这个代码:

    function changeCountry(countryName) {
    
        let clickedContry = document.getElementById(countryName);
        let totalCountries = document.getElementsByClassName("country");
    
        if(clickedContry.classList.contains("countryActive")) {
            for (let i = 0; i < totalCountries.length; i++) {
                if (totalCountries[i].classList.contains("countryInactive")) {
                    totalCountries[i].classList.replace("countryInactive", "countryActive");
                }
            }
        } else {
            // Remove class countryActive from previous selection
            clickedContry.classList.add("countryActive");
        }
    }
    

    .

    但是请记住..当您点击一个国家而用户点击另一个国家时会发生什么。

    祝你好运!

    【讨论】:

    • 虽然您的解决方案没有完全为我解决问题,但您的回答对解决我的问题有很大帮助。如果您有兴趣看到它,我会用我自己的答案回答这个问题。谢谢!
    【解决方案2】:

    在解决方案thiagotrss 的帮助下,我设法自己解决了这个问题。我就是这样做的:

    function changeCountry(countryName) {
    
        let totalCountries = document.getElementsByClassName("country");
        let clickedCountry = document.getElementById(countryName);
        country = countryName;
        console.log(country);
    
        if (clickedCountry.classList.contains("countryActive")) {
            clickedCountry.classList.remove("countryActive")
            country = "Total countries";
    
            for (let i = 0; i < totalCountries.length; i++) {
                if (totalCountries[i].classList.contains("countryInactive")) {
                    totalCountries[i].classList.remove("countryActive")
                    totalCountries[i].classList.remove("countryInactive")
                }
            }
        } else {
            for (let i = 0; i < totalCountries.length; i++) {
                if (totalCountries[i].classList.contains("countryActive")) {
                    totalCountries[i].classList.remove("countryActive")
                } else if (!totalCountries[i].classList.contains("countryActive")) {
                    totalCountries[i].classList.add("countryInactive")
                }
            }
            clickedCountry.classList.add("countryActive")
        }
    }

    【讨论】: