I am developing a responsive website. There are two functions: nested functions are used in both, handling event $(document).click(). Both hide the same elements — .dropdown.slide-out. However, in the first case, the function refers to the selector .dropdown, and in the second case to the selector .slide-out. The first works only: where am I going wrong?
/*
|---------------------------------------
| Dropdowns
|---------------------------------------
*/
$(function () {
var label = $('.dropdown-toggle');
var allDropDowns = $('.dropdown-menu, .rmb-popup');
var el = $(this);
label.click(function () {
if (Modernizr.mq('only screen and (min-width: 768px)')) {
allDropDowns.hide();
$(this).parents('.dropdown').children('.dropdown-menu').toggle('fast');
label.removeClass('active');
$(this).addClass('active');
return false
}
});
// Conflict point #1. Hide .dropdown.slide-out-right
$(document).click(function () {
allDropDowns.hide();
label.removeClass('active');
});
allDropDowns.click(function (event) {
event.stopPropagation();
});
});
/*
|---------------------------------------
| Slide-outs
|---------------------------------------
*/
$(function () {
var soRight = $('.slide-out-right');
$('.btn-menu-secd').click(function () {
if (Modernizr.mq('only screen and (max-width: 767px)')) {
soRight.animate({
right: 0
}, 400)
}
return false
});
// Conflict point #2. Slide out .dropdown.slide-out-right
$(document).click(function () {
if (Modernizr.mq('only screen and (max-width: 767px)')) {
if (soRight.attr('style')) {
soRight.animate({
right: '-270px'
}, 400, function () {
soRight.removeAttr('style')
})
}
}
});
soRight.click(function (event) {
event.stopPropagation();
});
});
UPD: I was wrong. JQuery starts from 1.7 let to attach more than one or more handlers on 1 event. It will execute it in order of binding Documentation
FIDDLE
1:
$(function(){
var allDropDowns = $('.dropdown-menu');
$('.dropdown-toggle').click(function() {
allDropDowns.show();
return false;
});
$(document).click(function() {
allDropDowns.hide();
});
$('.dropdown-menu').click(function(e) {
e.stopPropagation();
e.preventDefault();
});
});
2:
$(function() {
var slideOut = $('.slideout');
$('.btn-menu').click(function() {
slideOut.show();
return false;
});
$(document).click(function() {
slideOut.hide();
});
$('.slideout').click(function(e) {
e.stopPropagation();
e.preventDefault();
});
});
Related
I attach the link of my code here. in this, the slider animates correctly when clicking on the corner but I need is that working on the scroll.
$(document).ready(function () {
$('.corner').click(function() {
var $parent = $(this).parent();
$parent.removeClass("active");
if ($parent.next().length){
$parent.next().addClass("active");
} else {
$parent.prevAll().last().addClass("active");
}
});
});
https://jsfiddle.net/freer4/cqqxjjgu/1/
Try out this:
$('.corner').bind('mousewheel',function() {
alert(1);
var $parent = $(this).parent();
$parent.removeClass("active");
if ($parent.next().length){
$parent.next().addClass("active");
} else {
$parent.prevAll().last().addClass("active");
}
});
On the site I'm working on, there's a bar that appears:
1. When the user hovers over a link
$("#navbar-nav-list-element-left").hover(function() {
$('.bar-left').toggleClass('bar-active');
});
$("#navbar-nav-list-element-middle").hover(function() {
$('.bar-middle').toggleClass('bar-active');
});
$("#navbar-nav-list-element-right").hover(function() {
$('.bar-right').toggleClass('bar-active');
});
2. When the user is visiting that link's particular content
$(function(){
if (/(about.html)/.test(window.location.href)) {
$('.bar-middle').addClass('bar-active-scroll');
} else {
$('.bar-middle').removeClass('bar-active-scroll');
}
});
$(function(){
if (/(work.html)/.test(window.location.href)) {
$('.bar-left').addClass('bar-active-scroll');
} else {
$('.bar-left').removeClass('bar-active-scroll');
}
});
$(function(){
if (/(contact.html)/.test(window.location.href)) {
$('.bar-right').addClass('bar-active-scroll');
} else {
$('.bar-right').removeClass('bar-active-scroll');
}
});
3. When the user scrolls down to a specific point on the homepage
$(function(){
var stickyTop = $('#section2').offset().top;
$(window).on( 'scroll', function(){
if ($(window).scrollTop() >= stickyTop) {
$('.bar-left').addClass('bar-active-scroll');
} else {
$('.bar-left').removeClass('bar-active-scroll');
}
});
});
My site is a single page application & I'm using barba.js to handle AJAX. Taking that into consideration:
These functions run every time the DOM is loaded/refreshed (via .js file included in 'scripts' at bottom of the index page (and only there, since other 'pages' are added via AJAX))
$(function(){
var stickyTop = $('#section2').offset().top;
$(window).on( 'scroll', function(){
if ($(window).scrollTop() >= stickyTop) {
$('.bar-left').addClass('bar-active-scroll');
} else {
$('.bar-left').removeClass('bar-active-scroll');
}
});
});
$("#navbar-nav-list-element-left").hover(function() {
$('.bar-left').toggleClass('bar-active');
});
$("#navbar-nav-list-element-middle").hover(function() {
$('.bar-middle').toggleClass('bar-active');
});
$("#navbar-nav-list-element-right").hover(function() {
$('.bar-right').toggleClass('bar-active');
});
...and these functions run every time barba.js updates content
$(function(){
if (/(about.html)/.test(window.location.href)) {
$('.bar-middle').addClass('bar-active-scroll');
} else {
$('.bar-middle').removeClass('bar-active-scroll');
}
});
$(function(){
if (/(work.html)/.test(window.location.href)) {
$('.bar-left').addClass('bar-active-scroll');
} else {
$('.bar-left').removeClass('bar-active-scroll');
}
});
$(function(){
if (/(contact.html)/.test(window.location.href)) {
$('.bar-right').addClass('bar-active-scroll');
} else {
$('.bar-right').removeClass('bar-active-scroll');
}
});
$(function(){
var stickyTop = $('#section2').offset().top;
$(window).on( 'scroll', function(){
if ($(window).scrollTop() >= stickyTop) {
$('.bar-left').addClass('bar-active-scroll');
} else {
$('.bar-left').removeClass('bar-active-scroll');
}
});
});
My Problem: If I navigate to another page (triggering barba.js) and return to my homepage, then scroll until I trigger the bar, the bar remains active after I scroll back to the top.
I'm pretty sure I need to use '.off' on .bar-left, .bar-middle & .bar-right when pages refresh, but I'm unsure how to implement this correctly.
Any advice/constructive criticism/suggestions are much appreciated!
Here's the full block of code that runs when barba.js is triggered
document.addEventListener("DOMContentLoaded", function() {
if (!('webkitClipPath' in document.body.style)) {
alert('Sorry, this demo is available just with webkitClipPath. Try with
Chrome/Safari.');
}
Barba.Pjax.init();
Barba.Prefetch.init();
var FadeTransition = Barba.BaseTransition.extend({
start: function() {
/**
* This function is automatically called as soon the Transition starts
* this.newContainerLoading is a Promise for the loading of the new
container
* (Barba.js also comes with an handy Promise polyfill!)
*/
// As soon the loading is finished and the old page is faded out, let's
fade the new page
Promise
.all([this.newContainerLoading, this.fadeOut()])
.then(this.fadeIn.bind(this));
},
fadeOut: function() {
/**
* this.oldContainer is the HTMLElement of the old Container
*/
return $(this.oldContainer).animate({ opacity: 0 }).promise();
},
fadeIn: function() {
/**
* this.newContainer is the HTMLElement of the new Container
* At this stage newContainer is on the DOM (inside our #barba-
container and with visibility: hidden)
* Please note, newContainer is available just after
newContainerLoading is resolved!
*/
document.body.scrollTop = 0;
var _this = this;
var $el = $(this.newContainer);
$(this.oldContainer).hide();
$el.css({
visibility : 'visible',
opacity : 0
});
initFullpagePlugin($el);
$(function(){
if (/(about.html)/.test(window.location.href)) {
$('.bar-middle').addClass('bar-active-scroll');
} else {
$('.bar-middle').removeClass('bar-active-scroll');
}
});
$(function(){
if (/(work.html)/.test(window.location.href)) {
$('.bar-left').addClass('bar-active-scroll');
} else {
$('.bar-left').removeClass('bar-active-scroll');
}
});
$(function(){
if (/(contact.html)/.test(window.location.href)) {
$('.bar-right').addClass('bar-active-scroll');
} else {
$('.bar-right').removeClass('bar-active-scroll');
}
});
$(function(){
var stickyTop = $('#section2').offset().top;
$(window).on( 'scroll', function(){
if ($(window).scrollTop() >= stickyTop) {
$('.bar-left').addClass('bar-active-scroll');
} else {
$('.bar-left').removeClass('bar-active-scroll');
}
});
});
$el.animate({ opacity: 1 }, 400, function() {
/**
* Do not forget to call .done() as soon your transition is finished!
* .done() will automatically remove from the DOM the old Container
*/
_this.done();
});
}
});
http://codepen.io/oliecs/pen/womLPJ
var nav = {
init: function () {
console.log('nav init');
$nav = $('nav');
$navIcon = $('.nav-icon');
$navIcon.on('click',function(){
nav.show();
})
},
show: function () {
console.log('nav show');
$nav.addClass('active');
$_DOCUMENT.on('click.navisopen',function(){ //document is a global variable
nav.close();
})
},
close: function () {
console.log('nav close');
$nav.removeClass('active');
$_DOCUMENT.off('.navisopen');
}
};
I feel the pen describes this better than I can. I want to click the nav-icon to open the nav, then any clicks after this will close the nav. However, the close event is fired instantly after the first click, resulting in the nav opening and closing instantly. I don't know how to make this sequential.
Updated js file..Use this code
var ecs= {};
ecs.common = (function($) {
var $_DOCUMENT = $(document),
$_WINDOW = $(window),
$nav = $('nav'),
$navIcon = $('.nav-icon');
var nav = {
init: function () {
console.log('nav init');
$nav = $('nav');
$navIcon = $('.nav-icon');
$navIcon.on('click',function(){
nav.show();
})
},
show: function () {
console.log('nav show');
$nav.addClass('active');
// $_DOCUMENT.on('click.navisopen',function(){
// nav.close();
// })
},
close: function () {
console.log('nav close');
$nav.removeClass('active');
$_DOCUMENT.off('.navisopen');
}
};
//--------------------
// DOM Ready
//--------------------
$(function() {
nav.init();
});
$(document).mouseup(function (e) {
var container = $(".nav-icon");
if (!container.is(e.target) && container.has(e.target).length === 0) {
/* if the target of the click isn't the container && nor a descendant of the container */
$nav.removeClass('active');
}
});
})(jQuery);
You need to
$navIcon.on('click',function(event){
event.stopPropagation();
nav.show();
})
Because the first click is bubbling up the DOM all the way to the document where that event handler is triggered.
It is possible to change variable inside function which is based on element is user clicks?
In my case this will fully work for one kind of menu but I need two fully identical menu
with one difference -
second click handler must load toggleDrawer with changed $sidebar to $navbar variable.
/*
Variables
*/
var $sidebar = $('#sidebar'),
$navbar = $('#navbar'),
drawerOpen = false,
/*
Functions
*/
closeDrawer = function() {
drawerOpen = false;
$body.css('overflow','').removeClass('sidebar-open');
$sidebar.removeClass('open');
$sidebar.animate({'right':'-50%'},{duration:300});
$(this).hide();
},
openDrawer = function() {
drawerOpen = true;
$body.addClass('sidebar-open').css('overflow','hidden');
$sidebar.addClass('open');
$sidebar.animate({'right':'0%'},{duration:300});
},
toggleDrawer = function() {
if (drawerOpen) {
closeDrawer();
}else{
openDrawer();
}
},
/*
Bind Events
*/
$document.on('click', '.drawer-toggle-sidebar', function(event){
toggleDrawer();
event.preventDefault();
});
$document.on('click', '.drawer-toggle-navbar', function(event){
toggleDrawer();
event.preventDefault();
});
To elaborate on the above comment, and show an example:
Here are your functions with passing in the element you wish to open/close:
/*
Functions
*/
closeDrawer = function(drawer) {
drawerOpen = false;
$body.css('overflow','').removeClass('sidebar-open');
drawer.removeClass('open');
drawer.animate({'right':'-50%'},{duration:300});
$(this).hide();
},
openDrawer = function(drawer) {
drawerOpen = true;
$body.addClass('sidebar-open').css('overflow','hidden');
drawer.addClass('open');
drawer.animate({'right':'0%'},{duration:300});
},
toggleDrawer = function(drawer) {
if (drawerOpen) {
closeDrawer(drawer);
}else{
openDrawer(drawer);
}
},
And your bind events:
/*
Bind Events
*/
$document.on('click', '.drawer-toggle-sidebar', function(event){
toggleDrawer(event.currentTarget);
event.preventDefault();
});
$document.on('click', '.drawer-toggle-navbar', function(event){
toggleDrawer(event.currentTarget);
event.preventDefault();
});
You could even combine the two on click events into one and just pass in the currentTarget.
I hope this helps.
A bit of JQuery taken from http://briancray.com/2009/05/06/twitter-style-alert-jquery-cs-php/ which should give a nice old-twitter style notification.
How do I edit the code below to stop the div hiding on a mouseover?
UPDATE: I still want the div to slideup after the mouseover has finished.
$(function () {
var $alert = $('#alert');
if($alert.length) {
var alerttimer = window.setTimeout(function () {
$alert.trigger('click');
}, 5000);
$alert.animate({height: $alert.css('line-height') || '50px'}, 200).click(function () {
window.clearTimeout(alerttimer);
$alert.animate({height: '0'}, 200);
});
}
});
If I'm understanding correctly (which I'm probably not), you want something like this:
var alerttimer, alertBox = $('#alert');
function resetTimeout() {
if (alerttimer) {
clearTimeout(alerttimer);
}
alerttimer = setTimeout(function() {
alertBox.trigger('click');
}, 5000);
}
$(function () {
if(alertBox.length) {
resetTimeout();
alertBox.animate({ height: alertBox.css('line-height') || '50px' }, 200).click(function () {
window.clearTimeout(alerttimer);
alertBox.animate({ height: '0px' }, 200);
}).mouseover(function () {
clearTimeout(alerttimer);
}).mouseout(function () {
resetTimeout();
});
}
});
It's important to note that the above is very much untested.