简体   繁体   中英

Throttle Function Works on Button Clicks, but Not The Related 'download' Anchor Link

I currently have a page with downloadable images on, these can be downloaded by clicking a 'download' anchor link that contains a download attribute. Because data relating ot this download is stored in a MySQL database, when the user clicks the download link a related <button> element is also effectively clicked using the JavaScript .click() method.

I have included a throttle function that means if the link is clicked multiple times within a set time period (in this example 5 seconds) this prevents multiple calls to the database - this works as expected in the sense if I click repeatedly during this 5 second period it registers the first click event, and thus only one click on the hidden submit button (I'm using JavaScript's fetch() for the form submission to prevent a hard page refresh).

However, if a user clicks say 10 times in this 5 seconds the image is still downloaded 10 times. I have two questions rolled into one

  1. When an image is downloaded, does that image then get cached so any subsequent downloads come from that link? I can't seem to find any info on this.

  2. Assuming this doesn't happen - how do I get the 'download' functionality to behave like the hidden button click ie only fire once every five seconds even when multiple clicks happen, and not download the image multiple times?

Any help hugely appreciated.

JAVASCRIPT

// THROTTLE FUNCTION
const throttle =  (fn, delay) => {
    let last = 0;
    return (...args) => {
        let now = new Date().getTime();
        if (now - last < delay) {
            return;
        }
        last = now;
        return fn(...args);
    }
}

// CLICK EVENT ON THE DOWNLOAD ANCHOR LINK THAT ALSO FIRES A CLICK EVENT ON THE BUTTON TO UPDATE THE DATABASE
let downloadButton = document.querySelectorAll('.dl-button'),
    downloadLink = document.querySelectorAll('.dl-link')

if (downloadLink) {
    downloadLink.forEach(i => {
        i.addEventListener('click', throttle((e) => {
            console.log('clicked')
            e.target.closest('form').querySelector('.dl-button').click()
        }, 5000))
    })
}

HTML

<form method="post">
    <div class="wrapper">
        <a download class="dl-link" href="../images/ballon.jpg">
            <span>Download</span>
        </a>
        <button style="display:none" class="dl-button" type="submit" name="download" title="Download"></button>
    </div>
</form>

Why not simply disable the pointer-events on that link?

 let downloadButton = document.querySelectorAll('.dl-button'), downloadLink = document.querySelectorAll('.dl-link') if (downloadLink) { downloadLink.forEach(i => { i.addEventListener('click', (e) => { // For this demo to not navigate e.preventDefault() const link = e.currentTarget console.log("submitting...") e.target.closest('form').querySelector('.dl-button') //.click() // Removed for this demo // Disable pointer-events link.classList.add("disabled-link") console.log("pointer-events removed") // Restore pointer-events in 5 seconds setTimeout(() => { link.classList.remove("disabled-link") console.log("pointer-events restored") }, 5000) }) }) }
 .disabled-link { pointer-events: none; }
 <form method="post"> <div class="wrapper"> <a download class="dl-link" href="../images/ballon.jpg"> <span>Download</span> </a> <button style="display:none" class="dl-button" type="submit" name="download" title="Download"></button> </div> </form>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM