Importing MoonMap.js into my VueJS 2 project - javascript
I started a VueJS 2 project and I try to import a js I found which I need and is called Moon Map but since it seems that VueJS is using ES6 javascript and I try to import an ES5 javascript file it won't compile and I receive errors.
Can anyone here tell me or show me an example of importing an ES5 script inside my VueJS project?
Thanks.
EDIT - Still Relevant
I try to implement in socialCircle.
Home.vue
<template>
<div class="home">
<div class="wrapper">
<div class="box header"><div v-html="logo" class="logo"></div></div>
<div class="box content">
<div class="circle"></div>
<div class="socialCircle" v-for="social in socials">{{social.name}}</div>
</div>
<div class="box footer">Footer</div>
</div>
</div>
</template>
<script>
export default {
name: 'home',
data () {
return {
logo: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="29.094 45.2 229.507 71.651"><defs><style>.a{fill:#fff;}</style></defs><g transform="translate(29.094 45.2)"><g transform="translate(0)"><path class="a" d="M40.978,28.779V53.461a75.52,75.52,0,0,1-12.461,1.2c-9.585,0-16.775-2.157-21.328-6.47C2.4,43.876,0,37.406,0,28.3,0,19.433,2.4,12.723,7.189,8.41S18.931,1.7,28.037,1.7a44.489,44.489,0,0,1,11.5,1.438v7.668a41.366,41.366,0,0,0-10.784-1.2,25.908,25.908,0,0,0-10.544,1.917,13.688,13.688,0,0,0-6.231,5.991c-1.438,2.636-2.157,6.47-2.157,10.784,0,6.47,1.438,11.023,4.313,14.139q4.313,4.313,13.659,4.313a26.045,26.045,0,0,0,4.313-.24V28.779Z" transform="translate(0 2.374)"/><path class="a" d="M21.838,9.287A4.877,4.877,0,0,1,20.4,5.693,4.521,4.521,0,0,1,21.838,2.1C22.8,1.14,24.234.9,26.151.9a7.115,7.115,0,0,1,4.313,1.2A4.877,4.877,0,0,1,31.9,5.693a4.113,4.113,0,0,1-1.438,3.595c-.959.959-2.4,1.2-4.313,1.2A7.115,7.115,0,0,1,21.838,9.287Zm-.24,45.77v-38.1H30.7v38.1Z" transform="translate(28.486 1.257)"/><path class="a" d="M28.5,56.314V0h9.106V56.314Z" transform="translate(39.796)"/><path class="a" d="M59.5,8.838a10.314,10.314,0,0,1,5.272,4.793c1.2,2.157,1.677,5.272,1.677,9.106V46.221H58.784l-.719-3.834h-.479a11.712,11.712,0,0,1-4.313,3.355,16.686,16.686,0,0,1-5.991,1.2,14.268,14.268,0,0,1-6.47-1.438,9.052,9.052,0,0,1-4.074-3.834A11.385,11.385,0,0,1,35.3,35.917c0-3.595,1.2-6.231,3.595-8.148s6.231-3.115,11.5-3.595l7.189-.719V22.018a8.568,8.568,0,0,0-.959-4.553,5.6,5.6,0,0,0-2.876-2.4,15.488,15.488,0,0,0-5.272-.719,35.751,35.751,0,0,0-5.032.479,34.006,34.006,0,0,0-5.272,1.2V9.077a34.578,34.578,0,0,1,5.751-1.2A54.772,54.772,0,0,1,49.918,7.4,26.926,26.926,0,0,1,59.5,8.838ZM54.231,39.511a10.8,10.8,0,0,0,3.355-2.4V28.967l-6.231.479c-2.4.24-4.074.719-5.272,1.677a4.469,4.469,0,0,0-1.677,3.834,5.059,5.059,0,0,0,1.438,3.834,5.858,5.858,0,0,0,4.313,1.438A12.172,12.172,0,0,0,54.231,39.511Z" transform="translate(49.291 10.333)"/><path class="a" d="M52,7.879h7.668l.719,4.074h.479A14.274,14.274,0,0,1,65.9,8.6a18,18,0,0,1,6.231-1.2,13.509,13.509,0,0,1,9.346,3.355c2.4,2.157,3.355,5.991,3.355,11.023v24.2H75.724V22.257c0-2.636-.479-4.313-1.677-5.512-.959-1.2-2.636-1.677-4.793-1.677a10.384,10.384,0,0,0-4.553.959A14.619,14.619,0,0,0,60.867,18.9V45.742H52Z" transform="translate(72.611 10.333)"/><path class="a" d="M97.454,7.6,87.15,37.794,77.085,7.6H67.5L81.4,45.7h2.636L78.284,61.039H87.15L106.561,7.6H97.454ZM84.993,59.841a3.406,3.406,0,0,1-1.438.479,2.026,2.026,0,0,1-1.438-.479c-.479-.24-.479-.719-.479-1.438a2.569,2.569,0,0,1,.479-1.438,3.406,3.406,0,0,1,1.438-.479,2.026,2.026,0,0,1,1.438.479c.479.24.479.719.479,1.438S85.473,59.6,84.993,59.841Z" transform="translate(94.254 10.612)"/></g><g transform="translate(185.174 54.397)"><path class="a" d="M87.015,37.557h8.627v2.4H83.9V22.7H95.4v2.4H86.776v4.553H94.2v2.4H86.776v5.512Z" transform="translate(-66.407 -22.7)"/><path class="a" d="M94.712,39.954V25.336H89.2V22.7h14.139v2.636H97.827V39.954Z" transform="translate(-59.006 -22.7)"/><g transform="translate(0 0)"><path class="a" d="M76.6,33.248V36.6h2.876V25.1Z" transform="translate(-76.6 -19.349)"/><path class="a" d="M86.048,35.4,79.1,24.617l-1.2,3.115,7.908,12.221h3.115V22.7H86.048Z" transform="translate(-74.785 -22.7)"/></g></g></g></svg>',
socials: []
}
},
created () {
this.$http.get('/static/json/data.json').then(function ({data}) {
this.socials = data.frontPage.social
console.log(this.data)
})
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.logo {
width: 250px;
margin: 15px;
}
.circle {
background: #fff url(/static/img/me.acf533d.svg) no-repeat -40px 20px;
height: 350px;
width: 350px;
border-radius: 50%;
}
.socialCircle {
background: #fff;
height: 25px;
width: 25px;
border-radius: 50%;
}
.wrapper {
display: grid;
grid-template-areas:
"header header header"
"content content content"
"footer footer footer";
color: #444;
align-items: stretch;
}
.box {
background-color: #444;
color: #fff;
font-size: 150%;
display: flex;
align-items: center;
justify-content: center;
}
.header {
grid-area: header;
justify-content: flex-start;
height: 100px;
}
.content {
grid-area: content;
height: calc(100vh - 200px);
background: #333;
}
.footer {
grid-area: footer;
height: 100px;
background: #222;
}
</style>
Related
How can I remove class when click the same button
Please see code below: const sectionIcon = document.querySelectorAll(".nk-section-icons") const sectionContainer = document.querySelectorAll(".nk-sec-container") const sectionIconHover = document.querySelectorAll(".nk-section-icons") sectionIcon.forEach((sectionBtn)=> { sectionBtn.addEventListener("click", (btns)=> { // console.log(sectionIconHover) const containerTarget = btns.currentTarget.parentElement.children[1] const containerHoverTarget = btns.currentTarget.parentElement.children[0] sectionContainer.forEach(items => { if(items !== containerTarget) { items.classList.remove("show") // itemHover.classList.remove("rb") } }) sectionIconHover.forEach(itemHover => { if(itemHover !== containerHoverTarget) { itemHover.classList.remove("rb") } }) containerTarget.classList.toggle("show") containerHoverTarget.classList.add("rb") }) }) .nk-section-icons { height: 30px; min-width: 30px; width: 30px; display: flex; flex-direction: column; align-items: center; justify-content: center; cursor: pointer; border-radius: 3px; background: yellow; margin-bottom: 5px; } .nk-section-icons.rb { background: black; } .nk-sec-container { width: 300px; min-width: 300px; height: 100%; background: red; position: absolute; z-index: 11; box-shadow: rgba(17, 17, 26, 0.1) 0px 0px 16px; border-radius: 6px; left: 70px; top: 0px; } .nk-sec-container.show { background: green; } .nk-section-icons-container { position: relative; } <div class="nk-section-l-icons"> <div class="nk-section-icons-container"> <div class="nk-section-icons fav" data-title="Favorites">btn</div> <div class="nk-sec-container nk-sec-fav-c"> </div> </div> <div class="nk-section-icons-container"> <div class="nk-section-icons recent" data-title="Recent">btn</div> <div class="nk-sec-container nk-sec-recent-c"> </div> </div> <div class="nk-section-icons-container"> <div class="nk-section-icons notifs" data-title="Notifications">btn</div> <div class="nk-sec-container nk-sec-notif-c"> </div> </div> </div> Hello guys, can you please see my code? Currently, it's working fine when I click the button it's working the classes are moved when I click any of the buttons. However, if I tried clicking the same button again the class rb is not removed but the show class is removed. Can you please help me with how can I fix this? Thanks
<!DOCTYPE html> <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script> $(document).ready(function(){ $("button").click(function(){ if($("p").hasClass("main")) { $("p").toggleClass("main1"); } else { $("p").toggleClass("main"); } }); }); </script> <style> .main { font-size: 120%; color: red; } .main1 { font-size: 120%; color: green; } </style> </head> <body> <button>Toggle class "main" for p elements</button> <p>This is a paragraph.</p> <p>This is another paragraph.</p> <p><b>Note:</b> Click the button more than once to see the toggle effect.</p> </body> </html> Use toggling: Toggle between adding and removing the "main" class name for all elements The toggleClass() method toggles between adding and removing one or more class names from the selected elements.
Make dynamic fontsize using javascript to fit into a button
I have a button of fixed size and various chunks of text. The length of the texts is different. How can I make the size of the text font change dynamically according to its length in order to fit the button boundaries properly? Thank you.
Well, depends. Is the height fix as well? If both height and width are fixed, you will have to calculate the fontsize via javascript. In most of the cases two or three if conditions should be absolutely sufficient for the specific usecase. function font_size_adjust () { // Grab the string var string = $('#button_text').text() // Get the length in characters of the string var string_size = string.length // Build variable to change attribute var font_size = 0 // Define logic for resizing, adapt this to your personal needs if (string_size < 60) { fontsize = '2vw'; } else if (string_size > 60) { fontsize = '4vw'; } else {} // Change fontsize $('#button_text').css('font-size', fontsize) } // Call the function where- and whenever needed: font_size_adjust(); // Example stuff $('#toggle_small').click(function () { $('#button_text').text('Now I am small again!') font_size_adjust(); }) $('#toggle_big').click(function () { $('#button_text').text('Now I am large again! Lets get this rollin! rollin! rollin! rollin!') font_size_adjust(); }) #ctn { display: flex; float: left; } #button { width: 45vw; background-color: lightblue; padding: 10px; border-radius: 25px; margin-right: 1vw; font-family: Varela Round; color: #FFF; background: linear-gradient(126deg, rgba(143,61,217,1) 12%, rgba(109,35,177,1) 43%, rgba(101,34,162,1) 72%); } #ctn_toggle { display: flex; float: left; } .toggle { background-color: lightblue; font-size: 3vw; padding: 10px; border-radius: 25px; width: 11vw; text-align: center; margin-right: 2vw; font-family: Varela Round; } <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <link href="https://fonts.googleapis.com/css2?family=Varela+Round&display=swap" rel="stylesheet"> <html> <body> <div id="ctn"> <div id="button"> <p id="button_text">Make me small and big all day long this is so exciting! Let's go broooh!</p> </div> </div> <div id="ctn_toggle"> <div id="toggle_small" class="toggle"> <p id="button_small">Click me to shrink!</p> </div> <div id="toggle_big" class="toggle"> <p id="button_big">Click me to expand!</p> </div> </div> </body> </html> Otherwise, these are the options... : #ctn { display: flex; float: left; } #button { width: 20vw; background-color: lightblue; padding: 10px; border-radius: 25px; margin-right: 1vw; } #button_text { font-size: 4vw; } #button2 { width: 20vw; background-color: lightblue; padding: 10px; border-radius: 25px; margin-right: 1vw; } #button_text2 { } #button3 { width: 20vw; height: 10vh; background-color: lightblue; padding: 10px; border-radius: 25px; margin-right: 1vw; } #button_text3 { font-size: 4vw; } #button4 { width: 20vw; height: 10vh; background-color: lightblue; padding: 10px; border-radius: 25px; } #button_text4 { } <html> <body> <div id="ctn"> <div id="button"> <p id="button_text">Fix button width and fix font-size</p> </div> <div id="button2"> <p id="button_text2">Fix button width and no specific font-size</p> </div> <div id="button3"> <p id="button_text3">Fix button width, fix button height and fix font-size</p> </div> <div id="button4"> <p id="button_text4">Fix button width, fix button height and no font-size</p> </div> </div> </body> </html>
Is there a way to jump from a section into another section with Vanilla JavaScript?
I have two sections one over the other. What I want to do is that when I click the button, the first section display: none with a small transition and the second one appears. I need to do that with vanilla JavaScript as I'm learning it. My goal is to be able to create a login when the password is entered, the person is moved to the second section. (this is just for Front end, nothing backend). Here is the code below: *{ margin: 0; padding: 0; box-sizing: border-box; } /* Login Background */ #first{ position: absolute; width: 100%; height: 100vh; background-color: #464159; z-index: 1; } /* Login */ .login-container{ position: absolute; top: 50%; right: 50%; transform: translate(50%, -100%); display: flex; align-items: center; justify-content: center; } .logo{ justify-content: center; margin-right: 20px; } .logo img{ width: 180px; height: auto; } .user{ display: flex; flex-direction: column; } .w8u{ color: white; font-size: 15px; margin: 0 0 10px 0; } .submit{ flex: 1; margin: 30px 0 0 10px; } /* Menu */ #second{ position: absolute; width: 100%; height: 100vh; background-color: orangered; z-index: -1; } <body> <section id="first"> <div class="login-container"> <!-- Logo User --> <div class="logo"> <img src="w-logo.jpg" alt="User"> </div> <!-- User Name --> <div class="user"> <div class="w8u"> <h3>User</h3> </div> <div> <input class="input" type="password" placeholder="Enter your password" required> </div> </div> <!-- Submit Button --> <button id="btn-submit" class="submit" type="submit" onclick="">GO!</button> </section> <section id="second"> </section> <script src="app.js"></script> </body>
Yes, you can change CSS of elements using JavaScript: function login(){ document.getElementById("first").style.display="none"; document.getElementById("second").style.display="block"; } *{ margin: 0; padding: 0; box-sizing: border-box; } /* Login Background */ #first{ position: absolute; width: 100%; height: 100vh; background-color: #464159; z-index: 1; } /* Login */ .login-container{ position: absolute; top: 50%; right: 50%; transform: translate(50%, -100%); display: flex; align-items: center; justify-content: center; } .logo{ justify-content: center; margin-right: 20px; } .logo img{ width: 180px; height: auto; } .user{ display: flex; flex-direction: column; } .w8u{ color: white; font-size: 15px; margin: 0 0 10px 0; } .submit{ flex: 1; margin: 30px 0 0 10px; } /* Menu */ #second{ position: absolute; width: 100%; height: 100vh; background-color: orangered; z-index: -1; } <body> <section id="first"> <div class="login-container"> <!-- Logo User --> <div class="logo"> <img src="w-logo.jpg" alt="User"> </div> <!-- User Name --> <div class="user"> <div class="w8u"> <h3>User</h3> </div> <div> <input class="input" type="password" placeholder="Enter your password" required> </div> </div> <!-- Submit Button --> <button id="btn-submit" class="submit" type="submit" onclick="login()">GO!</button> </section> <section id="second"> Section 2 </section> <script> </script> </body>
Short Answer: You can solve your issue by using a common pattern of styling transitions and toggling classes in JavaScript. /* Get Screen Container */ let context = document.querySelector("main.screen-container"); /* Helper Methods */ // Utility const ele = context.querySelector.bind(context), eles = context.querySelectorAll.bind(context); // Action const showScreen = inactiveScreen => { const screens = eles(".screen"); screens.forEach(screen => screen.classList.remove("active-screen")); inactiveScreen.classList.add("active-screen"); } // Elements const login_button = ele("#loginBtn"), logout_button = ele("#logoutBtn"), login_screen = ele("#login"), loggedIn_screen = ele("#loggedIn"); // Add Event Listeners and Handlers login_button.addEventListener("click", () => showScreen(loggedIn_screen)); logout_button.addEventListener("click", () => showScreen(login_screen)); .full-width-full-height { width: 100%; height: 100%; } .no-overflow { overflow: hidden; } .inputs-container { display: flex; flex-direction: column; justify-content: center; height: 200px; padding: 5px; border: 5px black solid; } .inputs-container.inputs { padding: 10px; } .screen#login { display: flex; justify-content: center; } .screen#loggedIn { background: rgba(0,0,0,.5); border: 5px solid rgba(0,0,0,.3); text-align: center; } highlight { color: rgb(0,100,0); text-shadow: 3px 3px 10px rgb(0,200,0); } .screen-container { height: 100%; width: 100%; overflow: hidden; padding: 0px; margin: 0px; } main section { position: absolute; height: 0px; width: 0px; opacity: 0; transition: all .3s ease-in-out; } main section.active-screen { height: 100%; width: 100%; opacity: 1; } <body class="full-width-full-height no-overflow"> <main class="screen-container full-width-full-height"> <section id="login" class="screen active-screen"> <div class="inputs-container"> <div class="inputs"><label>Username:</label><input type="text" id="username" placeholder="admin" /></div> <div class="inputs"><label>Password:</label><input type="password" id="password" /></div> <button id="loginBtn">login</button> </div> </section> <section id="loggedIn" class="screen"> <h3>User Successfully <highlight>Logged In</highlight></h3> <button id="logoutBtn">logout</button> </section> </main> </body> Explanation of Answer: In your question you're asking for help in the following: Using Sections as Different Screens in an Application Change Screens on an Event such as click Transition between Screens when the Screen Changes Something like this isn't an atypical need and, in fact, just looking at the above you can see the resemblance between what you're looking for and common things like a carousel or tab navigation. Since this is the case there is a pretty common pattern when designing markup based around these types of requirements and this pattern is used in frameworks like BootStrap, DataTables, JQuery, etc. The Mark-Up Pattern: Create a Container Provide a class to define this type of container ( screen-container ) Create Visual Elements In your case Section Elements dubbed Screens Provide a class to define these specific elements In your case something like screen You will likely also want to provide an ID for each of these Visual Elements based on their Content. In your case something like login and loggedIn Create a class that will serve as the active Visual Element In your case something like active-screen Incorporating the above you end up with a basic outline: <main class="screen-container"> <section id="login" class="screen active-screen"></section> <section id="loggedIn" class="screen"></section> </main> Example: html, body, main, .screen-container { height: 100%; width: 100%; } .screen-container .screen { padding: 3px; background: rgba(24,24,24, .3); border: 3px solid black; width: 100px; height: 100px; } .screen-container .screen.active-screen { border-color: green; } <main class="screen-container"> <section id="login" class="screen active-screen">login</section> <section id="loggedIn" class="screen">logged in</section> </main> Styling: In your initial question you say that you want to use the display property to hide and show your screens, however, you also state that you would like to have the screens transition from one to another. Transitioning is definitely possible through the aptly named CSS transition property ( More info on MDN ). The problem is that the display property is not able to be animated. If an element is configured to display: none; the page is immediately repainted with that element removed. This means that you need to use a different property, and we typically would use opacity or visibility. Here are the differences between these three: display: none; immediately collapses the element removes the element from view. There's no transition allowed. visibility: hidden; Does not collapse the element The space it occupied is blank. removes the element from view Transitions are allowed The element will still pop out of sight. opacity: 0; Does not collapse the element The space it occupied is blank. removes the element from view Transitions are allowed. The element will fade until it is not visible. Here is an example of the different way these properties affect the layout of the page: const context = document.querySelector("#examples"); const ele = context.querySelector.bind(context), hide = section => section.classList.toggle("hide"), onClickHide = (btn, section) => btn.addEventListener("click", () => hide(section)); opacity = ele(".opacity"), opacity_button = ele("#oBtn"), visibility = ele(".visibility"), visibility_button = ele("#vBtn"), display = ele(".display"), display_button = ele("#dBtn"), toggle_button = ele("#tBtn"); onClickHide(opacity_button, opacity); onClickHide(visibility_button, visibility); onClickHide(display_button, display); toggle_button .addEventListener("click", function() { hide(opacity); hide(visibility); hide(display); }); html, body, #examples { width: 100%; height: 100%; box-sizing: content-box; margin: 0px; padding: 0px; } #examples section { display: flex; flex-direction: column; width: 100px; height: 100px; border: 5px solid black; margin: 5px; transition: all .5s ease-in-out; } #examples section.hide { border-radius: 100px; } #examples section.opacity { background-color: blue; color: white; } #examples section.opacity.hide { opacity: 0; } #examples section.visibility { background-color: purple; color: white; } #examples section.visibility.hide { visibility: hidden; } #examples section.display { display: block; background-color: red; color: white; } #examples section.display.hide { color: black; display: none; } <main id="examples"> <section class="opacity">opacity <button id="oBtn">hide</button></section> <hr /> <section class="visibility">visibility <button id="vBtn">hide</button></section> <hr /> <section class="display">display <button id="dBtn">hide</button></section> <hr/> <button id="tBtn">Toggle All</button> </main> Note: In the above there are actually two properties transitioning - opacity, visibility, or display - and border-radius. You should notice firstly how in the display example the border-radius change isn't seen at all, and secondly how the display example is the only one that collapses the element so that it no longer takes up space. Applying Transitions: By combining opacity: 0; with height: 0px; width: 0px; we can remove the element visually from the page while also removing any impact it has on other elements - meaning that it won't take up space and is transitionable. setInterval(function() { const screens = [ document.querySelector(".screen.active-screen"), document.querySelector(".screen:not(.active-screen)") ]; screens[0].classList.toggle("active-screen"); screens[0].ontransitionend = () => { screens[1].classList.toggle("active-screen"); screens[0].ontransitionend = undefined; } }, 1000) html, body, main, .screen-container { height: 100%; width: 100%; } .screen-container .screen { transition: all .3s ease-in-out; opacity: 0; height: 0px; width: 0px; } .screen-container .screen.active-screen { background: rgba(24, 24, 24, .3); border: 3px solid black; padding: 3px; border-color: green; width: 100px; height: 100px; opacity: 1; } <main class="screen-container"> <section id="login" class="screen active-screen">login</section> <section id="loggedIn" class="screen">logged in</section> </main> JavaScript The final piece of the puzzle is the JavaScript mechanics of the Screens. Any Programmer wants to make the switch as easy as possible, and this is done typically by providing a function that allows for quick reassignment of the class active-screen by removing it from the current active screen and applying it to the desired visual element. One thing to take into account is that you want your queries for elements to be as specific as possible. Meaning that instead of document.querySelector you want to provide the smallest context of where to find your Visual Elements. a.e. /* Get Screen Container */ let context = document.querySelector("main.screen-container"); /* Helper Methods */ // Utility const ele = context.querySelector.bind(context), eles = context.querySelectorAll.bind(context); This prevents code collision where other code in your Application's JavaScript, Styling, or Mark-Up may utilize a screen or active-screen class that isn't relevant to what you're doing here. Note: This is actually a problem in BootStrap currently. It searches for the active class in it's Tab architecture. This is such a generic class name that other libraries utilize it and it can cause a giant headache to get things to work properly. Writing explicit patching because you didn't think through your design fully is something I'd just as soon spare you from, so try to keep interactivity with other code in mind. Lastly we write our function ( showScreen ) that allow for quick, easy switching between screens: // Action const showScreen = inactiveScreen => { const screens = eles(".screen"); screens.forEach(screen => screen.classList.remove("active-screen")); inactiveScreen.classList.add("active-screen"); } And believe it or not, that's pretty much it! All that's left to do is apply this functionality to your button click events and it works just as it should: Result: /* Get Screen Container */ let context = document.querySelector("main.screen-container"); /* Helper Methods */ // Utility const ele = context.querySelector.bind(context), eles = context.querySelectorAll.bind(context); // Action const showScreen = inactiveScreen => { const screens = eles(".screen"); screens.forEach(screen => screen.classList.remove("active-screen")); inactiveScreen.classList.add("active-screen"); } // Elements const login_button = ele("#loginBtn"), logout_button = ele("#logoutBtn"), login_screen = ele("#login"), loggedIn_screen = ele("#loggedIn"); // Add Event Listeners and Handlers login_button.addEventListener("click", () => showScreen(loggedIn_screen)); logout_button.addEventListener("click", () => showScreen(login_screen)); .full-width-full-height { width: 100%; height: 100%; } .no-overflow { overflow: hidden; } .inputs-container { display: flex; flex-direction: column; justify-content: center; height: 200px; padding: 5px; border: 5px black solid; } .inputs-container.inputs { padding: 10px; } .screen#login { display: flex; justify-content: center; } .screen#loggedIn { background: rgba(0,0,0,.5); border: 5px solid rgba(0,0,0,.3); text-align: center; } highlight { color: rgb(0,100,0); text-shadow: 3px 3px 10px rgb(0,200,0); } .screen-container { height: 100%; width: 100%; overflow: hidden; padding: 0px; margin: 0px; } main section { position: absolute; height: 0px; width: 0px; opacity: 0; transition: all .3s ease-in-out; } main section.active-screen { height: 100%; width: 100%; opacity: 1; } <body class="full-width-full-height no-overflow"> <main class="screen-container full-width-full-height"> <section id="login" class="screen active-screen"> <div class="inputs-container"> <div class="inputs"><label>Username:</label><input type="text" id="username" placeholder="admin" /></div> <div class="inputs"><label>Password:</label><input type="password" id="password" /></div> <button id="loginBtn">login</button> </div> </section> <section id="loggedIn" class="screen"> <h3>User Successfully <highlight>Logged In</highlight></h3> <button id="logoutBtn">logout</button> </section> </main> </body> Conclusion: I hope this helps and gives you some insight into how this pattern is used! It's not a difficult thing to learn, but it's incredibly useful! Good luck and Happy Coding!
How do I give elements with the same class name to perform the same function in javascript?
I have multiple elements with the same class name and want them to perform the same javascript function but output their unique "inner.Text" specific to the element i clicked. Right Now i know i need an [index] and a loop but I just don't know how to implement that at the moment since im a novice in javascript. spent 3 hours trying to figure it out const myButton = document.querySelectorAll('.clipboard-icon'); const myInp = document.querySelectorAll('.snippetcode'); myButton.forEach(ree => ree.addEventListener('click', copyElementText)); function copyElementText(id) { var text = myInp.innerText; var elem = document.createElement("textarea"); document.body.appendChild(elem); elem.value = text; elem.select(); document.execCommand("copy"); document.body.removeChild(elem); console.log('clicked'); } console.log(myButton); console.log(myInp); /*everything works fine if the script was changed to affect only ONE class name but I cant figure out how to make them work for more than one */ .snippet1 { border: solid rgb(55, 63, 184) 3px; } .snippet_holder { display: flex; flex-direction: column; justify-content: center; align-items: center; height: 100%; padding: 0 3.5rem; margin: 0 0 1rem 0; position: relative; } .buttons { width: 170px; height: 40px; border: 0; padding: 0; font-size: 1rem; color: #fff; border-radius: 10px; } .snippet_holder:hover .clipboard-icon { display: block; position: absolute; top: 15px; right: 65px; background: rgb(51, 153, 136); margin: 0; width: 30px; padding: 0; height: 30px; } .clipboard-icon { display: none; } .clipboard-icon img { width: inherit; height: inherit; position: relative; } .clipboard-icon pre { display: none; } .snippetcode1 { display: none; } .button1 { -webkit-animation: rainbow 6.5s ease infinite; animation: rainbow 6.5s ease infinite; background-image: linear-gradient(124deg, #ff470f, #ff3860, #b86bff, #3273dc); background-size: 800% 800%; } #keyframes rainbow { 0% { background-position: 1% 80%; } 50% { background-position: 99% 20%; } 100% { background-position: 1% 80%; } 0% { background-position: 1% 80%; } 50% { background-position: 99% 20%; } 100% { background-position: 1% 80%; } } main { margin: 0 auto; display: flex; flex-direction: column; justify-content: center; align-items: center; } <html> <body> <main> <div class="snippet_holder snippet_holder1"> <div class="clipboard-icon"> <pre> <code class= "snippetcode"> 1st class text copieddddd </code> </pre> <img src="https://www.shareicon.net/data/128x128/2016/04/27/756265_clipboard_512x512.png"> </div> <button type="button" class="buttons button1">button</button> </div> <div class="snippet_holder snippet_holder1"> <div class="clipboard-icon"> <pre> <code class= "snippetcode"> 22222nddd class text copieddddd </code> </pre> <img src="https://www.shareicon.net/data/128x128/2016/04/27/756265_clipboard_512x512.png"> </div> <button type="button" class="buttons button1">button</button> </div> <div class="snippet_holder snippet_holder1"> <div class="clipboard-icon"> <pre> <code class= "snippetcode"> 3rd class text copieddddd </code> </pre> <img src="https://www.shareicon.net/data/128x128/2016/04/27/756265_clipboard_512x512.png"> </div> <button type="button" class="buttons button1">button</button> </div> <div class="snippet_holder snippet_holder1"> <div class="clipboard-icon"> <pre> <code class= "snippetcode"> 4thhhhhhhhclass text copieddddd </code> </pre> <img src="https://www.shareicon.net/data/128x128/2016/04/27/756265_clipboard_512x512.png"> </div> <button type="button" class="buttons button1">button</button> </div> </main> </body> </html>
You've to query the .snippetcode related to the button pressed, so, it makes no sense to query the nodeList myInp, you can access to the right element using the currentTarget provided in the event object... function copyElementText(event) { var text = event.currentTarget.querySelector('.snippetcode').innerText; var elem = document.createElement("textarea"); document.body.appendChild(elem); elem.value = text; elem.select(); document.execCommand("copy"); document.body.removeChild(elem); console.log('clicked'); }
Create a custom drop down menu and place dataset value in input
I'm trying to create a custom drop down menu, using HTML, CSS and Vanilla Javascript. I've managed to get the menu to appear when the user clicks on the the "from" input field, however when I try and click on an option, it wont let you add the value stored in the "code" dataset. I did get it to work by using setTimeout method, however it is a bit hit and miss sometimes and doesn't seem like a good solution. Is there an alternative way to get it to work? function app() { var messages = document.querySelector(".messages"); var inputFrom = document.querySelector(".input-from"); var inputTo = document.querySelector(".input-to"); var nearestContainer = document.querySelector(".nearest-container"); inputFrom.addEventListener("focus", inputToFocusIn, false); function inputToFocusIn(e) { messages.innerHTML = "focusin event triggered on input-from"; // add class inputFrom.classList.add("input-from--focusin"); nearestContainer.classList.add("nearest-container--active"); // remove class inputFrom.classList.remove("input-from--focusout"); nearestContainer.classList.remove("nearest-container--hidden"); } inputFrom.addEventListener("focusout", inputToFocusOut, false); function inputToFocusOut(e) { messages.innerHTML = "focusout event triggered on input-from"; // add class inputFrom.classList.remove("input-from--focusin"); nearestContainer.classList.remove("nearest-container--active"); // remove class inputFrom.classList.add("input-from--focusout"); nearestContainer.classList.add("nearest-container--hidden"); } var nearestStations = document.querySelectorAll(".nearest-station"); // add event listener to buttons for(var nearestStation of nearestStations) { nearestStation.addEventListener("click", addToInputFrom, false); } function addToInputFrom(e) { inputFrom.classList.add("input-from--focusout"); nearestContainer.classList.add("nearest-container--hidden"); inputFrom.classList.remove("input-from--focusin") nearestContainer.classList.remove("nearest-container--active") var targetDataset = e.currentTarget.dataset.code; messages.innerHTML = "station added to input from field" inputFrom.value = ""; inputFrom.value = targetDataset; } var switchButton = document.querySelector(".button-switch"); switchButton.addEventListener("click", clickSwitch, false); function clickSwitch(e) { var inputFromValue = inputFrom.value; var inputToValue = inputTo.value; inputFrom.value = inputToValue; inputTo.value = inputFromValue; } } window.onload = app(); /* stylesheet */ body { font-family: "GRAPHIK"; font-style: normal; font-weight: 400; font-size: 16px; color: #242424; } * { box-sizing: border-box; outline: none; } .container { display: flex; flex-direction: column; justify-content: center; align-items: center; width: 100vw; height: 100vh; background-color: #FF4136; } .search-container { display: flex; flex-direction: column; flex-shrink: 0; width: 300px; padding: 10px; background-color: #FFF; border-radius: 10px; } .form-container { display: flex; flex-direction: row; width: 100%; } .input-container { width: 100%; } .input { width: 100%; border: none; border-radius: 10px; background-color: #f1f1f1; padding: 10px; } .input-from { margin-bottom: 5px; } .input-from--focusout { border-radius: 10px; } .input-from--focusin { border-radius: 10px 10px 0 0; } .input-to { margin-bottom: 5px; } .switch-container { margin-bottom: 5px; } .button { border: none; background-color: transparent; } .button-switch { height: 100%; width: 38px; margin-left: 5px; background-color: #f1f1f1; border-radius: 10px; background-image: url(../assets/images/switch.svg); background-position: center; background-size: 20px; background-repeat: no-repeat; } .button-switch:hover { background-image: url(../assets/images/switch-hover.svg); } .button-search { padding: 10px; background-color: #2ECC40; color: #FFF; border-radius: 10px; width: 100%; transition: background-color 0.5s ease; } .button-search:hover { background-color: #33e147; } .input-container-to { position: relative; } .nearest-container { position: absolute; top: 38px; background-color: #f1f1f1; padding: 5px; border-radius: 0 0 10px 10px; width: 100%; z-index: 100; } .messages { width: 300px; background-color: #FFF; padding: 5px; border-radius: 10px; text-align: center; margin-bottom: 5px; font-size: 10px; } .finding, .show-more { width: 100%; font-size: 10px; font-style: italic; margin: 0; padding: 5px; } .show-more { text-align: center; } .nearest-station { font-size: 10px; padding: 5px; border-radius: 10px; } .nearest-container--hidden { display: none; } .nearest-station--active { display: flex; } .nearest-station:hover { background-color: #FFF; cursor: pointer; } .logo { margin-right: 5px; } .nr-logo { width: 15px; } .station-distance { font-style: italic; float: right; } <div class="container"> <div class="messages">messages here</div> <div class="search-container"> <div class="form-container"> <div class="input-container"> <div class="input-container-to"> <input type="text" class="input input-from" placeholder="From"> <div class="nearest-container nearest-container--hidden"> <div class="stations-container"> <p class="finding">Finding stations closest to you...</p> <!-- stations here--> <div class="nearest-station" data-code="Leigh-on-Sea"> <span class="logo"><img class="nr-logo" src="assets/images/nr-logo.svg"></span> <span class="station-name">Leigh-on-Sea</span> <span class="station-distance">0.6km</span> </div> <div class="nearest-station" data-code="Chalkwell"> <span class="logo"><img class="nr-logo" src="assets/images/nr-logo.svg"></span> <span class="station-name">Chalkwell</span> <span class="station-distance">1.5km</span> </div> <div class="nearest-station" data-code="Westcliff"> <span class="logo"><img class="nr-logo" src="assets/images/nr-logo.svg"></span> <span class="station-name">Westcliff</span> <span class="station-distance">2.7km</span> </div> <div class="nearest-station" data-code="Southend Central"> <span class="logo"><img class="nr-logo" src="assets/images/nr-logo.svg"></span> <span class="station-name">Southend Central</span> <span class="station-distance">3.6km</span> </div> <div class="nearest-station" data-code="Southend Victoria"> <span class="logo"><img class="nr-logo" src="assets/images/nr-logo.svg"></span> <span class="station-name">Southend Victoria</span> <span class="station-distance">3.8km</span> </div> </div> <div class="stations-show-more"> <!-- <p class="show-more">Show more stations</p> --> </div> </div> </div> <div class="input-container-to"> <input type="text" class="input input-to" placeholder="To"> </div> </div> <div class="switch-container"> <input type="button" class="button button-switch"> </div> </div> <div class="button-search-container"> <input type="button" class="button button-search" value="Search"> </div> </div> </div>
Using setTimeout in the inputToFocusOut() function is indeed the correct way to obtain the desired effect: hiding of the menu must be delayed so that a click on a menu item will register and its callback will fire. There should be nothing hit and miss about it, just set the delay at a reasonable value, say 300ms, and remove the hiding of the menu from the addToInputFrom() callback. Actually, you can remove all of the latter function's class-toggling calls, as they are redundant there and may interfere. The menu will be shown/hidden by virtue of inputFrom gaining/losing focus. BTW, why are you using focusout and not blur?
Using focusout event here inputFrom.addEventListener("focusout", inputToFocusOut, false); is not right. Because it will be triggered before click event. When the function inputToFocusOut is executed the .nearest-container becomes hidden: nearestContainer.classList.add("nearest-container--hidden"); and that's why click event for it and all of its child nodes (we are interested in .nearest-station elements) won't be triggered. Instead of focusout, use mousedown event. With blur event it won't work.