The Countdown feature is currently only functioning on the initial button and not on any of the other buttons

I could use some assistance. I have a download button with a countdown, but there seems to be an issue with the button's functionality. It only works on the first button, or if the second button is clicked first, it starts the countdown on the first button instead of the second. Can someone please help me fix this error? I have provided a snippet of the code. Please take a look and let me know what might be wrong. Thank you.

  function generate() {
    var e, n = document.getElementById("downloadingx"),
      t = document.getElementById("downloadbuttonx"),
      a = document.getElementById("downloadingx").href,
      l = 10,
      d = document.createElement("span");
    n.parentNode.replaceChild(d, n), e = setInterval(function() {
      --l < 0 ? (d.parentNode.replaceChild(n, d), clearInterval(e), window.open(a), n.style.display = "inline") : (d.innerHTML = "<i class='fa fa-clock-o' aria-hidden='true'/> Redirecting to download page in " + l.toString() + " seconds.", t.style.display = "none")
    }, 1e3)
  }
#downloadbuttonx{
  cursor: pointer;
  padding: 10px 20px;
  border: none;
  border-radius: 3px;
  background: #fff;
  color: #e67e22;
  float: none;
  text-transform: uppercase;
  font-weight: 800;
  transition: all 0.5s;
  font-size: 16px;
  outline: none;
}

#downloadbuttonx:hover,
#downloadingx:hover{
  background: #ffffff;
  color: #b62727;
  outline: none;
}

.batas-downx{
  margin: auto;
  border-radius: 4px;
  display:block;
}

.background-box-st{
  background: #b62727;
  color: #fff;
  padding: 10px 10px 5px 10px;
  width: 310px;
  text-align: center;
  left: 50%;
  transform: translate(-50%);
  position: relative;
  border-top-right-radius:5px;
  border-top-left-radius:5px;
  border-bottom-right-radius:5px;
  border-bottom-left-radius:5px;
  line-height: 80px;
  margin-bottom: 10px;
}

.background-box-n{
  background: #a30085;
  color: #fff;
  padding: 10px 10px 5px 10px;
  width: 310px;
  text-align: center;
  left: 50%;
  transform: translate(-50%);
  position: relative;
  border-top-right-radius:5px;
  border-top-left-radius:5px;
  border-bottom-right-radius:5px;
  border-bottom-left-radius:5px;
  line-height: 80px;
  margin-bottom: 10px;
}

.file-name{
  font-family: sans-serif;
  font-size: 1.3em;
  font-weight: 700;
  color: #fff;
  line-height: 35px;
  text-align: center;
  display: block;
  margin: 5px;
}

.catatan-downx{
padding:20px;
background:#f7f7f7;
color:#555;
font-size:20px;
}

#downloadingx{
  display:block;
  padding: 10px 20px;
  border-radius: 3px;
  color: #e67e22;
  background: #fff;
  text-decoration: none;
  text-transform:capitalize;
  text-align:center;
  float:none;
  line-height:80px;
  font-size:16px;
  font-weight: 600;
}

.bungkus-info span{
display:block;
line-height:80px;
float:none;
}

.file-deskripsi{
display:block;
}

.file-deskripsi span{
margin-right:3px;
}

#downloadbuttonx,
a#downloadingx{
width:160px;
padding:15px;
cursor:pointer;
}

.bungkus-info span{
float:none;
width:100%;
text-align:center;
}

.file-deskripsi{text-align:center}
}
<div class="batas-downx">
  <div class="background-box-n">
    <div class="bungkus-info">
      <div class="file-name">File 1</div>
      <button id="downloadbuttonx" onclick="generate()"><i aria-hidden="true" class="fa fa-cloud-download"></i> Download</button>
      <a href="#" id="downloadingx" style="display: none;"><i aria-hidden="true" class="fa fa-cloud-download"></i> Redirecting...</a>
    </div>
  </div>
</div>
<br>
<div class="batas-downx">
  <div class="background-box-st">
    <div class="bungkus-info">
      <div class="file-name">File 1</div>
      <button id="downloadbuttonx" onclick="generate()"><i aria-hidden="true" class="fa fa-cloud-download"></i> Download</button>
      <a href="#" id="downloadingx" style="display: none;"><i aria-hidden="true" class="fa fa-cloud-download"></i> Redirecting...</a>
    </div>
  </div>
</div>

Answer №1

Check this out

function downloadLink(btnId, linkId) {
    var timer, linkElem = document.getElementById(linkId),
      btnElem = document.getElementById(btnId),
      url = document.getElementById(linkId).href,
      countdown = 10,
      tempElem = document.createElement("span");
    linkElem.parentNode.replaceChild(tempElem, linkElem);
    timer = setInterval(function() {
      if (--countdown < 0) {
        tempElem.parentNode.replaceChild(linkElem, tempElem);
        clearInterval(timer);
        window.open(url);
        linkElem.style.display = "inline";
      } else {
        tempElem.innerHTML = "<i class='fa fa-clock-o' aria-hidden='true'/> Redirecting to download page in " + countdown.toString() + " seconds.";
        btnElem.style.display = "none";
      }
    }, 1000);
  }


<div class="download-section">
      <div class="background-box">
        <div class="info-wrapper">
          <div class="file-name">File 1</div>
          <button id="downloadbtn0" onclick="downloadLink('downloadbtn0','downloadtext0')"><i aria-hidden="true" class="fa fa-cloud-download"></i> Download</button>
          <a href="#" id="downloadtext0" style="display: none;"><i aria-hidden="true" class="fa fa-cloud-download"></i> Redirecting...</a>
        </div>
      </div>
    </div>
    <br>
    <div class="download-section">
      <div class="background-box">
        <div class="info-wrapper">
          <div class="file-name">File 2</div>
          <button id="downloadbtn1" onclick="downloadLink('downloadbtn1','downloadtext1')"><i aria-hidden="true" class="fa fa-cloud-download"></i> Download</button>
          <a href="#" id="downloadtext1" style="display: none;"><i aria-hidden="true" class="fa fa-cloud-download"></i> Redirecting...</a>
        </div>
      </div>
    </div>

Answer №2

If you want to determine which button is clicked, you can pass the button's ID using `this.id` and then use that ID as a reference.

Check out the example below.

function checkButton(id){
 console.log("Button ID: ", id)
}
<button id="btn-1" onclick="checkButton(this.id)"> Click Me</button>
<br />

<button id="btn-2" onclick="checkButton(this.id)"> Click Me</button>

For your specific code, you can pass the `id` as a parameter to the `checkButton()` function. Make sure to have a unique ID like `downloadingx` for each `` tag, such as `downloadingx-btn-download-1` and `downloadingx-btn-download-2`.

Remember, each element on a page must have a unique ID.

function checkButton(btnId) {
  var e, n = document.getElementById(btnId),
    t = document.getElementById(btnId),
    a = document.getElementById("downloadingx-"+btnId).href,
    l = 10,
    d = document.createElement("span");
  n.parentNode.replaceChild(d, n), e = setInterval(function() {
    --l < 0 ? (d.parentNode.replaceChild(n, d), clearInterval(e), window.open(a), n.style.display = "inline") : (d.innerHTML = "<i class='fa fa-clock-o' aria-hidden='true'/> Redirecting to download page in " + l.toString() + " seconds.", t.style.display = "none")
  }, 1e3)
}
#downloadbuttonx{
  cursor: pointer;
  padding: 10px 20px;
  border: none;
  border-radius: 3px;
  background: #fff;
  color: #e67e22;
  float: none;
  text-transform: uppercase;
  font-weight: 800;
  transition: all 0.5s;
  font-size: 16px;
  outline: none;
}

#downloadbuttonx:hover,
#downloadingx:hover{
  background: #ffffff;
  color: #b62727;
  outline: none;
}

...
<div class="batas-downx">
  ...
</div>
<br>
<div class="batas-downx">
  ...
</div>

Answer №3

One of the best practices in JavaScript is to register your event listeners properly. By doing so, you can easily refer to the specific element using the this keyword inside the generate function.

Once you have registered the event listener, you can effortlessly find the adjacent anchor (<a>) element using the nextElementSibling property.

Another advantage of this approach is that you no longer need to assign different IDs to button and anchor elements, especially when dealing with a large list.

(function() {

  function generate() {
    var e, n = this.nextElementSibling,
      t = this,
      a = this.nextElementSibling.href,
      l = 10,
      d = document.createElement("span");
    n.parentNode.replaceChild(d, n), e = setInterval(function() {
      --l < 0 ? (d.parentNode.replaceChild(n, d), clearInterval(e), window.open(a), n.style.display = "inline") : (d.innerHTML = "<i class='fa fa-clock-o' aria-hidden='true'/> Redirecting to download page in " + l.toString() + " seconds.", t.style.display = "none")
    }, 1e3)
  }

  const buttons = document.getElementsByTagName('button');

  for (let i = 0; i < buttons.length; i++) {
    const button = buttons[i];
    button.addEventListener('click', generate);
  }

})();
.downloadbuttonx {
  cursor: pointer;
  padding: 10px 20px;
  border: none;
  border-radius: 3px;
  background: #fff;
  color: #e67e22;
  float: none;
  text-transform: uppercase;
  font-weight: 800;
  transition: all 0.5s;
  font-size: 16px;
  outline: none;
}

.downloadbuttonx:hover,
.downloadingx:hover {
  background: #ffffff;
  color: #b62727;
  outline: none;
}

.batas-downx {
  margin: auto;
  border-radius: 4px;
  display: block;
}

.background-box-st {
  background: #b62727;
  color: #fff;
  padding: 10px 10px 5px 10px;
  width: 310px;
  text-align: center;
  left: 50%;
  transform: translate(-50%);
  position: relative;
  border-top-right-radius: 5px;
  border-top-left-radius: 5px;
  border-bottom-right-radius: 5px;
  border-bottom-left-radius: 5px;
  line-height: 80px;
...
  width: 100%;
  text-align: center;
}

.file-deskripsi {
  text-align: center
}
<div class="batas-downx">
  <div class="background-box-n">
    <div class="bungkus-info">
      <div class="file-name">File 1</div>
      <button class="downloadbuttonx"><i aria-hidden="true" class="fa fa-cloud-download"></i> Download</button>
      <a href="#" class="downloadingx" style="display: none;"><i aria-hidden="true" class="fa fa-cloud-download"></i> Redirecting...</a>
    </div>
  </div>
</div>
<br>
<div class="batas-downx">
  <div class="background-box-st">
    <div class="bungkus-info">
      <div class="file-name">File 2</div>
      <button class="downloadbuttonx"><i aria-hidden="true" class="fa fa-cloud-download"></i> Download</button>
      <a href="#" class="downloadingx" style="display: none;"><i aria-hidden="true" class="fa fa-cloud-download"></i> Redirecting...</a>
    </div>
  </div>
</div>

UPDATE Enhanced the styling by using CSS classes instead of duplicate IDs for a cleaner and more efficient code structure.

Answer №4

I discovered an error in your code where both the first Download button and the second one shared the same id. I resolved this issue by changing the id of the second button.

function generatex() {
var e, n = document.getElementById("downloadingx"),
  t = document.getElementById("downloadbuttonx"),
  a = document.getElementById("downloadingx").href,
  l = 10,
  d = document.createElement("span");
n.parentNode.replaceChild(d, n), e = setInterval(function() {
  --l < 0 ? (d.parentNode.replaceChild(n, d), clearInterval(e), window.open(a), n.style.display = "inline") : (d.innerHTML = "<i class='fa fa-clock-o' aria-hidden='true'/> Redirecting to download page in " + l.toString() + " seconds.", t.style.display = "none")
}, 1e3)
}
function generatey() {
var e, n = document.getElementById("downloadingy"),
  t = document.getElementById("downloadbuttony"),
  a = document.getElementById("downloadingy").href,
  l = 10,
  d = document.createElement("span");
n.parentNode.replaceChild(d, n), e = setInterval(function() {
  --l < 0 ? (d.parentNode.replaceChild(n, d), clearInterval(e), window.open(a), n.style.display = "inline") : (d.innerHTML = "<i class='fa fa-clock-o' aria-hidden='true'/> Redirecting to download page in " + l.toString() + " seconds.", t.style.display = "none")
}, 1e3)
}

css

#downloadbuttonx{
  cursor: pointer;
  padding: 10px 20px;
  border: none;
  border-radius: 3px;
  background: #fff;
  color: #e67e22;
  float: none;
  text-transform: uppercase;
  font-weight: 800;
  transition: all 0.5s;
  font-size: 16px;
  outline: none;
}
#downloadbuttony{
  cursor: pointer;
  padding: 10px 20px;
  border: none;
  border-radius: 3px;
  background: #fff;
  color: #e67e22;
  float: none;
  text-transform: uppercase;
  font-weight: 800;
  transition: all 0.5s;
  font-size: 16px;
  outline: none;
}

#downloadbuttonx:hover,
#downloadingx:hover{
  background: #ffffff;
  color: #b62727;
  outline: none;
}
#downloadbuttony:hover,
#downloadingy:hover{
  background: #ffffff;
  color: #b62727;
  outline: none;
}
.batas-downx{
  margin: auto;
  border-radius: 4px;
  display:block;
}
.batas-downy{
  margin: auto;
  border-radius: 4px;
  display:block;
}

.background-box-st{
  background: #b62727;
  color: #fff;
  padding: 10px 10px 5px 10px;
  width: 310px;
  text-align: center;
  left: 50%;
  transform: translate(-50%);
  position: relative;
  border-top-right-radius:5px;
  border-top-left-radius:5px;
  border-bottom-right-radius:5px;
  border-bottom-left-radius:5px;
  line-height: 80px;
  margin-bottom: 10px;
}

.background-box-n{
  background: #a30085;
  color: #fff;
  padding: 10px 10px 5px 10px;
  width: 310px;
  text-align: center;
  left: 50%;
  transform: translate(-50%);
  position: relative;
  border-top-right-radius:5px;
  border-top-left-radius:5px;
  border-bottom-right-radius:5px;
  border-bottom-left-radius:5px;
  line-height: 80px;
  margin-bottom: 10px;
}

.file-name{
  font-family: sans-serif;
  font-size: 1.3em;
  font-weight: 700;
  color: #fff;
  line-height: 35px;
  text-align: center;
  display: block;
  margin: 5px;
}

.catatan-downx{
padding:20px;
background:#f7f7f7;
color:#555;
font-size:20px;
}
.catatan-downy{
padding:20px;
background:#f7f7f7;
color:#555;
font-size:20px;
}

#downloadingx{
  display:block;
  padding: 10px 20px;
  border-radius: 3px;
  color: #e67e22;
  background: #fff;
  text-decoration: none;
  text-transform:capitalize;
  text-align:center;
  float:none;
  line-height:80px;
  font-size:16px;
  font-weight: 600;
}
#downloadingy{
  display:block;
  padding: 10px 20px;
  border-radius: 3px;
  color: #e67e22;
  background: #fff;
  text-decoration: none;
  text-transform:capitalize;
  text-align:center;
  float:none;
  line-height:80px;
  font-size:16px;
  font-weight: 600;
}


.bungkus-info span{
display:block;
line-height:80px;
float:none;
}

.file-deskripsi{
display:block;
}

.file-deskripsi span{
margin-right:3px;
}

#downloadbuttonx,
#downloadbuttony,
a#downloadingx,
a#downloadingy{
width:160px;
padding:15px;
cursor:pointer;
}

.bungkus-info span{
float:none;
width:100%;
text-align:center;
}

.file-deskripsi{text-align:center}
}

html

<div class="batas-downx">
    <div class="background-box-n">
        <div class="bungkus-info">
            <div class="file-name">File 1</div>
            <button id="downloadbuttonx" onclick="generatex()"><i aria-hidden="true" class="fa fa-cloud-download"></i> Download</button>
            <a href="#" id="downloadingx" style="display: none;"><i aria-hidden="true" class="fa fa-cloud-download"></i> Redirecting...</a>
        </div>
    </div>
</div>
<br>
<div class="batas-downx">
    <div class="background-box-st">
        <div class="bungkus-info">
            <div class="file-name">File 1</div>
            <button id="downloadbuttony" onclick="generatey()"><i aria-hidden="true" class="fa fa-cloud-download"></i> Download</button>
            <a href="#" id="downloadingy" style="display: none;"><i aria-hidden="true" class="fa fa-cloud-download"></i> Redirecting...</a>
        </div>
    </div>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having trouble getting Vue.js hello world to display on the page

I am attempting to create a Hello World app following the Vue.js site's get started documentation. Everything seems to be in order, but only the HTML code is being displayed on the page. Vue version: 1.0.26 Below is the HTML code: <!DOCTYPE ht ...

Using jQuery, identify when any of the elements within every function are missing

In my JavaScript file, I have the following code snippet: var aryYears= []; $(".year").each(function(){ aryYears.push($(this).val()); }) This allows me to pass an array of years as a parameter in the saveChanges function. I want to make ...

Stop observing IntersectionObserver within the React.useEffect function

I'm attempting to retrieve the top and bottom measurements from multiple elements using the IntersectionObserver. However, once I have the measurements, I'm unsure how to stop observing the elements. The issue is that each element has a position ...

Overlay Image on Card, Overflowing into Card Body

I currently have a webpage featuring cards. Each card includes a thumbnail at the top with an overlay. The main content of the card needs to be positioned outside of the overlay, but it ends up overflowing onto it. Take a look at the demo: https://codepe ...

Generate a variety of HTML ordered lists

Can anyone assist me in determining the type of ordered list shown below? What is the method to achieve an ordered list like this: (a) (b) (c) in HTML? ...

Exploring the versatility of Angular 4 by implementing a switch feature with

My goal is to have the menu change based on the click of the "Cadastros" action, but it seems like the issue lies with the "workspaceSelected" property not being visible to all components. I believe the best approach in this situation would be to have the ...

How can I make sure a Post method finishes executing before returning the result of a Get method in Express.js?

I am currently utilizing the Ionic framework and Express to facilitate communication between my application, a server API, and a JavaScript game. The game transmits information to the API through XMLHttpRequest and post requests, while my application retri ...

A guide on coding the source tag script for a payment form in CodeIgniter, specifically for a JavaScript form

Scenario: I have a variable called $data['tabdata'] that I am passing from controller C to view V. This variable includes a script element pointing to http://example.com/1.js. Problem: The script in 1.js is not running properly in the view. This ...

Babel continues to encounter issues with async/await syntax, even with all the necessary presets and plugins installed

I am encountering a compiler error while attempting to compile an async/await function using Babel. Below is the function in question: async function login(username, password) { try { const response = await request .post("/api/login") . ...

Discovering the process of mapping transitions in MUI

I'm struggling with mapping my products in mui and placing each one in Grow. However, I keep getting this error message: "Warning: Failed prop type: Invalid prop children of type array supplied to ForwardRef(Grow), expect a single ReactElement". Can a ...

Issues encountered when attempting to insert numerous records (close to 1000) using $wpdb

Adding a large number of records from my plugin has been challenging. When attempting to add nearly 1000 records, I noticed that not all records are successfully added. The number of inserted records also varies - sometimes it is 300, other times 400, or e ...

Any modifications made to a copied object will result in changes to the original object

The original object is being affected when changes are made to the cloned object. const original = { "appList": [{ "appId": "app-1", "serviceList": [{ "service": "servic ...

What is the best way to ensure that when a div is opened, the information to the right does not get pushed down?

I have a functioning menu bar, but when it expands, the content below is pushed down even though it should not be affected. How can I adjust my code to prevent this issue? View my website here: <div id="menu_wrapper"> <div id="menu"> &l ...

I would like to style the input checkbox using CSS

Is there a way to style input checkboxes with CSS that will work on all browsers (Chrome, Firefox, IE 6, 7, and 8)? If jQuery is the only solution, please let me know. It needs to be compatible with all browsers. Can anyone provide guidance on how to ach ...

Dealing with Koa-router and handling POST requests

I am facing an issue handling POST requests in my koa-router. Despite using koa-bodyparser, I am unable to receive any data sent through my form. My template engine is Jade. router.js: var jade = require('jade'); var router = require('koa- ...

Automatically update the div every few seconds and pause when it has loaded successfully

I am facing a challenge in creating a div that refreshes automatically every 10 seconds, but stops when it successfully loads. Here is the jQuery script I have developed: <script type="text/javascript"> $(document).ready(function(){ var j = jQuer ...

transferring a document using axios, bypassing the FormData interface

One way to upload a file to the server is by using axios along with the FormData api. Here's an example: persist(photo){ let data = new FormData(); data.append('photo', photo); axios.post(`/api/photos/${this.user ...

Nested loops seem to override previous results with the final output

I am attempting to iterate through an array of months nested within an array of 'years' in order to calculate a count for each month using a custom angular filter. Initially, I set up the structure I will be looping through in the first while loo ...

Unable to click a button on HTML file

In my current project, there is a piece of code responsible for checking if the user is logged in or not. If the user hasn't logged in yet, they are redirected to the login page. Once the user logs in successfully, they should be able to upload conten ...

Transitioning menus in Ionic 2

I followed the instructions in the Ionic 2 menu documentation and tried to display the menu in a specific way: https://i.sstatic.net/zzm8f.png My intention was to have the menu displayed below the content page while keeping the menu button visible. Howe ...