This is JS, I try to change "touch" to "click", but nothing happens:
$(document).ready(function(){
var touch = $('#resp-menu');
var menu = $('.menu');
$(touch).on('click', function(e) {
e.preventDefault();
menu.slideToggle();
});
$(window).resize(function(){
var w = $(window).width();
if(w > 767 && menu.is(':hidden')) {
menu.removeAttr('style');
}
});
});
You can see the full dropdown menu here:
http://codepen.io/anon/pen/ygbpmV
.menu li:hover>ul {
visibility: visible;
opacity: 1;
transform: translate(0,0);
}
replace with
.menu li.active>ul {
visibility: visible;
opacity: 1;
transform: translate(0,0);
}
JS
$(document).ready(function(){
var touch = $('#resp-menu');
var menu = $('.menu li');
$(menu).on('click', function(e) {
e.preventDefault();
$(this).addClass('active');
}).on('mouseleave',function(){
$(this).removeClass('active');
});
$(window).resize(function(){
var w = $(window).width();
if(w > 767 && menu.is(':hidden')) {
menu.removeAttr('style');
}
});
});
You are actually setting the onclick function as it's supposed to be.
You can test this by writing this in the developers console.
var touch = $('#resp-menu');
touch.click();
The issue here is that the "touch" element can't be clicked because you can't see it.
Perhaps you should think again where do you want the event to happen.
Related
I have the following code which 'shows/hides' my navigation up off the top of the screen, and brings it down again.
jQuery(document).ready(function($){
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('nav').outerHeight(true);
$(window).scroll(function(event) { didScroll = true; });
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 0);
function hasScrolled() {
if($( window ).width() > 768) {
var st = $(this).scrollTop();
if (Math.abs(lastScrollTop - st) <= delta)
return;
if (st > lastScrollTop) {
// Scroll Down
$('#screen-nav').removeClass('nav-down').addClass('nav-up');
} else {
$('#screen-nav').removeClass('nav-up').addClass('nav-down');
}
}
lastScrollTop = st;
}
});
css
#screen-nav {
position: fixed;
top: 0; left: 0; right: 0;
}
#screen-nav.nav-up { top: -100px; }
#screen-nav.nav-down { top: 0; }
The problem is that on the safari browser and when the screen changes from mobile size (<768px on all browsers) to screen size sometimes the .nav-up class gets added and the navigation doesn't show. But only when the user scrolls to the top of the page.
Not sure if there is a better way to write the code to ensure proper functionality.
I see you are using this example. He has the fiddle working well too. the only thing is that on browser resize nothing regarding show the nav is in place. You should be able to just add that separately.
$(window).resize(function(){
$('#screen-nav').removeClass('nav-up').addClass('nav-down')
});
I updated his original fiddle to reflect the addition of window resize handling.
I'm trying to create a div which will get a class only on scrolling and when the value of scroll is 210. I have next code :
$(document).ready(function() {
var pageWidth = $(window).width();
if(pageWidth > 700){
var contentLeft = $('#content-left');
var height = 210;
$(window).scroll(function () {
if ($(window).scrollTop() < height) {
contentLeft.attr('class', 'content-left');
} else {
contentLeft.attr('class', 'content-left leftContentFixed');
}
});
}
});
I try to apply this only on desktops.
Thus, I do not need the class leftContentFixed if it's on a smartphone or tablet.
If I try something like :
$(document).ready(function() {
var pageWidth = $(window).width();
if(pageWidth > 700){
alert("Bigger than 700");
}else{
alert("Smaller than 700");
}
});
Than it works perfect, but with my code it isn't working. The class leftContentFixed is added although the screen is smaller than 700.
Any advice?
You need to check screen size on resize event and check for its value when user scrolls the page. You could create mobile variable and make it true/false depends on screen size, then in scroll callback check for its value and choose correct class.
$(document).ready(function() {
var pageWidth = $(window).width(),
height = 210,
contentLeft = $('.content-left'),
mobile = false;
$(window).on('load resize', function() {
pageWidth = $(this).width();
// Save mobile status
if (pageWidth > 700) {
mobile = false;
} else {
mobile = true
}
})
$(window).on('scroll', function() {
if ($(window).scrollTop() > height) {
// Set default class
var _class = 'content-left leftContentFixed';
// If mobile then modify class
if (mobile) {
_class = 'content-left';
}
contentLeft.attr('class', _class);
} else {
var _class = 'content-left';
contentLeft.attr('class', _class);
}
});
});
html {
height: 2000px
}
.content-left {
background: gold;
width: 50px;
height: 100px;
}
.content-left.leftContentFixed {
position: fixed;
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="content-left"></div>
I have a script that changes the way my menu looks when you scroll past a certain point, to stop it repeating my animation over and over again I have put in a $(window).off("scroll"); so it only executes once. I need the menu to change back again when I scroll back past the same point again, but once I have turned off scroll, is there a way I can turn it back on at certain point?
This is what I have so far:
var Header = $('#header');
var Navbar = $('.navbar');
var links = $(".navbar ul.nav > li > a");
var HeaderH = Header.height();
var NavbarH = Navbar.height();
$(window).on("scroll", function(){
if ($(this).scrollTop() === (HeaderH + 64)) {
$(window).off("scroll");
Navbar.addClass('navbar-fixed-top')
links.css('padding', '10px 20px 10px 20px');
Header.css('margin-bottom', '64px');
$('.navbar-fixed-top').css('top', '-64px')
$('.navbar-fixed-top').animate({'top' : '0'}, 1000);
}
});
Just toggle a custom class :
var Header = $('#header');
var Navbar = $('.navbar');
var links = $(".navbar ul.nav > li > a");
var HeaderH = Header.height();
var NavbarH = Navbar.height();
$(window).on("scroll", function(){
if ($(this).scrollTop() >= (HeaderH + 64)) {
if (!Navbar.hasClass('myclass')) {
Navbar.addClass('navbar-fixed-top myclass')
$('.navbar-fixed-top').stop().animate({'top' : '0'}, 1000);
}
} else {
Navbar.removeClass('navbar-fixed-top myclass');
}
});
And CSS :
.myclass {
padding: 10px 20px;
margin-bottom: 64px;
top: -64px;
}
I'm trying to check when a div is reached from scrollbar with jquery.
I read some similar question on stackoverflow, but all are on one div only.
I have 4 div, with height: 100% and I want know when the scroll bar pass every div.
I tried, but only works with the first div.
HTML:
<body>
<div id="main"></div>
<div id="service"></div>
<div id="clients"></div>
<div id="about"></div>
</body>
CSS:
body, html {
height: 100%;
padding: 0px;
margin: 0px;
}
#main {
background: red;
height: 100%;
}
#service {
background: green;
height: 100%;
}
#clients {
background: blue;
height: 100%;
}
#about {
background: yellow;
height: 100%;
}
JS:
$(document).ready(function() {
var passed_service = false;
var passed_service = false;
$('body,html').bind('scroll mousedown wheel DOMMouseScroll mousewheel keyup', function(event){
if($(window).scrollTop() >= ($("#service").height())){
if(!passed_service){
alert("To #service");
passed_service = true;
}
}
if($(window).scrollTop() >= ($("#service").height() + $("#clients").height())){
if(!passed_clients){
alert("To #clients");
passed_clients = true;
}
}
});
});
SORRY TO ALL, WAS A MY STUPID ERROR, I CAN'T DELETE THE QUESTION :(
var passed_service = false;
var passed_service = false; /* should be 'passed_clients' */
^ There's your problem
Also, instead of adding up the divs' heights, use the top offset instead.
DEMO
$(window).scrollTop() >= $("#service").offset().top
$(window).scrollTop() >= $("#clients").offset().top
...
You never declare the passed_clients variable.
Change this:
var passed_service = false;
var passed_service = false;
to this:
var passed_service = false;
var passed_clients = false;
Working fiddle: http://jsfiddle.net/XUEfD/8/
Working Demo link
use this: (parseInt($("#service").height()) + parseInt($("#clients").height()))
$(document).ready(function() {
var passed_service = false;
var passed_clients = false;
$('body,html').bind('scroll mousedown wheel DOMMouseScroll mousewheel keyup', function(event){
if($(window).scrollTop() >= ($("#service").height())){
if(!passed_service){
alert("To #service");
passed_service = true;
}
}
//console.log($(window).scrollTop());
if($(window).scrollTop() >= (parseInt($("#service").height()) + parseInt($("#clients").height()))){
if(!passed_clients){
alert("To #clients");
passed_clients = true;
}
}
});
});
So basically I'd like to remove the class from 'header' after the user scrolls down a little and add another class to change it's look.
Trying to figure out the simplest way of doing this but I can't make it work.
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll <= 500) {
$(".clearheader").removeClass("clearHeader").addClass("darkHeader");
}
}
CSS
.clearHeader{
height: 200px;
background-color: rgba(107,107,107,0.66);
position: fixed;
top:200;
width: 100%;
}
.darkHeader { height: 100px; }
.wrapper {
height:2000px;
}
HTML
<header class="clearHeader"> </header>
<div class="wrapper"> </div>
I'm sure I'm doing something very elementary wrong.
$(window).scroll(function() {
var scroll = $(window).scrollTop();
//>=, not <=
if (scroll >= 500) {
//clearHeader, not clearheader - caps H
$(".clearHeader").addClass("darkHeader");
}
}); //missing );
Fiddle
Also, by removing the clearHeader class, you're removing the position:fixed; from the element as well as the ability of re-selecting it through the $(".clearHeader") selector. I'd suggest not removing that class and adding a new CSS class on top of it for styling purposes.
And if you want to "reset" the class addition when the users scrolls back up:
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 500) {
$(".clearHeader").addClass("darkHeader");
} else {
$(".clearHeader").removeClass("darkHeader");
}
});
Fiddle
edit: Here's version caching the header selector - better performance as it won't query the DOM every time you scroll and you can safely remove/add any class to the header element without losing the reference:
$(function() {
//caches a jQuery object containing the header element
var header = $(".clearHeader");
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 500) {
header.removeClass('clearHeader').addClass("darkHeader");
} else {
header.removeClass("darkHeader").addClass('clearHeader');
}
});
});
Fiddle
Pure javascript
Here's javascript-only example of handling classes during scrolling.
const navbar = document.getElementById('navbar')
// OnScroll event handler
const onScroll = () => {
// Get scroll value
const scroll = document.documentElement.scrollTop
// If scroll value is more than 0 - add class
if (scroll > 0) {
navbar.classList.add("scrolled");
} else {
navbar.classList.remove("scrolled")
}
}
// Use the function
window.addEventListener('scroll', onScroll)
#navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
width: 100%;
height: 60px;
background-color: #89d0f7;
box-shadow: 0px 5px 0px rgba(0, 0, 0, 0);
transition: box-shadow 500ms;
}
#navbar.scrolled {
box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.25);
}
#content {
height: 3000px;
margin-top: 60px;
}
<!-- Optional - lodash library, used for throttlin onScroll handler-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
<header id="navbar"></header>
<div id="content"></div>
Some improvements
You'd probably want to throttle handling scroll events, more so as handler logic gets more complex, in that case throttle from lodash lib comes in handy.
And if you're doing spa, keep in mind that you need to clear event listeners with removeEventListener once they're not needed (eg during onDestroy lifecycle hook of your component, like destroyed() for Vue, or maybe return function of useEffect hook for React).
Example throttling with lodash:
// Throttling onScroll handler at 100ms with lodash
const throttledOnScroll = _.throttle(onScroll, 100, {})
// Use
window.addEventListener('scroll', throttledOnScroll)
Add some transition effect to it if you like:
http://jsbin.com/boreme/17/edit?html,css,js
.clearHeader {
height:50px;
background:lightblue;
position:fixed;
top:0;
left:0;
width:100%;
-webkit-transition: background 2s; /* For Safari 3.1 to 6.0 */
transition: background 2s;
}
.clearHeader.darkHeader {
background:#000;
}
Its my code
jQuery(document).ready(function(e) {
var WindowHeight = jQuery(window).height();
var load_element = 0;
//position of element
var scroll_position = jQuery('.product-bottom').offset().top;
var screen_height = jQuery(window).height();
var activation_offset = 0;
var max_scroll_height = jQuery('body').height() + screen_height;
var scroll_activation_point = scroll_position - (screen_height * activation_offset);
jQuery(window).on('scroll', function(e) {
var y_scroll_pos = window.pageYOffset;
var element_in_view = y_scroll_pos > scroll_activation_point;
var has_reached_bottom_of_page = max_scroll_height <= y_scroll_pos && !element_in_view;
if (element_in_view || has_reached_bottom_of_page) {
jQuery('.product-bottom').addClass("change");
} else {
jQuery('.product-bottom').removeClass("change");
}
});
});
Its working Fine
Is this value intended? if (scroll <= 500) { ... This means it's happening from 0 to 500, and not 500 and greater. In the original post you said "after the user scrolls down a little"
In a similar case, I wanted to avoid always calling addClass or removeClass due to performance issues. I've split the scroll handler function into two individual functions, used according to the current state. I also added a debounce functionality according to this article: https://developers.google.com/web/fundamentals/performance/rendering/debounce-your-input-handlers
var $header = jQuery( ".clearHeader" );
var appScroll = appScrollForward;
var appScrollPosition = 0;
var scheduledAnimationFrame = false;
function appScrollReverse() {
scheduledAnimationFrame = false;
if ( appScrollPosition > 500 )
return;
$header.removeClass( "darkHeader" );
appScroll = appScrollForward;
}
function appScrollForward() {
scheduledAnimationFrame = false;
if ( appScrollPosition < 500 )
return;
$header.addClass( "darkHeader" );
appScroll = appScrollReverse;
}
function appScrollHandler() {
appScrollPosition = window.pageYOffset;
if ( scheduledAnimationFrame )
return;
scheduledAnimationFrame = true;
requestAnimationFrame( appScroll );
}
jQuery( window ).scroll( appScrollHandler );
Maybe someone finds this helpful.
For Android mobile $(window).scroll(function() and $(document).scroll(function() may or may not work. So instead use the following.
jQuery(document.body).scroll(function() {
var scroll = jQuery(document.body).scrollTop();
if (scroll >= 300) {
//alert();
header.addClass("sticky");
} else {
header.removeClass('sticky');
}
});
This code worked for me. Hope it will help you.
This is based of of #shahzad-yousuf's answer, but I only needed to compress a menu when the user scrolled down. I used the reference point of the top container rolling "off screen" to initiate the "squish"
<script type="text/javascript">
$(document).ready(function (e) {
//position of element
var scroll_position = $('div.mainContainer').offset().top;
var scroll_activation_point = scroll_position;
$(window).on('scroll', function (e) {
var y_scroll_pos = window.pageYOffset;
var element_in_view = scroll_activation_point < y_scroll_pos;
if (element_in_view) {
$('body').addClass("toolbar-compressed ");
$('div.toolbar').addClass("toolbar-compressed ");
} else {
$('body').removeClass("toolbar-compressed ");
$('div.toolbar').removeClass("toolbar-compressed ");
}
});
}); </script>