jquery 单击每个按钮将类从属性添加/删除到HTML文档

mrfwxfqh  于 2023-04-20  发布在  jQuery
关注(0)|答案(3)|浏览(99)

我现在有两个按钮作为例子。这里的问题是,当我点击按钮A时,例如它会用“data-accent-switcher”的值更改html文档上的类,在这种情况下是蓝色的,但是当我再次按下按钮A时,它会用按钮B的值更改,按钮b也会发生同样的情况。现在即使我在按钮A上按了20次,我总是希望从data属性(data-accent-switcher)中获得值。
我怎样才能使它成为可能?

<button class='ipsButton accentSwitcher' data-accent-switcher="blue">Button A</button>
<button class='ipsButton accentSwitcher' data-accent-switcher="yellow">Button B</button>
<script type="text/javascript">
  $(document).ready(function() {
    $('.accentSwitcher').on("click", function() {
      var accentValue = $(this).data('accent-switcher');
      if (document['documentElement']['classList']['contains']('accent-blue')) {
        document['documentElement']['classList']['remove']('accent-blue');
        document['documentElement']['classList']['add']('accent-yellow');
      } else {
        if (document['documentElement']['classList']['contains']('accent-yellow')) {
          document['documentElement']['classList']['remove']('accent-yellow');
          document['documentElement']['classList']['add']('accent-blue');
        }
      }
      ips['utils']['cookie']['set']('ipsTheme_type', accentValue, true)
    });
  });
</script>

我尝试过if语句,但显然我错了,不起作用。

liwlm1x9

liwlm1x91#

我建议使用以下方法,并在代码中添加解释性注解:

// a named function to handle the 'accent-switching', declared using
// Arrow function syntax, and taking one argument 'evt', a reference
// to the Event object passed automatically from the later use of
// EventTarget.addEventListener():
const accentSwitch = (evt) => {
    // we use destructuring assignment to retrieve the
    // currentTarget node (the node to which the function
    // was bound) from the Event Object:
    let {
      currentTarget
    } = evt,
    // we cache the data-accent-switcher attribute-value,
    // using the HTMLElement.dataset API:
    value = currentTarget.dataset.accentSwitcher,
    // we cache a reference to the element we wish to
    // affect (obviously, this could be changed to select
    // the appropriate ancestor element of your choice,
    // up to, and including, the <html> element):
    targetElement = currentTarget.closest('section');
    // if we have a variable called 'accentChoices', and
    // it holds a truthy value:
    if (accentChoices) {
      // we take the targetElement, and use the Element.classList
      // API to remove the list of classes from the element:
      targetElement.classList.remove(...accentChoices);
    }
    // here we again use the Element.classList API, this
    // time to add a class-name:
    currentTarget.closest('section').classList.add(value);
  },
  // using document.querySelectorAll() to retrieve a NodeList of
  // all elements that have the class of 'accentSwitcher'
  // and also have a 'data-accent-switcher' attribute:
  accentButtons = document.querySelectorAll('.accentSwitcher[data-accent-switcher]'),

  // here we convert that iterable NodeList to an Array and then
  // use Array.prototype.map() to create a new Array based upon
  // the first:
  accentChoices = Array.from(accentButtons).map(
    // using an Arrow function, we use the
    // HTMLElement.dataset API to retrieve
    // the attribute-value of the data-*
    // attribute:
    (el) => el.dataset.accentSwitcher
  );

// iterating over the NodeList of elements we found,
// using NodeList.prototype.forEach():
accentButtons.forEach(
  // using an Arrow function to bind the accentSwitch()
  // function - note the deliberate lack of parentheses -
  // as the event-handler for the 'click' event:
  (el) => el.addEventListener('click', accentSwitch)
);
:root {
  --blue: hsl(200deg 90% 70% / 1);
  --purple: hsl(300deg 90% 70% / 1);
  --yellow: hsl(60deg 90% 70% / 1);
}

*,
::before,
::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  min-block-size: 100vh;
}

main {
  block-size: 100vh;
  display: grid;
  place-content: center;
}

.wrapper {
  background-image:
    linear-gradient(
      135deg,
      #ffff,
      #fff7
    ),
    repeating-linear-gradient(
      45deg,
      transparent 0 0.75rem,
      var(--colorChoice, var(--purple)) 0.75rem 1rem
    );
  box-shadow:
    0.75rem 0.75rem 1.5rem var(--colorChoice, var(--purple)),
    -0.75rem -0.75rem 1.5rem var(--colorChoice, var(--purple));
  display: flex;
  inline-size: clamp(15rem, 40%, 800px);
  justify-content: space-between;
  outline: 3px solid var(--purple);
  padding-block: 1em;
  padding-inline: 2em;
}

section.blue {
  --colorChoice: var(--blue);
}

section.yellow {
  --colorChoice: var(--yellow);
}

button {
  padding-block: 0.5rem;
  padding-inline: 0.75rem;
}
<!-- your HTML was adjusted primarily to wrap the <button> elements,
     and show an ancestor element that could be easily targeted via
     JavaScript, while providing some aesthetic hooks for the CSS: -->
<main>
  <section class="wrapper">
    <button class='ipsButton accentSwitcher' data-accent-switcher="blue">Button A</button>
    <button class='ipsButton accentSwitcher' data-accent-switcher="yellow">Button B</button>
  </section>
</main>

JS Fiddle demo
由于OP希望继续使用jQuery,我在下面添加了jQuery选项,这在代码中也有解释性注解:

// creating a const variable to hold the collection of
// <button> elements:
const buttons = $('.accentSwitcher[data-accent-switcher]'),
            // creating an Array from the <button> collection:
          accentSwitches = buttons.map(function() {
        // returning the data-accent-switcher attribute-
        // value, using the data() method:
        return $(this).data('accent-switcher');
      // converting the modified collection into
      // a plain JavaScript Array with get():
      }).get();

// using on() to bind the anonymous function of the
// method as the event-handler for 'clicke' events:
buttons.on('click', function() {
    // caching the attribute-value of the
  // data-accent-switcher value:
    let accentChoice = $(this).data('accent-switcher')
  // navigating to the closest ancestor <section>
  // element:
  $(this).closest('section')
    // removing all the classes that are featured
    // in the Array of accentSwitches:
    .removeClass(accentSwitches)
    // adding the data-accent-switcher attribute-
    // value to the current element:
    .addClass(accentChoice)
    // using the css() method to update the
    // --colorChoice css custom property:
    .css('--colorChoice',
        // we're setting the above property to
      // the value held in the current <button>
      // element's own --colorChoice
      // custom property:
        $(this).css(`--colorChoice`)
    );
});
:root {
  --purple: hsl(300deg 90% 70% / 1);
}

*,
::before,
::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  min-block-size: 100vh;
}

main {
  block-size: 100vh;
  display: grid;
  place-items: center;
}

.wrapper {
  background-image:
    linear-gradient(
      135deg,
        #ffff,
        #fff7
    ),
    repeating-linear-gradient(
      45deg,
        transparent 0 0.75rem,
        var(--colorChoice, var(--purple)) 0.75rem 1rem
    );
  box-shadow:
    0.75rem 0.75rem 1.5rem var(--colorChoice, var(--purple)),
    -0.75rem -0.75rem 1.5rem var(--colorChoice, var(--purple));
  display: flex;
  flex-flow: row wrap;
  gap: 0.5rem;
  inline-size: clamp(15rem, 40%, 800px);
  justify-content: space-between;
  outline: 3px solid var(--purple);
  padding-block: 1em;
  padding-inline: 2em;
}

button {
  flex-grow: 1;
  padding-block: 0.5rem;
  padding-inline: 0.75rem;
}
<!-- your HTML was adjusted primarily to wrap the <button> elements,
     and show an ancestor element that could be easily targeted via
     JavaScript, while providing some aesthetic hooks for the CSS: -->
<main>
  <section class="wrapper">
    <button class='ipsButton accentSwitcher' data-accent-switcher="blue" style="--colorChoice: hsl(200deg 90% 70% / 1);">Button A</button>
    <button class='ipsButton accentSwitcher' data-accent-switcher="yellow" style="--colorChoice: hsl(60deg 100% 50% / 1);">Button B</button>
    <button class='ipsButton accentSwitcher' data-accent-switcher="green" style="--colorChoice: hsl(100deg 90% 70% / 1);">Button C</button>
    <button class='ipsButton accentSwitcher' data-accent-switcher="pink" style="--colorChoice: hsl(330deg 95% 70% / 1);">Button D</button>
    <button class='ipsButton accentSwitcher' data-accent-switcher="orange" style="--colorChoice: hsl(25deg 100% 50% / 1);">Button E</button>
    <button class='ipsButton accentSwitcher' data-accent-switcher="red" style="--colorChoice: hsl(355deg 90% 70% / 1);">Button F</button>
  </section>
</main>

JS Fiddle demo
参考文献:

lyr7nygr

lyr7nygr2#

所以感谢@DavidThomas,我用了他的代码,想出了这个

<script>
  $(document).ready(function() {
    const accentButtons = $('.accentSwitcher[data-accent-switcher]'),
          accentSwitches = accentButtons.map(function() {
            return $(this).data('accent-switcher');
          }).get();
    accentButtons.on('click', function() {
      let accentChoice = $(this).data('accent-switcher')
      $(this).closest(document.documentElement)
        .removeClass(accentSwitches)
        .addClass(accentChoice)
      ips.utils.cookie.set('ipsTheme_type', accentChoice, true);
    });
  });
</script>

我希望这是正确的。但我不确定这个$(this).closest(document.documentElement)

guykilcj

guykilcj3#

谢谢你的提问,我想你可以做到的,就像这样。

<script type="text/javascript">
  $(document).ready(function() {
    $('.accentSwitcher').on("click", function() {
      var accentValue = $(this).data('accent-switcher');
      var currentAccentValue = document.documentElement.classList.contains('accent-blue') ? 'blue' : 'yellow';
      if (accentValue !== currentAccentValue) {
        if (currentAccentValue === 'blue') {
          document.documentElement.classList.remove('accent-blue');
          document.documentElement.classList.add('accent-yellow');
        } else {
          document.documentElement.classList.remove('accent-yellow');
          document.documentElement.classList.add('accent-blue');
        }
        ips.utils.cookie.set('ipsTheme_type', accentValue, true);
      }
    });
  });
</script>

我希望我的解决方案能帮助到你。

相关问题