Home > database >  Change the value of a progress when click on a element with javascript
Change the value of a progress when click on a element with javascript

Time:10-30

I want to change the value of the progress bar when each tap is clicked.

var taps = document.getElementsByClassName('et_pb_tab');

for (var i = 0; i < taps.length; i  ) {
  taps[i].addEventListener('click', () => {
    var v1 = document.getElementById('p1').value;
    v1.value = v1   20;
  });
}
li.et_pb_tab_active {
  background-color: rgba(255, 211, 14, 0.29);
}
<progress value="0" max="100" id="p1"></progress>

<ul >
  <li ><a href="#">Clase N° 1</a></li>
  <li  style="height: 64.8px;"><a href="#">Clase N° 2</a></li>
  <li  style="height: 64.8px;"><a href="#">Clase N° 3</a></li>
  <li  style="height: 64.8px;"><a href="#">Clase N° 4</a></li>
  <li  style="height: 64.8px;"><a href="#">Clase N° 5</a></li>
</ul>

I was trying to get the element "et_pb_tab" that is each tap and with a for add the listener, then click on the tap, the progress bar adds 20 to the value, but it's not working.

CodePudding user response:

You were very close. You had mixed up the progress element itself with its value. Here's a slightly revised example of how it might work:

const
  v1 = document.getElementById('p1'),
  taps = document.getElementsByClassName('et_pb_tab');

for (const tap of taps) {  
  tap.addEventListener('click', () => v1.value  = 20);
} 
.et_pb_tab{ width: 2em; margin-bottom: 0.5em; border: 1px solid grey; text-align: center; }
<progress value="0" max="100" id="p1"></progress>
<ul >
  <li > 1 </li>
  <li > 2 </li>
  <li > 3 </li>
  <li > 4 </li>
  <li > 5 </li>
</ul>

But you might want to consider using event delegation:

const
  v1 = document.getElementById('p1'),
  container = document.getElementsByClassName('et_pb_tabs_controls')[0];

  container.addEventListener('click', handleClick);

  function handleClick(event){ // Events bubble up to ancestors
    const clickedThing = event.target;
    if(!clickedThing.classList.contains("et_pb_tab")){//Ignores irrelevant clicks
      return;
    }
    v1.value  = 20;
  }
.et_pb_tab{ width: 2em; margin-bottom: 0.5em; border: 1px solid grey; text-align: center; }
<progress value="0" max="100" id="p1"></progress>
<ul >
  <li > 1 </li>
  <li > 2 </li>
  <li > 3 </li>
  <li > 4 </li>
  <li > 5 </li>
</ul>

CodePudding user response:

  1. At the moment you're immediately grabbing the value from the progress element. Just select the element, and then use the value its new value in the calculation.

  2. Cache all the elements you need up front so that you don't need to hit the DOM on each click.

  3. The anchors don't do much so you can probably remove them.

  4. Instead of attaching a listener to each list item you can attach one to the container (the ul element), and then have that catch events from its children as they "bubble up" the DOM. This is known as event delegation.

  5. If you want to add/remove active classes to your list items you can do that. Within the handleClick function remove all the active classes from the list items first, and then add one to the element that was clicked.

// Cache the progress bar, list and list items up front
const progress = document.querySelector('#p1');
const list = document.querySelector('.et_pb_tabs_controls');
const items = list.querySelectorAll('li.et_pb_tab');

// Add one listener to the list element
list.addEventListener('click', handleClick);

// When the listener detects a click...
function handleClick(e) {

  // ...check that it's a list item
  if (e.target.matches('li')) {

    // Iterate over the list items removing all their
    // active classes
    items.forEach(item => item.classList.remove('active'));

    // Add one to the clicked element
    e.target.classList.add('active');

    // Update the value of the progress bar
    progress.value = progress.value   20;
  }
}
:root { --active: rgba(255,211,14,0.29); }
ul { list-style: none; margin-left: 0px; padding-left: 0px; }
li { background-color: lightgray; padding: 0.25em; }
li:hover { cursor: pointer; background-color: var(--active) }
.active { background-color: var(--active) }
<progress value="0" max="100" id="p1"></progress>

<ul >
  <li >Clase N° 1</li>
  <li >Clase N° 2</li>
  <li >Clase N° 3</li>
  <li >Clase N° 4</li>
  <li >Clase N° 5</li>
</ul>

CodePudding user response:

I think you are looking for something more like this?

(and the use of a hyperlink complicates more than it helps)

const
  progressBarEl = document.querySelector('#p1')
, taps          = document.querySelector('ul.et_pb_tabs_controls')
, tpas_li       = document.querySelectorAll('ul.et_pb_tabs_controls > li')
  ;
taps.onclick = evt =>
  {
  if (!evt.target.matches('ul.et_pb_tabs_controls > li')) return
  
  tpas_li.forEach( (li,indx) =>
    {
    if ( li.classList.toggle('et_pb_tab_active', li===evt.target) )
      {
      progressBarEl.value = (indx  1) *20
      }
    })
  }
body {
  font-family      : Arial, Helvetica, sans-serif;
  font-size        : 16px;
  }
ul.et_pb_tabs_controls {
  list-style: none;
  }

ul.et_pb_tabs_controls li {
  height      : 2em;
  line-height : 2em;
  cursor      : pointer;
 }

ul.et_pb_tabs_controls li.et_pb_tab_active {
  background-color: rgba(255, 211, 14, 0.29);
}
<progress value="20" max="100" id="p1"></progress>

<ul >
  <li  > Clase N° 1 </li>
  <li           > Clase N° 2 </li>
  <li           > Clase N° 3 </li>
  <li           > Clase N° 4 </li>
  <li           > Clase N° 5 </li>
</ul>

  • Related