Navbar opacity on scroll vuejs - javascript

I want to change the opacity of my fixed navbar background when user scrolling the page. Initially navbar background should be transparent and when scrolling down it background needs to be change to white.
Like this example https://codepen.io/michaeldoyle/pen/Bhsif
I have found various examples for this scenario using jquery. But I need to achieve this using vuejs.
$(window).scroll(function() {
if ($(document).scrollTop() > 200) {
$('nav').addClass('transparent');
} else {
$('nav').removeClass('transparent');
}
});
I tried above code inside my vue page. I put it inside mounted(). But it doesn't work. I need to done this using vue. Not like above jquery.
<nav class="navbar navbar-inverse">
<ul class="nav menu">
<li>
<router-link to="/about" #click.native="closeNavBarFromChild">About</router-link>
</li>
<li class="hidden-lg hidden-md">
<router-link to="/product" #click.native="closeNavBarFromChild">Product</router-link>
</li>
</ul>
</nav>
This is how my navbar component looks like.
nav.navbar{
-webkit-transition: all 0.4s ease;
transition: all 0.8s ease;
}
.navbar-inverse {
background-color: rgba(255,255,255,0);
}
nav.navbar.transparent {
background-color:rgba(0,0,0,1);
}
this is the css part that i used.

Set your listener in created lifecycle hook:
export default {
created () {
window.addEventListener('scroll', this.onScroll);
},
destroyed () {
window.removeEventListener('scroll', this.onScroll);
},
methods: {
onScroll (event) {
// add/remove class
}
}
}

Related

Changing pages disables navbar menu on Ruby on Rails

I have this problem. When the screen width goes below 1024px, the navbar changes to a responsive navbar that activates when a burger menu is clicked, this is made using javascript (it is being correctly compiled, the file is imported in application.js). This functionality works fine, but when I change pages (from home to store for example) it stops working, and I can't find the reason. Here's the code:
/* Javascript file */
document.addEventListener('DOMContentLoaded', () => {
let responsiveMenu = document.querySelector('.responsive-navbar');
let body = document.querySelector('body');
let burgerBtn = document.querySelector('.burger-menu');
let responsiveLinks = document.querySelectorAll('.responsive-menu-links')
burgerBtn.addEventListener('click', () => {
burgerBtn.classList.toggle('cross')
responsiveMenu.classList.toggle('menu-open');
body.classList.toggle('disable-scroll');
responsiveLinks.forEach(link => {
link.classList.toggle('trigger-anim')
})
})
})
/* _navbar.html.erb partial */
<div class="navbar-header">
<div class="navbar-menu">
<%=link_to 'Inicio', root_path%>
ustedes
contacto
sobre mi
<%=link_to 'Tienda', store_path%>
</div>
<div class="burger-menu">
<span></span>
<span></span>
<span></span>
</div>
<div class="responsive-navbar">
<div class="menu-background"></div>
<div class="menu-links">
<%=link_to 'Inicio', root_path, class: 'responsive-menu-links'%>
ustedes
contacto
sobre mi
<%=link_to 'Tienda', store_path, class: 'responsive-menu-links'%>
</div>
</div>
<div class="navbar-items">
<div class="logo">
</div>
</div>
</div>
/* styles */
.trigger-anim {
animation: scaleIn .2s forwards;
}
.menu-open {
width: 100vw !important;
a {
opacity: 1 !important;
}
}
.disable-scroll {
overflow: hidden;
.home-container {
height: 100vh !important;
overflow: hidden !important;
}
}
.cross {
span {
&:nth-of-type(1) {
transform: rotate(40deg) translateY(20px);
}
&:nth-of-type(2) {
transform: translateX(500px);
opacity: 0;
}
&:nth-of-type(3) {
transform: rotate(-40deg) translateY(-20px);
}
}
}
Sounds like you are using Rails with Turbolink so your event needs to be turbolinks:load and not DOMContentLoaded so:
document.addEventListener("turbolinks:load", function() {
// ...
})
From the Turbolinks documentation:
You may be used to installing JavaScript behavior in response to the
window.onload, DOMContentLoaded, or jQuery ready events. With
Turbolinks, these events will fire only in response to the initial
page load, not after any subsequent page changes.
Turbolinks triggers a series of events during navigation. The most
significant of these is the turbolinks:load event, which fires once on
the initial page load, and again after every Turbolinks visit.
Hope that helps.

On state change, do animation

Currently I'm working in Vue.js and have a navigation menu that I'd like to animate. What I'm looking to do is show two li elements when a user hovers over one of the navigational buttons.
Currently what I'm doing is setting a data type of showActivities to false by default and setting that to true on mouseenter and false on mouseleave. So this has the items appearing and disappearing on hover but they're not animated. How could animation for this be done?
<ul class="navs">
<li>Schedule</li>
<li #mouseenter="showActivities = true" #mouseleave="showActivities = false">Team Activity</li>
<li v-show="showActivities">tik tak tow</li>
<li v-show="showActivities">Bejewel</li>
<li>Resources</li>
<li class="logout">Logout</li>
</ul>
<script>
export default {
name: 'SideMenu',
data() {
return {
showActivities: false,
};
},
};
</script>
okay if i got you correct you want a type of animation like a slow fade In and Out.
In vuejs transitions, state are attached to CSS classes that can be called and modified ass you want it to be. The doc is clearer about it
Vuejs Transitions
for example if you add this in your css section the transition will be a slow fade In and Out:
.fade-enter-active, .fade-leave-active {
transition: opacity .5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
}

How do I make a navbar pop up when I click on an icon

I'm a beginner trying to learn react and watched this tutorial on making a navbar. For a smaller screen size I followed it to make a navbar that pops up on the side when I press the menu icon. Ive made the navbar that pops up on the side and to hide it, I used translatex(-500px). Now I dont know how to get it to pop up when I press the icon, should I use some code inside css or use an onclick function what would be more efficient?
```
function NavBar() {
return(
<div>
<nav>
<div className="logo">React Nav</div>
<ul id="bc" className="nav-links">
<li><a>Home</a></li>
<li><a>Home</a></li>
<li><a>Home</a></li>
<li><a>Home</a></li>
<li><a>Home</a></li>
</ul>
<i onClick="burger()" className="fas fa-bars burger"></i>
</nav>
</div>
)
}
```
this is the navbar code
#media all and (max-width: 768px) {
nav .burger {
display: block;
}
nav .nav-links {
position: absolute;
display: block;
top: 0;
left: 0;
height: 100vh;
padding: 20px;
background-color: blue;
width: 50%;
transform: translateX(-500px);
}
this is the css for the side navbar
import React from "react";
const burger = () => {
document.getElementbyId("bc").className = "bclick";
}
export default burger;
I tried making this function and passing it as onclick in the i tag and then I had another class called bclick which was translateX(500px) but that didnt work
Welcome to the world of React. You will want to look into "state", or if you are using React 16.8+ the useState hook. Learn more about hooks here: https://reactjs.org/docs/hooks-state.html
Your code could be something like this:
function NavBar() {
const [isOpen, setOpen] = useState(false);
return (
<div>
<nav>
<div className="logo">React Nav</div>
<ul className={isOpen ? "nav-links is-open" : "nav-links"}>
...
</ul>
<i onClick="() => setOpen(!isOpen)" className="fas fa-bars burger"></i>
</nav>
</div>
)
Add this to your css, so the navigation bar is visible again, when open
nav .nav-links.open {
transform: translateX(0);
}
Final remark: translateX(500px) is just moving your navigation bar into the opposite direction, but you probably want it show show in its actual position - thus resetting the transformation with translateX(0).

How to toggle sidebar without page reload when router-link is clicked in Vue 3

I have a sidebar component that works similar to a modal. When a button is clicked, the sidebar translates into the viewport with nav links. These nav links are actually router-links that are wired up to a vue-router.
What I'm trying to accomplish
When I click on a router-link that is inside my sidebar component, I want the sidebar to transition off the viewport and I want the clicked router-link's component to render without the page reloading.
What's currently happening
When I click on the router-link, the sidebar is removed instantly from the DOM. It does not translate off the screen as intended. Also, the page is reloaded.
What else have I tried
I also tried moving the <transition> wrapper inside TheSidebar.vue component along with the associated CSS classes, and I passed sidebarIsVisible as a prop from App.vue to TheSidebar.vue.
My code
A Codesandbox demo can be found here
App.vue
<template>
<router-view></router-view>
<button #click="toggleSidebar" class="toggleBtn">Toggle Sidebar</button>
<transition name="sidebar">
<the-sidebar
v-if="sidebarIsVisible"
#link-clicked="toggleSidebar"
></the-sidebar>
</transition>
</template>
<script>
import TheSidebar from "./components/TheSidebar.vue";
export default {
components: {
TheSidebar,
},
data() {
return {
sidebarIsVisible: false,
};
},
methods: {
toggleSidebar() {
this.sidebarIsVisible = !this.sidebarIsVisible;
},
closeSidebar() {
this.sidebarIsVisible = false;
},
},
};
</script>
<style>
/* basic styling */
.toggleBtn {
position: fixed;
top: 5px;
left: 5px;
}
.sidebar-enter-active {
animation: slide-sidebar 0.3s ease;
}
.sidebar-leave-active {
animation: slide-sidebar 0.3s ease reverse;
}
#keyframes slide-sidebar {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
</style>
TheSidebar.vue
<template>
<div class="sidebar">
<nav>
<ul>
<li>
<router-link #click="$emit('link-clicked')" to="/link1">
Link 1
</router-link>
</li>
<li>
<router-link #click="$emit('link-clicked')" to="/link2">
Link 2
</router-link>
</li>
</ul>
</nav>
</div>
</template>
<script>
export default {
emits: ["link-clicked"],
};
</script>
<style scoped>
/* basic styling */
</style>
main.js
import { createApp } from "vue";
import { createRouter, createWebHistory } from "vue-router";
import App from "./App.vue";
import LinkOne from "./components/LinkOne.vue";
import LinkTwo from "./components/LinkTwo.vue";
const app = createApp(App);
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: "/link1", component: LinkOne },
{ path: "/link2", component: LinkTwo }
]
});
app.use(router);
app.mount("#app");
There are a couple of things I'm unsure about here but I'll try and explain what I think is happening.
Firstly, the click event on the router-link is what's causing the page to reload, but I can't find anything in the docs mentioning this as expected behaviour (it might be worth opening an issue on the GitHub repo).
The fix for this is to use event-delegation by moving the event-handler onto the ul and creating a method to determine if a link has been clicked (example below).
Secondly, and this is where things get weird, in VSCode, using kebab-case in the child components' emitted event seems to prevent anything from being emitted, so changing them to camelCase fixes this. But, trying this in CodeSandbox simply doesn't work, and ESLint complains that the emitted event should be kebab-case. So, in CodeSandbox, the opposite is true: the emitted event names should be kebab-case and the listener should be camelCase! Absolutely no idea why as this goes against what the docs say on casing:
...we recommend using kebab-cased event listeners when you are using in-DOM templates.
Again, I can't find anything in the docs explicitly saying you need to use camelCase when emitting an event, it just says kebab-case is preferred when listening for an event.
So, all in all, for your code to work in VSCode and in a way which follows what is recommended by the docs, you need to change it to this:
<template>
<div class="sidebar">
<nav>
<!-- Move event here -->
<ul #click="handleClick($event)">
<li>
<router-link to="/link1">
Link 1
</router-link>
</li>
<li>
<router-link to="/link2">
Link 2
</router-link>
</li>
</ul>
</nav>
</div>
</template>
<script>
export default {
emits: ['linkClicked'], // Use camelCase for emitting
methods: {
handleClick(e) {
// Check the target is a link being clicked
if (e.target.localName !== 'a') return
this.$emit('linkClicked')
}
}
}
</script>
Keep App.vue exactly as you have it already and it should work.
For your code to work in CodeSandbox, swap the casing:
...
emits: ['link-clicked'], // Use kebab-case for emitting
...
this.$emit('link-clicked')
...
App.vue:
#linkClicked="toggleSidebar"
Working example.
If anyone could shed some light on this, it'd be great as I'm completely stumped on what's happening here.

Transition in Navbar when Scroll Down

My navbar color will be change when I scroll down. The color is changing. But there is no transition effects. How to give a transition for this. Here is my Code..
$(window).scroll(function() {
if($(this).scrollTop() > 0)
{
$('.navbar-trans').addClass('afterscroll');
} else
{
$('.navbar-trans').removeClass('afterscroll');
}
});
This is my script code. and my css is,
.navbar.navbar-trans.afterscroll { background-color:#1ba4df; }
How to give an animation to this.
Just add this rule in your css file. It will work for you, because here the transition property is set to all changes...
.navbar-trans {transition: all 0.3s ease; /* other css rules here */}
Read more about transition property here...
Thats it... Try this dude....
.navbar.navbar-trans.afterscroll {
background-color:#1ba4df;
Transition:0.3s all linear;
}

Categories