I have an element on my page that is toggled on and off by clicking on a text link. I also need the element to hide when a user clicks ANYWHERE on the page outside of the element itself - this is my jQuery code - can someone please show me what modifications to make to do what I need?
$(function() {
$("#header-translate ul li").click(function() {
$("#header-translate li ul").toggle("slide", { direction: "up" }, 500);
});
});
Using jQuery's one function is perfect for this.
$(function() {
$("#header-translate ul li").click(function(e) {
e.preventDefault();
var $toClose = $("#header-translate li ul")
$toClose.slideToggle(500, function() {
if($toClose.is(':visible')) {
$('body').one('click', function(e) {
e.preventDefault();
$toClose.slideUp(500);
});
}
else {
$('body').unbind('click');
}
});
});
});
What this will do is assure that this click handler will only get executed once, and only when the element is shown.
I believe you need to add a click() handler to the $('body'), and also event.stopPropagation() to your element.
$(function() {
$("#header-translate ul li").click(function(e) { // don't forget that 'e'
$("#header-translate li ul").toggle("slide", { direction: "up" }, 500);
e.stopPropagation(); // so this doesn't register as a body click
});
$("body").click(function(e) {
$("#header-translate").hide();
});
});
You'll want to check if
$(function()
{
var elToHideSelector = "#header-translate li ul";
$("body").click(function(e)
{
if ( ! $(e.target).is(elToHideSelector + ',' + elToHideSelector + ' *') )
{
$(elToHideSelector).hide();
}
});
});
I've used this code:
$(function() {
$("#header-translate ul li").click(function(e) {
$("#header-translate li ul").toggle("slide", { direction: "up" }, 500);
e.stopPropagation(); // so this doesn't register as a body click
});
$("body").click(function(e) {
if ($('#header-translate li ul').is(':visible')) { $("#header-translate li ul").hide("slide", { direction: "up" }, 500);}
});
});
Add a click handler to BODY tag that will slide the element up and add event.stopPropagation() to the element that opens the element in the first place so the click to open is not send to BODY.
You can add a listener to the document (since the event bubbles up, you can capture it in a parent element)
$(function() {
$("#header-translate ul li").click(function() {
$("#header-translate li ul").toggle("slide", { direction: "up" }, 500);
$(document).one('click', function(){
$("#header-translate li ul").hide();
});
});
});
Related
If you go to the JSFiddle, and click "About" and then "Contact" in rapid succession, the drop-down options (which appear to the right of the parents) appear appended to each other although only one parent is selected - this is not desired. I'm trying to only allow a new selection to be made once the appear/disappear animation has been completed, avoiding any appending of the children's content.
$(function() {
function animate(e) {
e.stopPropagation();
var $detected = $(this).closest('.nav-ul');
$detected.find('li.detected').removeClass('detected');
$(this).addClass('detected');
//figure out which rel to show
var ulToShow = $(this).attr('rel');
//hide current rel
if ($('.substitute .sub-child.active').length > 0) {
console.log("A");
$('.substitute .sub-child.active').hide(700, function() {
$(this).removeClass('active');
$('#' + ulToShow).fadeIn(528, function() {
$(this).addClass('active');
//$('#nav .nav-ul li').on('click', animate)
});
});
} else {
console.log("B");
$('#' + ulToShow).fadeIn(528, function() {
$(this).addClass('active');
//$('#nav .nav-ul li').on('click', animate)
});
}
}
$('#nav .nav-ul li').on('click', animate);
// close menu when clicking anywhere on the page
$(document).on("click", function() {
$("#nav li.detected").removeClass("detected");
$("#nav div.active").hide(700, function() { $(this).removeClass("active"); });
});
});
I tried adding this code after the opening of the function, but it only gave me the alert.
$('#nav .nav-ul li').click(function(){
var $this = $(this);
if(!$this.data('disabled')){
$this.data('disabled', true);
alert('next click enable only in 5 seconds');
setTimeout(function(){
$this.data('disabled', false);
}, 5000);
}
});
Have this code and tried to hide my side navbar when clicked outside the #nav, got this error.
Cannot read property 'addEventListener' of null
$( document ).ready( function() {
setTimeout(function(){
$('.menu-opener').click(function(){
$('#nav').toggleClass('active');
});
let slide = document.querySelector('#nav .active');
slide.addEventListener('click', function(e) {
if (e.target !== slide) return;
$('#nav').removeClass('active');
});
}, 1000);
});
answer is that you need to detect click outside of div you are trying to hide:
$(window).click(function() {
//Hide the menus if visible
});
//stopping above function from running when clicking on #nav itself
$('#nav').click(function(event){
event.stopPropagation();
});
Try this inside setTimeout
$('body').on('click','#nav .active', function(e){
// your logic
})
OR
$( "'#nav .active'" ).bind( "click", function(e) {
// your logic
});
instead of
let slide = document.querySelector('#nav .active');
slide.addEventListener('click', function(e) {
if (e.target !== slide) return;
$('#nav').removeClass('active');
});
Got this working with
$(document).click(function(event) {
if(!$(event.target).closest('#nav').length && !$(event.target).closest(".menu-opener").length)
{
$('#nav').removeClass('active');
}
});
My pjax is working fine, but I need to do different things on different pjax events. Here is my pjax:
//MainMenu
$(document).pjax('.menu li a', '.pjax_submenu', { fragment: '.pjax_submenu', timeout: 5000});
//SubMenu
$(document).pjax('.submenu li a', '.submenu', { fragment: '.submenu', timeout: 5000 });
Basicly I have these two menues and want to do stuff on pjax:start and pjax:end. Unfortunatly these events are always called. e.g.:
$("body").on("pjax_event", ".pjax_submenu", function(e, category){
$(document).on('pjax:start', function() {
if(category === 1){
$('.pjax_submenu').fadeOut(500);
} else{
$('.info').slideUp(500);
}
});
$(document).on('pjax:end', function() {
if(category === 1){
$('.pjax_submenu').hide().fadeIn(500);
} else{
$('.info').hide().slideDown(500);
}
});
});
$("body").on("click", ".menu li a", function() {
$(".pjax_submenu").trigger("pjax_event", 1);
});
$("body").on("click", ".submenu li a", function() {
$(".pjax_submenu").trigger("pjax_event", 2);
});
It doesn't matter if I click on a menu or a sub menu link, the result is the execution of all pjax code.
Even if I do it like this:
$("body").on("click", ".menu li a", function() {
$(document).on('pjax:start', function() { stuff }
$(document).on('pjax:end', function() { stuff }
});
$("body").on("click", ".submenu li a", function() {
$(document).on('pjax:start', function() { stuff }
$(document).on('pjax:end', function() { stuff }
});
It still executes >both< and I can't seem to get my head around a method to distinguish the pjax events on different clicked items.
What I want to do is fade content on a main menu point and use slideUp/Down for the sub menu info boxes.
Tell me if you need any additional information, every help is appreciated!
I wanted to share my solution, it's not too pretty - but it works marvelous! Also it's the only solution I found...
You will need the pjax version that's readable!
Search pjax.js for "pjax:end". Add the paragrpah below:
fire('pjax:end', [xhr, options])
if(options.menu == 'main'){
fire('pjax:main:end', [xhr, options])
}else if(options.menu == 'sub'){
fire('pjax:sub:end', [xhr, options])
}
same for pjax:start!
You can then declare your pjax links with:
//MainMenu
$(document).pjax('.menu li a', '.pjax_submenu', {menu: 'main',fragment:'.pjax_submenu', timeout: 5000});
//SubMenu
$(document).pjax('.submenu li a', '.submenu', { menu: 'sub',fragment: '.submenu', timeout: 5000 });
and voilà you have the separate events:
//... for Main Menu
$(document).on('pjax:main:start', function() {
console.log('pjax:main:start');
});
$(document).on('pjax:main:end', function() {
console.log('pjax:main:end');
});
//... for Sub Menu
$(document).on('pjax:sub:start', function() {
console.log('pjax:sub:start');
});
$(document).on('pjax:sub:end', function() {
console.log('pjax:sub:end');
$('.info') .slideDown(500);
});
Hope this helps someone in the future!
Cheers!
I want to add a marker character to a link when the user clicks it, and remove it when he clicks it a second time.
Here's what I have :
$('#text a').click(function () {
$(this).addClass('clicked');
$(this).text(markerTextChar + $(this).text());
$(this).click(function () {
$(this).removeClass('clicked');
$(this).text($(this).text().substring(1));
});
});
The marker is added on click, but it is added one more time when I click it to deselect it.
Can you help me fix that ?
Adding a event handler with bind (or click) doesn't remove the old ones.
You could unbind it but this is not needed. Do this instead :
$('#text a').click(function () {
if ($(this).hasClass('clicked')) {
$(this).removeClass('clicked');
$(this).text($(this).text().substring(1));
} else {
$(this).text(markerTextChar + $(this).text());
$(this).addClass('clicked');
}
});
demonstration
You might also use toggleClass and use :before in css to add your char, that would be much cleaner.
css :
.clicked:before {
content: "yourmarker";
}
javascript :
$('#text a').click(function () {
$(this).toggleClass('clicked');
});
demonstration
you have to unbind first click event do it like this
$('#text a').click(function () {
$(this).addClass('clicked');
$(this).text(markerTextChar + $(this).text());
$(this).removeAttr('onclick');
$(this).click(function () {
$(this).removeClass('clicked');
$(this).text($(this).text().substring(1));
});
});
My document click function isn't hiding my menu when I click the document outside of my menu. When I click the img it shows the menu and when I click the img again it hides it but when I document click I want it to hide the menu does any one know what I'm doing wrong and how to make it work.
var visible = false;
var id = $(this).attr('id');
$(document).not('#' + id + ' div:eq(1)').click(function () {
if (visible) {
$('.dropdownlist .menu').hide();
visible = false;
}
});
$(this).find('div:eq(1)').click(function (e) {
var menu = $(this).parent().find('.menu');
if (!visible) {
menu.show();
visible = true;
} else if (visible) {
menu.hide();
visible = false;
}
menu.css({ 'left': $(this).position().left + $(this).width() - menu.find('ul').width(),
'top': $(this).position().top + $(this).height() });
})
I had a similar problem and solved it with the following code:
$("body").mouseup(function(){
if (visible) {
$('.dropdownlist .menu').hide();
visible = false;
}
});
instead of your $(document).not(.. code.
//add event.stopPropagation() when the user clicks on a .menu element
$('.menu').on('click', function (event) {
//.stopPropagation() will stop the event from bubbling up to the document
event.stopPropagation();
});
//add the click event handler to the image that will open/close .menu elements
$('img').on('click', function (event) {
//we call .stopPropagation() again here so the document won't receive this event
event.stopPropagation();
//cache .menu element
var $div = $('.menu');
//this if statement determines if the .menu should be shown or hidden, in my example I'm animating its top property
if ($div.css('top') == '-50px') {
$div.stop().animate({top : 0}, 250);
} else {
$div.stop().animate({top : '-50px'}, 150);
}
});
//add click event handler to the document to close the .menu
$(document).on('click', function () {
$('div').stop().animate({top : '-50px'}, 150);
});
jsfiddle: http://jsfiddle.net/jasper/n5C9w/1/