admin管理员组

文章数量:1122846

I'm trying to organize market lists by metro regions but I'm running into issues retrieving elements by their ID. Specifically, I'm encountering a TypeError: Cannot read properties of null (reading 'closest').

Here’s my current JavaScript code. I’ve started mapping market IDs to their corresponding metro regions. Next, I’m working on creating the elements and structuring them with their respective <div> wrappers.

const mapping = {
  'Austin': {
    ids: ['91352212', '87371946'],
    description: 'austin lists'
  },
  'Dallas': {
    ids: ['57955430', '19944090'],
    description: 'dallas lists'
  },
  'Houston': {
    ids: ['19944180', '19944174'],
    description: 'houston lists'
  }
}

document.addEventListener('DOMContentLoaded', function() {
  const buildDescription = function(text) {
    el = document.createElement('p');
    el.classList.add('group__description');
    el.innerText = text;
    return el;
  }

  const buildWrapper = function(descriptionEl) {
    el = document.createElement('div')
    el.classList.add('group__contents')
    if (descriptionEl) {
      el.append(descriptionEl);
    }
    return el;
  }

  const buildHeader = function(label) {
    el = document.createElement('h3')
    el.classList.add('group__header')
    el.setAttribute('aria-expanded', 'false');
    el.addEventListener('click', function(e) {
      var state = (e.target.getAttribute('aria-expanded') == 'false') ? 'true' : 'false';
      e.target.setAttribute('aria-expanded', state);
      console.log("group expanded");
    })
    el.innerText = label;
    return el;
  }

  const buildGroupWrapper = function(headerEl, wrapperEl) {
    el = document.createElement('div')
    el.classList.add('group')
    el.append(headerEl);
    el.append(wrapperEl);
    return el;
  }

  const rootEl = document.querySelector('div.subscribe-options');

  const buildGroups = function(key, ids, descriptionText) {
    const groupId = key.toLowerCase().replaceAll(' ', '-');

    description = !!descriptionText ? buildDescription(descriptionText) : undefined;
    wrapper = buildWrapper(description);
    header = buildHeader(key);
    groupWrapper = buildGroupWrapper(header, wrapper);
    rootEl.before(groupWrapper);

    ids.forEach(function(id) {
      const inputEl = document.getElementById('id_' + id);
      const itemEl = inputEl.closest('.item');

      itemEl.setAttribute('data-subscription-id', id);
      itemEl.setAttribute('data-subscription-group', key);
      wrapper.append(itemEl);
    });
    
    if(wrapper.querySelector('.highlighted-subscription')) {
      header.setAttribute('aria-expanded', 'true');
    } 
  };

  Object.keys(mapping).forEach(function(key) {
    buildGroups(key, mapping[key].ids, mapping[key].description)
  });

  const miscWrapper = buildWrapper('')
  const miscHeader = buildHeader('Other Marketing')
  const miscGroupWrapper = buildGroupWrapper(miscHeader, miscWrapper);
  rootEl.before(miscGroupWrapper);

  document.querySelectorAll('div.item:not([data-subscription-group])').forEach(function(el) {
    miscWrapper.append(el)
  });
});
.item .item-inner > p {
  display: none;
}

.group__header {
  display: flex;
  justify-content: space-between;
  cursor: pointer;
  border-bottom: 3px solid #aeaeae;
  font-size: 1.25rem;
  font-weight: bold;
  line-height: 1.5;
  margin-bottom: 1rem;
  color:#3e3e3e!important;
}

.group__header[aria-expanded="true"]::after {
  content: '–';
}

.group__header[aria-expanded="false"]::after {
  content: '+';
}

.group__header[aria-expanded="false"] + .group__contents {
  display: none;
}
<div class="item">  
  <div class="item-inner selected">
    <div class="checkbox-row">
      <span class="fakelabel">
        <input id="id_91352212" type="checkbox" checked="" name="id_91352212">
        <span>Central Austin</span>
      </span>
    </div>
  </div>
</div>
<div class="item">  
  <div class="item-inner selected">
    <div class="checkbox-row">
      <span class="fakelabel">
        <input id="id_57955430" type="checkbox" checked="" name="id_57955430">
        <span>Frisco</span>
      </span>
    </div>
  </div>
</div>
<div class="item">  
  <div class="item-inner selected">
    <div class="checkbox-row">
      <span class="fakelabel">
        <input id="id_19944180" type="checkbox" checked="" name="id_19944180">
        <span>The Woodlands</span>
      </span>
    </div>
  </div>
</div>
<div class="subscribe-options" style="margin-right: 0">
    <p class="header">Or check here to never receive any emails:</p>
    <p>
        <label for="globalunsub">
            <input name="globalunsub" id="globalunsub" type="checkbox">
            <span>
                Unsubscribe me from all mailing lists.
            </span>
        </label>
    </p>
</div>

本文标签: javascriptGroup lists using DOM manipulationStack Overflow