简体   繁体   中英

How to use higher-order functions in JavaScript?

I am new to JavaScript and have almost no idea of how functional programming works. I am running into a problem.

 const cards = document.querySelectorAll('.card') const descriptionCards = document.querySelectorAll('.description-card') async function displayParagraph(descriptionId) { function timer(time) { return new Promise(resolve => setTimeout(resolve, time)) } await timer(500) document.querySelector(descriptionId).style.display = 'block' } cards.forEach(card => { const cardIndex = card.id['card-'.length] card.addEventListener('mouseover', () => { document.querySelector('#description-card-' + cardIndex).style.height = '302px' displayParagraph('#description-' + cardIndex) }) card.addEventListener('mouseout', () => { document.querySelector('#description-card-' + cardIndex).style.height = '0px' document.querySelector('#description-' + cardIndex).style.display = 'none' }) }) descriptionCards.forEach(descriptionCard => { const cardIndex = descriptionCard.id['description-card-'.length] descriptionCard.addEventListener('mouseover', () => { document.querySelector('#description-card-' + cardIndex).style.height = '302px' document.querySelector('#description-' + cardIndex).style.display = 'block' }) descriptionCard.addEventListener('mouseout', () => { document.querySelector('#description-card-' + cardIndex).style.height = '0px' document.querySelector('#description-' + cardIndex).style.display = 'none' }) })
 .absolute { position: absolute; } .first-row { left: 100px; } .first-column { top: 407px; } .card { background: #FFFFFF; width: 320px; height: 240px; border: 0; border-radius: 25px; box-shadow: 0px 1px 15px 10px #00000040; z-index: 1; } .card img { margin: auto; } /* Descriptions */ .description-card { position: absolute; top: 215px; width: 100%; height: 0px; background: #FFFFFF; border-radius: 0px 0px 25px 25px; transition: all 500ms; } .description { position: absolute; top: 45px; font-size: 16px; display: none; } #description-a { left: 28px; width: 263px; }
 <div class="first-row first-column absolute"> <div id="card-a" class="card"> <img src="organizations/panthera.png" alt="Panthera"> </div> <div id="description-card-a" class="description-card"> <p id="description-a" class="description">Panthera is the only organization in the world that is devoted exclusively to the conservation of the world's 40 wild cat species and their ecosystems. Utilizing the expertise of the world's premier cat biologists, Panthera develops and implements global strategies for the most imperiled large cats: tigers, lions, jaguars, snow leopards, cheetahs, pumas, and leopards.</p> </div> </div>

This works perfectly. But the problem, as you can see, is that I am repeating the code for what happens when I am hovering over the card or the description-card . Basically, I want the same behaviour when I am hovering over either the card or the description-card . Naturally, this is a good place to use functions to avoid repeating code. So I tried doing this:

 const cards = document.querySelectorAll('.card') const descriptionCards = document.querySelectorAll('.description-card') async function displayParagraph(descriptionId) { function timer(time) { return new Promise(resolve => setTimeout(resolve, time)) } await timer(500) document.querySelector(descriptionId).style.display = 'block' } function hovering() { document.querySelector('#description-card-' + cardIndex).style.height = '302px' displayParagraph('#description-' + cardIndex) } function notHovering() { document.querySelector('#description-card-' + cardIndex).style.height = '0px' document.querySelector('#description-' + cardIndex).style.display = 'none' } cards.forEach(card => { const cardIndex = card.id['card-'.length] card.addEventListener('mouseover', hovering) card.addEventListener('mouseout', notHovering) }) descriptionCards.forEach(descriptionCard => { const cardIndex = descriptionCard.id['description-card-'.length] descriptionCard.addEventListener('mouseover', hovering) descriptionCard.addEventListener('mouseout', notHovering) })
 .absolute { position: absolute; } .first-row { left: 100px; } .first-column { top: 407px; } .card { background: #FFFFFF; width: 320px; height: 240px; border: 0; border-radius: 25px; box-shadow: 0px 1px 15px 10px #00000040; z-index: 1; } .card img { margin: auto; } /* Descriptions */ .description-card { position: absolute; top: 215px; width: 100%; height: 0px; background: #FFFFFF; border-radius: 0px 0px 25px 25px; transition: all 500ms; } .description { position: absolute; top: 45px; font-size: 16px; display: none; } #description-a { left: 28px; width: 263px; }
 <div class="first-row first-column absolute"> <div id="card-a" class="card"> <img src="organizations/panthera.png" alt="Panthera"> </div> <div id="description-card-a" class="description-card"> <p id="description-a" class="description">Panthera is the only organization in the world that is devoted exclusively to the conservation of the world's 40 wild cat species and their ecosystems. Utilizing the expertise of the world's premier cat biologists, Panthera develops and implements global strategies for the most imperiled large cats: tigers, lions, jaguars, snow leopards, cheetahs, pumas, and leopards.</p> </div> </div>

But this does not work as cardIndex is not defined in the hovering and notHovering functions. I can't figure out how to pass cardIndex into the hovering and notHovering functions since I am not supposed to call the functions but the pass in the function names as variables into the addEventListener functions.

in response to the comment that you put and according to the title of question, I read an article about higher-order functions in js and this is the link of that:

https://jrsinclair.com/articles/2019/what-is-a-higher-order-function-and-why-should-anyone-care/

according to the definition :

A function that takes a function as an argument, or returns a function as a result

is a higher-order function. so the "addEventListener()" function is a higher-order function itself. so the benefit of using such a function is that you could pass different functions to them, for example you could pass a new "clicking" function like this:

card.addEventListener('click', ()=>clicking(cardIndex, cardNum, cardWidth))

as you could see this new "hypothetical function" could take three argument and have a complete different action, and this is the benefit of using higher-order functions in javascript.

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