I'm new to JavaScript, I wonder, how can I make this:
I have menu item, then you click on it, info box pops up, there's X in corner, you close it and that's it. But my goal is not only on click show it, but even then you hover it. Here's script, if you need CSS let me know.
$('#help').appendTo('.navbar-container .level1');
$('#help a').click(function(e) {
e.preventDefault();
if($('#help').hasClass('active')) {
$('#help').removeClass('active');
} else {
$('#help').addClass('active');
}
$('#help-block').toggle();
});
$('#help-block .help-close').click(function(e) {
e.preventDefault();
$('#help-block').css('display','none');
$('#help').removeClass('active');
});
Thanks, people! Happy new year.
Multiple events can be bound to one .on() method, e.g:
$('#help a').on('click hover', function(e) {
// continue
});
Description: Attach an event handler function for one or more events to the selected elements.
Ref: .on() | jQuery API Documentation
Consider using this method instead.
Use .on() and mouseover like this:
$('#help').appendTo('.navbar-container .level1');
$('#help a').on("click mouseover",function(e) {
e.preventDefault();
if($('#help').hasClass('active')) {
$('#help').removeClass('active');
} else {
$('#help').addClass('active');
}
$('#help-block').toggle();
});
$('#help-block .help-close').on("click mouseover",function(e) {
e.preventDefault();
$('#help-block').css('display','none');
$('#help').removeClass('active');
});
Related
I am trying to develop some code to allow the user show/hide a block level element by clicking a button.
The HTML structure is like below
<div class="chat_container"><a class="crm" href="https://google.com" target="_blank">Chat?</a><button id="close_chat"><</button></div>
I have written a click() function for #close_chat which amongst other things changes the ID of the button to #open_chat. I then use the on() method on #open_chat to modify some classes and ids on various elements. In isolation both these methods work, however when combined they don't work. I have noticed that when I click #close_chat even though the ID changes to #open_chat the original event is still attached to the button. After doing some search I suspected the issue might have been related to events bubbling up, but now I am not so sure, still I added event.stopPopagation() to my click function and I can see it appears to be called correctly. I have also tried using the one() method, this appeared to get closer to the behavior I was expecting at the DOM level but still didn't working
My expected behavior is the click() function is called when the user clicks #close_chat, the event is then unbound allowing the .on() event to be called on #open_chat. Id than of course have to reset the original functionality. My code looks like this
$(document).ready(function () {
var close = "<button id='close_chat'><</div>";
var container = $("<div />");
container.addClass("chat_container");
var crmChat = $("<a />");
crmChat.addClass("crm");
crmChat.attr("href", "https://google.com");
crmChat.attr("target", "_blank");
crmChat.text("Chat?");
console.log(crmChat);
console.log(container);
$(container).insertAfter("#heading");
$(container).prepend(crmChat);
$(close).insertAfter(crmChat);
$("#close_chat").click(function (event) {
$("#close_chat").removeAttr("id").attr("id", "open_chat");
event.stopPropagation();
alert(event.isPropagationStopped());
//return false;
});
$(".chat_container").on("#open_chat", "button", function () {
//$(".crm_chat_container").addClass("animate-open").removeClass("animate-close");
$("#open_chat").html(">").removeAttr("id").attr("id", "reopen");
//event.stopPropagation();
});
});
any help is greatly appreciated
Sam
edit, I have now updated my code to look like so
//onclick function for our close button
$("#close_chat").click(function (event) {
attachClosedChatListner();
});
function attachOpendChatListener() {
$(".chat_container").on("click","#open_chat", function () {
$("#open_chat").removeAttr("id").attr("id", "close_chat");
$("#close_chat").html("<")
$(".crm_chat_container").removeClass("animate-close").addClass("animate-open");
});
//attachClosedChatListner();
}
function attachClosedChatListner() {
$("#close_chat").off('click');
$("#close_chat").removeAttr("id").attr("id", "open_chat");
$("#open_chat").html(">")
$(".chat_container").removeClass("animate-open").addClass("animate-close");
//attachOpendChatListener();
}
What about re-attaching the event?
$("#close_chat").click(function (event) {
$("#close_chat").removeAttr("id").attr("id", "open_chat");
attachOpenChatListener();
event.stopPropagation();
alert(event.isPropagationStopped());
//return false;
});
function attachOpenChatListener() {
$("#close_chat").off('click');
$(".chat_container").on("#open_chat", "button", function () {
//$(".crm_chat_container").addClass("animate-open").removeClass("animate-close");
$("#open_chat").html(">").removeAttr("id").attr("id", "reopen");
//event.stopPropagation();
});
}
I managed to work this out, the click function was causing the problem
//onclick function for our close button
$("#close_chat").click(function (event) {
attachClosedChatListner();
});
I've replaced it with .on and it works now
$(".crm_chat_container").on("click", "#close_chat", function (event) {
$("#close_chat").off('click');
$("#close_chat").removeAttr("id").attr("id", "open_chat");
$("#open_chat").html(">");
$(".crm_chat_container").removeClass("primo-animate-open").addClass("animate- close");
attachCloseChatListener();
event.stopImmediatePropagation();
});
function attachCloseChatListener() {
$(".crm_chat_container").on("click", "#open_chat", function (event) {
$("#open_chat").off('click');
$(".crm_chat_container").removeClass("primo-animate-close").addClass("primo-animate-open");
$("#open_chat").removeAttr("id").attr("id", "close_chat");
$("#close_chat").html("<");
event.stopImmediatePropagation();
});
}
on thing is my click events appears to be firing multiple times, that is after clicking my buttons a few times I see several click events in dev tools.
Anyway, thanks for putting me on the right path
$("#button1").click(function(e)
{
//action
});
$("#button2").click(function(e)
{
//do something
$("#button1").click(function(f)
{
//do something else
});
});
I have two buttons doing different actions.but if button 2 is clicked,i need button 1 to do a different task on the next click without the first function being executed.
any suggestions?
For that ,you need to use one variable scope for detect whether button 1 or 2 is click
var btn = 1; // default
$("#button1").click(function(e)
{
if(btn){
#button1 click
}
else{
#after button2 click
}
});
$("#button2").click(function(e)
{
btn = 2; //change value after button2 click
});
I suggest you look into jQuery's .on() and .off() capabilities.
http://api.jquery.com/on/
http://api.jquery.com/off/
As it says in the 'off' link above, you can create namespaces for your click events, so you can add and remove just the particular on and off events you like. Something like this:
$("#button1").on("click.myName", function(e){
//action
});
$("#button2").click(function(e){
//do something
$("#button1").off("click.myName").on("click.myOtherName", function(e) {
//do something else
});
});
This allows you to target your click events more directly, and not call .off() generically, wiping out all click events.
One method you could use is by unbinding any event listener before adding a new event listener to the button you want to change.
This can be done with the on() and off() functions in Jquery.
$("#button1").off('click').on('click',function(e)
{
//action
});
You can then do the same thing with button 2...
$("#button2").off('click').on('click',function(e)
{
//action
$("#button1").off('click').on('click',function(e)
{
//action
});
});
By doing this, the last on click that you set is the only one that will occur when you click that element.
You may try this once
$("#button1").click(function(e)
{
//action
});
$("#button2").click(function(e)
{
//do something
$("#button1").unbind();
$("#button1").bind('click', function(f)
{
//do something else
});
});
I hope this would work for you.
$('#clickableElement').bind({
mousedown: function(e)
{
console.log('mousedown on element');
$(document).bind('mouseup',function(e){
console.log('mouseup caught');
//Do some magic here
$(this).unbind('mouseup');
});
},
mouseup:function(e)
{
//mouseup within element, no use here.
}
});
I'm trying to catch the mouseup event from a mousedown that's released inside or outside of an element. This code almost works, but the problem is the unbind('mouseup') which is unbinding other scripts attached to the mouseup event (jqueryui). If unbind() is not set then the code gets stacked within mouseup event and called x number of times, where x is the times you've mousedowned.
Route 1: is there some kind of self destructing function that calls itself once and destroys?
Route 2: any way to copy/clone the mouseup function prior to inserting the code, then unbind, then set as previous?
Ideally I'd like to keep this code structure for neatness as I have lots of clickable elements, so binding the document.mouseup outside of element.mousedown would be messy.
Here's the Fiddle I forgot to add http://jsfiddle.net/9gFNk/
Can giv your click event a namespace so only that namespaced event gets unbound, and not any others
$(document).on('mouseup.clickableElement',function(e){
console.log('mouseup caught');
//Do some magic here
$(this).off('mouseup.clickableElement');
});
I created a global object to catch mouse events from the document. It's currently set for mouseup only but can be easily expanded for others. The mouseup code is still customizable within the mousedown functions of the clickable elements so it this handy if you have lots of clickable things like I do.
var MouseCatcher=function()
{
this.init=function()
{
var mc = this;
$(document).bind({
mouseup:function(e)
{
mc.mouseup();
}
});
}
this.mouseup=function()
{
return false;
}
}
var mouseCatcher = new MouseCatcher();
mouseCatcher.init();
$('#clickableElement').bind({
mousedown: function(e)
{
console.log('mousedown on element');
mouseCatcher.mouseup=function()
{
console.log('mouseup called from MouseCatcher');
this.mouseup = function(){return false;}
}
},
mouseup:function(e)
{
//mouseup within element, no use here.
}
});
With "on" event its possible, its may not be an exact solution. Please refer this code
$(document).on('mousedown', function() {
$('#clickableElement').css('display', 'none');
$(document).bind('mouseup', function() {
$('#clickableElement').css('display', 'block');
});
});
http://jsfiddle.net/9gFNk/13/
I am creating a dynamic quiz and I need to prevent multiple clicks on my 'next' button. In the click function I tried to an if condition to prevent multiple clicks. Not sure why it doesn't work. Would greatly appreciate some help.
var nextButton= $('<button/>', {
text: 'Next',
id: 'nextButton',
click: function (event) {
event.preventDefault();
if($("#container").filter(':animated').length>0) {
return false;
}
/* rest of code*/
}
});
Here is the code as it appears my JSFiddle of my application
Bonus Question: I was told event.preventDefault() is good practice. Is this true? If so, why?
Update: The JSFiddle line # where the code above is line 81 in case you want to mess around with the code without digging through it all.
var nextButton= $('<button/>', {
text: 'Next',
id: 'nextButton',
click: function (event) {
event.preventDefault();
if($("#insideContainer").filter(':animated').length>0) {
return false;
}
/* rest of code*/
}
});
I found out why. You're checking against the wrong element. It should be #insideContainer
Demo
Try like this
$("#id or .class").one("click",function(){
// your activity
});
Description:
The one() method attaches one or more event handlers for the selected elements, and specifies a function to run when the event occurs.
When using the one() method, the event handler function is only run ONCE for each element.
One way to do this to use timeStamp property of event like this to gap some time between multiple clicks:
var a = $("a"),
stopClick = 0;
a.on("click", function(e) {
if(e.timeStamp - stopClick > 300) { // give 300ms gap between clicks
// logic here
stopClick = e.timeStamp; // new timestamp given
}
});
Try to use event.stopImmediatePropagation() to prevent multiple clicks.
Desc: Keeps the rest of the handlers from being executed and prevents the event from bubbling up the DOM tree.
I have the following function to open an overlay menu:
$('.context-switch').click(function() {
$(".context-switch-menu").toggle();
});
To hide the menu, I would like the user to be able to click on any area outside ".context-switch-menu"
I am trying with :not() but with no success..
$('body').click(function(e) {
if ($(e.target).hasClass('context-switch')) {
return;
}
$(".context-switch-menu").hide();
});
$('.context-switch').click(function() {
$(".context-switch-menu").toggle();
return false;
});
The reason this can be difficult is because of event bubbling.
You can try something like this:
$('.context-switch').click(function(e) {
e.stopPropagation();
$(".context-switch-menu").toggle();
});
$(".context-switch-menu").click(function(e){
e.stopPropagation();
});
$("body").click(function(e){
$(".context-switch-menu").hide();
});
The e.stopPropagation() prevents the click event from bubbling to the body handlers. Without it, any click to .context-switch or .context-switch-menu would also trigger the body event handler, which you don't want, as it would nullify the effect of the .context-switch click half the time. (ie, if the state is hidden, and then you click to show, the event would bubble and trigger the body handler that would then hide the .context-switch-menu again.)
Without testing, would something like this work?:
$('.context-switch').click(function() {
$(".context-switch-menu").show();
});
$(document).click(function() {
$(".context-switch-menu").hide();
});
Instead of using document, 'html' or 'body' may work as well.
$(document).on('click', function(e) {
if (e.target.className !='context-switch-menu') {
$(".context-switch-menu").hide();
}
});
Just an idea here, based on what what others have suggested in the past:
$(document).click(function(e){
//this should give you the clicked element's id attribute
var elem = $(e.target).attr('classname');
if(elem !== 'context-switch-menu'){
$('.context-switch-menu').slideUp('slow');
//or however you want to hide it
}
});
try this, we don't want to call a function when you clicked on the element itself, and not when we click inside the element. That's why we need 2 checks.
You want to use e.target which is the element you clicked.
$("html").click(function(e){
if( !$(e.target).is(".context-switch-menu") &&
$(e.target).closest(".context-switch-menu").length == 0
)
{
alert("CLICKED OUTSIDE");
}
});
Live fiddle: http://jsfiddle.net/Xc25K/1/