如何在svelte中使用子复选框切换父div的css属性的实现建议

khbbv19g  于 2023-03-20  发布在  其他
关注(0)|答案(2)|浏览(128)

这花了我很长的时间,我仍然认为我的实现是相当糟糕和混乱,现在我只是很大程度上感到困惑,为什么事情会打破,如果我删除checkedActivities.has(activity) ? "checked" : "unchecked",因为我认为我的 typescript 取代了这个功能。

<script context="module" lang="ts">
    import userActivities from "../userActivities.json";
    const activityArray: string[] = userActivities.activities.map(
        ([name, icon]) => name
    );
    export let selectedActivities: String[] = activityArray.slice(0, 3);

    let checkedActivities = new Set(activityArray.slice(0, 3));
    function toggleActivitySelection(activity: string) {
        let div = document.getElementById(activity);
        if (checkedActivities.has(activity)) {
            checkedActivities.delete(activity);
            div?.classList.remove("checked");
            div?.classList.add("unchecked");
        } else {
            checkedActivities.add(activity);
            div?.classList.remove("unchecked");
            div?.classList.add("checked");
        }
        console.log(checkedActivities);
    }
</script>

<div>
    <div class="heading-bar">
        <span>Saved activities</span>
        <form action="/activities">
            <button on:click={() => console.log(selectedActivities)}
                >Done</button
            >
        </form>
    </div>
    <div class="bg-container">
        {#each activityArray as activity}
            <div
                class={checkedActivities.has(activity) ? "checked" : "unchecked"}
                id={activity}
            >
                <label>
                    <input
                        class="input_checkbox"
                        id="input_checkbox"
                        type="checkbox"
                        bind:group={selectedActivities}
                        value={activity}
                        on:change={() => {
                            toggleActivitySelection(activity);
                        }}
                    />
                    {activity}
                </label>
            </div>
        {/each}
    </div>
</div>

<style>
    input[type="checkbox"] {
        width: 100%;
        height: 100%;
        display: none;
    }

    label {
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    div.checked:hover, div.unchecked:hover {
        border-left: 2px solid var(--color-text) !important;
        border-bottom: 2px solid var(--color-objects) !important;
        border-right: 2px solid var(--color-text) !important;
        border-top: 2px solid var(--color-objects) !important;
    } 

    div.checked {
        padding-top: 0.5em;
        padding-bottom: 0.5em;
        border-radius: 20px;
        margin: 0.5em 0;
        border-left: 2px solid var(--color-text) !important;
        border-bottom: 2px solid var(--color-objects) !important;
        border-right: 2px solid var(--color-text) !important;
        border-top: 2px solid var(--color-objects) !important;
    }

    div.unchecked {
        padding-top: 0.5em;
        padding-bottom: 0.5em;
        border-radius: 20px;
        margin: 0.5em 0;
        border-left: 2px solid var(--color-objects) !important;
        border-bottom: 2px solid var(--color-objects) !important;
        border-right: 2px solid var(--color-objects) !important;
        border-top: 2px solid var(--color-objects) !important;
    }

    .heading-bar {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        margin-top: 1.8em;
        margin-bottom: 0.6em;
    }

    .bg-container {
        border-radius: 12px;
        background-color: var(--color-objects);
        padding: 1em 1.4em;
    }

    #item {
        display: flex;
        align-items: center;
        justify-content: center;
    }

    button {
        background-color: var(--color-objects);
        border: none;
        color: var(--color-text);
        font-size: 1em;
        border-radius: 10px;
        padding: 0.5em 0.5em;
    }
</style>
2izufjch

2izufjch1#

你不应该像那样直接查询或者修改DOM,所有手动添加/删除类的代码都应该删除。
主要问题是checkedActivities在没有赋值的情况下发生了变化,这不会触发任何依赖于它的内容的更新。
切换功能应可简化为:

function toggleActivitySelection(activity: string) {
    checkedActivities.has(activity) ?
        checkedActivities.delete(activity) :
        checkedActivities.add(activity);

   checkedActivities = checkedActivities; // triggers updates
}

任何类更改都应在使用class属性或class:...指令的标记中发生。

fivyi3re

fivyi3re2#

我正在尝试使您的示例运行ts-example

<script lang="ts">
    const userActivities = {activities:[
      {name:"name1",icon:"icon",checked:false},  
      {name:"name2",icon:"icon",checked:false},
      {name:"name3",icon:"icon",checked:false} 
    ]}
  let selectedActivities:any
</script>

<div>
    <div class="heading-bar">
        <span>Saved activities</span>
        <form action="/activities">
            <button on:click={() => console.log(selectedActivities)}
                >Done</button
            >
        </form>
    </div>
    <div class="bg-container">
        {#each  userActivities.activities as i}
            <div
                class={i.checked ? "checked" : "unchecked"}>
                <label> {i.name} 
                  <input type="checkbox" bind:checked={i.checked} on:change={_ = >selectedActivities = i} />
                </label>
               
            </div>
        {/each}
    </div>
</div>

<style>
    input[type="checkbox"] {
        width: 100%;
        height: 100%;
        /* display: none; */
    }

    label {
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    div.checked:hover, div.unchecked:hover {
        border-left: 2px solid var(--color-text) !important;
        border-bottom: 2px solid var(--color-objects) !important;
        border-right: 2px solid var(--color-text) !important;
        border-top: 2px solid var(--color-objects) !important;
    } 

    div.checked {
      color: green;
    
    }

    div.unchecked {
     color:red;
    }

   

</style>

相关问题