Скрипт для отображения / скрытия при нажатии — как мне написать этот очиститель кода?

У меня есть этот простой код, но он беспорядочный — как мне его очистить?

Это работает так: если вы нажмете на menu-btn1 то div появляется и скрывает других, но если вы нажмете на menu-btn1 снова он тоже скроется.

let coll = document.getElementsByClassName('collection');
let dis = document.getElementsByClassName('display');
let drop = document.getElementsByClassName('drop');

document.getElementById("menu-btn1").addEventListener("click", function() {
  if(coll[0].style.display == 'none') {
    coll[0].style.display = 'block';
    dis[0].style.display = 'none';
    drop[0].style.display = 'none';
  } else {
    coll[0].style.display = 'none';
  }
});
<div class="menu">
    <span id="text"><span id="menu-btn1">collection</span></span>
</div>

<div class="collection" style="display:none;"></div>
<div class="display" style="display:none;"></div>
<div class="drop style="display:none;"></div>

На самом деле в css нет ничего важного, только позиционирование сетки.

1 ответ
1

Сначала я думаю, что используя document.querySelector кажется намного удобнее, чем использование document.getElementsByClassName. Вместо let coll = document.getElementsByClassName('collection'); coll[0].xxx, мы можем просто использовать document.querySeletor('collection').xxx.

Таким образом, код можно немного реорганизовать, чтобы

    let coll = document.querySelector('.collection');
    let dis = document.querySelector('.display');
    let drop = document.querySelector('.drop');

    document.getElementById("menu-btn1").addEventListener("click", function() {
        if(coll.style.display == 'none') {
            coll.style.display = 'block';
            dis.style.display = 'none';
            drop.style.display = 'none';
        } else {
            coll.style.display = 'none';
        }
    });

Затем я помещу код извлечения DOM в обработчик событий, чтобы предотвратить ненужное загрязнение пространства имен. Хотя, возможно, в вашем рабочем коде вы можете использовать coll для другой обработки, то можно разместить там. Кроме того, я не думаю, что кто-то изменит переменную DOM на другое значение, поэтому я бы использовал constant вместо.

    document.getElementById("menu-btn1").addEventListener("click", function() {
        const coll = document.querySelector('.collection');
        const dis = document.querySelector('.display');
        const drop = document.querySelector('.drop');
        if(coll.style.display == 'none') {
            coll.style.display = 'block';
            dis.style.display = 'none';
            drop.style.display = 'none';
        } else {
            coll.style.display = 'none';
        }
    });

Однако эти изменения не решают того факта, что display: none фактически разбросан как в HTML, так и в Javascript. Я думаю, что лучше просто разместить код в одном месте. То есть удалите стили в HTML.

Для этого, я думаю, есть два подхода, один из них — использование RxJS, другой способ — использовать подход, основанный на данных, например React, Angular, Vue, …

Подход, основанный на данных: использование VueJS

Давайте сначала посмотрим, как мы можем реализовать это в подходе, основанном на данных. Я буду использовать Vue для демонстрации, так как он самый простой в настройке из трех.

new Vue({
            el: "#app",
            template: `
            <div class="ui">
                <div class="menu">
                    <span id="text"><span @click="show = !show">collection</span></span>
                </div>

                <div class="collection" :style="styles">
                    Collection Inside
                </div>
            </div>
            `,
            data: function() {
                return {
                    show: false
                }
            },
            computed: {
                styles: function() {
                    return {
                        "display": this.show ? "block": "none"
                    };
                },
            },
        })
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  </div>

Как видите, HTML-код теперь помещен в Javascript в качестве шаблона, и мы используем :style и @click в шаблоне вместо обычного HTML. Это специфический синтаксис Vue, который используется во Vue для упрощения взаимодействия между Javascript-компонентом Vue и шаблоном.

Подход, основанный на событиях: RxJS

Другой подход — RxJS, который просто работает без фреймворка, что упрощает его внедрение в унаследованное веб-приложение.

rxjs.merge(
    rxjs.of(1), // so that it immediately triggers
    rxjs.fromEvent(document.querySelector("#menu-btn1"), 'click'),
)
    .pipe(
        rxjs.operators.scan((accum, value, index) => {
            return index % 2 == 1;
        }, false)
    ).subscribe(show => {
        const coll = document.querySelector(".collection");
        const value = show ? "block" : "none";
        coll.style.display = value;
    }

    )
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.6.3/rxjs.umd.min.js"></script>
<div class="menu">
    <span id="text"><span id="menu-btn1">collection</span></span>
</div>

<div class="collection">
    Collection Inside
</div>

Вот все решения, о которых я думаю, и вам остается решить, какой из них является наиболее чистым кодом. Мне просто нравится способ RxJS сконструирован, и не нужно поддерживать дополнительные данные для хранения.

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *