简体   繁体   中英

Change multiple style proprieties when hover the button

I'm trying to write a JS function to change the color of multiple elements (including a SVG) when mouseover the parent tag ( <a> ). I tried to do with only CSS and the result isn't great.

 const changeColor = () => { document.getElementsByClassName("link-label").style.color = '#3a4646'; document.getElementById("Arrow").style.fill = '#3a4646'; document.getElementByClassName("cls-1").style.stroke ='#3a4646'; document.getElementByClassName("icon-arrow").style.border = "none"; }
 @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200&display=swap'); .container { height: 200px; display: grid; place-content: center; font-family: 'Poppins', sans-serif; background-color: #3a4646; }.btn--rounded { font-size: 20px; color: white; line-height: 1; letter-spacing: 0.4px; position: relative; cursor: pointer; display: inline-flex; align-items: center; padding: 12px 15px 12px 5px; transition: color 0.25s linear; text-decoration: none; background: transparent; border: none; z-index: 1; }.btn--rounded:before { width: 40px; height: 40px; position: absolute; top: 50%; transform: translateY(-50%); z-index:-1; animation-name: circleOut; animation-duration: 0.5s; animation-direction: alternate; animation-fill-mode: forwards; }.btn--rounded:hover:before { content: ''; border: none; position: absolute; top: 50%; z-index: -1; animation-name: circleIn; animation-duration: 0.8s; animation-direction: alternate; animation-fill-mode: forwards; }.icon-arrow { border: 1px solid white; border-radius: 100%; }.link-label { padding-left: 20px; } @keyframes circleOut { 0% { width: 100%; border-radius: 40px; background-color: #ffff; } 90% { border-radius: 40px; } 100% { width: 40px; border-radius: 100%; background-color: transparent; } } @keyframes circleIn { 0% { width: 60px; border-radius: 100%; background-color: transparent; } 10% { border-radius: 60px; } 100% { width: 100%; border-radius: 60px; background-color: #ffff; } }
 <div class="container"> <a href=# class="btn--rounded" onmouseover= "changeColor()"> <div class="icon-arrow"> <svg xmlns="http://www.w3.org/2000/svg" width="36" height="36"><defs><style>.cls-1,.cls-2{fill:none}.cls-1{stroke:#fff}</style></defs><g id="Group_4802" transform="translate(-1113 -542)"><g id="Rectangle_2080" class="cls-1" transform="translate(1113 542)"></g><g id="Icon_Arrow_Base" transform="translate(1123 552)"><path id="Ligne" d="M15 0H0" class="cls-1" transform="translate(0 8)"/><path id="Arrow" fill="#fff" d="M12 0l-.727.727 2.753 2.753v1.039l-2.753 2.754L12 8l4-4z" transform="translate(0 4)"/></g></g></svg> </div> <div class="link-label"> Subscribe! </div> </a> <div>

But, now I don't know why my function isn't working... All the elements are undefined in the console. Anybody knows how to fix it?

getElementsByClassName() returns an array-like collection, not a single DOM element.

If you want to alter the first element returned:

document.getElementsByClassName("link-label")[0].style.color = '#3a4646';

Also, there is no getElementByClassName() function. So your changeColor() function should be:

const changeColor = () => {
  document.getElementsByClassName("link-label")[0].style.color = '#3a4646';
  document.getElementById("Arrow").style.fill = '#3a4646';
  document.getElementsByClassName("cls-1")[0].style.stroke ='#3a4646';
  document.getElementsByClassName("icon-arrow")[0].style.border = "none";
}

Why your code is not working:

When using getElementsByClassName() , you return a collection of HTML elements, think of it as an HTML list of all the elements that have a class with a given name, an array of values that are the classees elements. Even though you may only have one class in that list, Javascript is looking for further reference (index identifier) to tell which element within that list is being referenced.

Each element within that list must be identified using the index value. document.getElementsByClassName("link-label")[0] , where zero in this example is the index identifier and the first iteration within that HTMLCollection list. This would be the static way to get the first child using the index in that HTMLCollection of elements that have that class name.

You could also use the selector -> document.querySelector(".class_name") -> returns the first Element within the document that matches the specified selector. When you use querySelector(), there is no need to use the index identifier.

Note that you have more than one class with .cls-1 , you must create a loop for these elements that handles each element.

You also need a onmouseout event that changes those colors and borders back to the they were before. The animation @keyframes will need to by tweaked to get a transformation on the onmouseback event.

See the snippit below:

 const changeColor = () => { document.querySelector(".link-label").style.color = '#3a4646'; document.getElementById("Arrow").style.fill = '#3a4646'; // because cls1 has more that one element within is HTML Collection // we must loop over the collection and style each element using // a index identifier within a loop using a basic for loop and iterator let cls1 = document.querySelectorAll(".cls-1"); for (let i = 0; i < cls1.length; i++) { cls1[i].style.stroke = '#3a4646'; } document.querySelector(".icon-arrow").style.border = "none"; } const changeBack = () => { document.querySelector(".link-label").style.color = '#eee'; document.getElementById("Arrow").style.fill = '#eee'; // because cls1 has more that one element within is HTML Collection // we must loop over the collection and style each element using // a index identifier within a loop using a basic for loop and iterator let cls1 = document.querySelectorAll(".cls-1"); for (let i = 0; i < cls1.length; i++) { cls1[i].style.stroke = '#eee'; } document.querySelector(".icon-arrow").style.border = "1px solid white"; }
 @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200&display=swap'); .container { height: 200px; display: grid; place-content: center; font-family: 'Poppins', sans-serif; background-color: #3a4646; }.btn--rounded { font-size: 20px; color: white; line-height: 1; letter-spacing: 0.4px; position: relative; cursor: pointer; display: inline-flex; align-items: center; padding: 12px 15px 12px 5px; transition: color 0.25s linear; text-decoration: none; background: transparent; border: none; z-index: 1; }.btn--rounded:before { width: 40px; height: 40px; position: absolute; top: 50%; transform: translateY(-50%); z-index: -1; animation-name: circleOut; animation-duration: 0.5s; animation-direction: alternate; animation-fill-mode: forwards; color: #eee; }.btn--rounded:hover:before { content: ''; border: none; position: absolute; top: 50%; z-index: -1; animation-name: circleIn; animation-duration: 0.8s; animation-direction: alternate; animation-fill-mode: forwards; }.icon-arrow { border: 1px solid white; border-radius: 100%; }.link-label { padding-left: 20px; } @keyframes circleOut { 0% { width: 100%; border-radius: 40px; background-color: #ffff; } 90% { border-radius: 40px; } 100% { width: 40px; border-radius: 100%; background-color: transparent; } } @keyframes circleIn { 0% { width: 60px; border-radius: 100%; background-color: transparent; } 10% { border-radius: 60px; } 100% { width: 100%; border-radius: 60px; background-color: #ffff; } }
 <div class="container"> <a href=# class="btn--rounded" onmouseover="changeColor()" onmouseout="changeBack()"> <div class="icon-arrow"> <svg xmlns="http://www.w3.org/2000/svg" width="36" height="36"> <defs> <style>.cls-1,.cls-2{fill:none}.cls-1{stroke:#fff}</style> </defs> <g id="Group_4802" transform="translate(-1113 -542)"> <g id="Rectangle_2080" class="cls-1" transform="translate(1113 542)"></g> <g id="Icon_Arrow_Base" transform="translate(1123 552)"> <path id="Ligne" d="M15 0H0" class="cls-1" transform="translate(0 8)"/> <path id="Arrow" fill="#fff" d="M12 0l-.727.727 2.753 2.753v1.039l-2.753 2.754L12 8l4-4z" transform="translate(0 4)"/> </g> </g> </svg> </div> <div class="link-label"> Subscribe! </div> </a> <div>

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