I'm building a login/join form which involves entering one field at a time (within a modal style box), which is quickly replaced by another field.
This all works perfectly until I add my code for clicking outside the modal box, as shown below
$(document).ready(function(){
$("#loginJoinBackground").click(function(){
$("#loginJoinBackground").fadeOut(300,function(){});
});
$("#logins-box").click(function(){
event.stopPropagation();
});
});
Now, that also works fine for what it is supposed to to.
The problem is that when I have that code in, it stops the other functions from firing. Is there something obvious that I am missing?
Edit: I am using meteor so perhaps that might be affecting things differently, the code that fails to fire as a result of the above is below:
$(document).on("click", "#loginB", function(){
logMeIn($("#logU").val(), "");
})
function logMeIn(emailVar, passwordVar = ""){
Meteor.loginWithPassword(emailVar, passwordVar, function(err){
console.log(err.reason);
if(err.reason == "Incorrect password"){
event.preventDefault();
$("#spanEmailLogin").hide("slide", { direction: "left" }, 200);
$("#spanPasswordLogin").show("slide", { direction: "right" }, 200);
$("#logP").focus();
}
else{
event.preventDefault();
$("#spanEmailLogin").hide("slide", { direction: "left" }, 200);
$("#spanPasswordLoginForm").show("slide", { direction: "right" }, 200);
$("#passwordForm").focus();
}
});
}
No need jquery for click event. You should use Template.events
Try this and let me know:
Template.youTemplate.events({
'click #loginB': function (e,t) {
var emailVar = t.find('#logU').value
var passwordVar = t.find('#logP').value
Meteor.loginWithPassword(emailVar, passwordVar, function(err){
console.log(err.reason);
if(err.reason == "Incorrect password"){
e.preventDefault();
$("#spanEmailLogin").hide("slide", { direction: "left" }, 200);
$("#spanPasswordLogin").show("slide", { direction: "right" }, 200);
$("#logP").focus();
} else{
e.preventDefault();
$("#spanEmailLogin").hide("slide", { direction: "left" }, 200);
$("#spanPasswordLoginForm").show("slide", { direction: "right" }, 200);
$("#passwordForm").focus();
}
});
}
});
Did you try to call the preventDefault() method instead of stopPropagation() ?
$(document).ready(function(){
$("#loginJoinBackground").click(function(){
$("#loginJoinBackground").fadeOut(300,function(){});
});
$("#logins-box").click(function(e){
e.preventDefault()
//event.stopPropagation();
});
});
$(document).ready(function(){
$("#loginJoinBackground").click(function(){
$("#loginJoinBackground").fadeOut(300,function(){}); });
$("#logins-box").click(function(event){
event.stopPropagation();
});
});
this may work im not sure
Related
As it is possible to define multiple event handlers in one single function in jQuery like this:
$(document).on({
'event1': function() {
//do stuff on event1
},
'event2': function() {
//do stuff on event2
},
'event3': function() {
//do stuff on event3
},
//...
});
Then again we can do this:
$(document).on('click', '.clickedElement', function() {
//do stuff when $('.clickedElement') is clicked
});
I was wondering if it is also possible to do something like this (the following code does not work, it's just for illustration):
$(document).on('click', {
'.clickedElement1', function() {
//do stuff when $('.clickedElement1') is clicked
},
'.clickedElement2', function() {
//do stuff when $('.clickedElement2') is clicked
},
//... and so on
});
This code gives me an error complaining about the "," after '.clickedElementX'. I also tried it like this:
$(document).on('click', {
'.clickedElement1': function() {
//do stuff when $('.clickedElement1') is clicked
},
//... and so on
});
Then I don't have the error but also the function is not executed. Is there a way to collect all the click handlers in one place like this or would I have to always do it like this:
$(document).on('click', '.clickedElement1', function() {
//do stuff when $('.clickedElement1') is clicked
});
$(document).on('click', '.clickedElement2', function() {
//do stuff when $('.clickedElement2') is clicked
});
//... and so on
You can chain :
$(document).on({
click: function() {
//click on #test1
},
blur: function() {
//blur for #test1
}
}, '#test1').on({
click: function() {
//click for #test2
}
}, '#test2');
FIDDLE
Short answer: no, you have to bind them all separately.
Long answer: You can create an "infrastructure" for your site and have all events in one place. e.g.
var App = function(){
// business logic
return {
Settings: { ... },
Events: {
'event1': function(){
},
'event2': function(){
},
'event3': function(){
}
}
}
}();
Then wiring it up involves:
$(document).on(App.Events);
Then internally you can add then new bindings to your App object but still remains wired up in only one place (as far as jQuery is concerned). You could then make some kind of subscriber model within App (e.g. App.Subscribe('click', function(){ ... })) and each new subscription still is only wired through the single .on() binding.
but, IMHO, this is a lot of overhead with very little pay-off.
$(document).on('click' , function(e){
if($(e.target).hasClass("some-class")){
//do stuff when .some-class is clicked
}
if($(e.target).hasClass("some-other-class")){
//do stuff when .some-other-class is clicked
}
});
you can choose any some-class you want
It can be easily done, really:
$(document).ready(function()
{
$(this).on('click', '.one, .two',function()
{
if ($(this).hasClass('one'))
{//code for handler on .one selector
console.log('one');
}
else
{//code for handler on .two selector
console.log('two');
}
console.log(this);//code for both
});
});
If multiple events is what you're after:
$(document).ready(function()
{
$(this).on('click focus', '.one, .two',function()
{
if (event.which === 'click')
{
if ($(this).hasClass('one'))
{
console.log('one');
}
else
{
console.log('two');
}
}
else
{
console.log('focus event fired');
}
console.log(this);
});
});
Play around with this: here's a fiddle
documentation on event
jQuery's on, which is used here as though it were delegate
you can use a helper function:
function oneplace(all){
for (var query in all){
$(query).on('click', all[query]);
}
}
and then call:
oneplace(
{'#ele1':function(){
alert('first function');
},
'#ele2':function(){
alert('second function');
}});
jsfiddle here: http://jsfiddle.net/5zwkf/
So, i have some animation actions, this is for my login panel box:
$('.top_menu_login_button').live('click', function(){
$('#login_box').animate({"margin-top": "+=320px"}, "slow");
});
$('.login_pin').live('click', function(){
$('#login_box').animate({"margin-top": "-=320px"}, "slow");
});
now i need to add some hiding action after click on body so i do this:
var mouse_is_inside = false;
$('#login_box').hover(function () {
mouse_is_inside = true;
}, function () {
mouse_is_inside = false;
});
for stop hiding this element on body click, and this for body click outside by login-box
$("body").mouseup(function () {
if (!mouse_is_inside) {
var login_box = $('#login_box');
if (login_box.css('margin-top','0')){
login_box.stop().animate({"margin-top": "-=320px"}, "slow");
}
}
});
Everything is fine but this panel animates after each body click, how to stop this and execute only one time? Depend on this panel is visible or not?
You'd normally do this sort of thing by checking if the click occured inside the element or not, not by using mousemove events to set globals :
$(document).on('click', function(e) {
if ( !$(e.target).closest('#login_box').length ) { //not inside
var login_box = $('#login_box');
if ( parseInt(login_box.css('margin-top'),10) === 0){
login_box.stop(true, true).animate({"margin-top": "-=320px"}, "slow");
}
}
});
And live() is deprecated, you should be using on().
I found a topic for revealing a DIV upwards but as I am no Javascript expert, I am wondering how I can make this work onClick rather than on hover?
Just in case this helps, the link to previous topic is: How to make jQuery animate upwards
Any help is appreciated.
Here is a sample demo
$("#slideToggle").click(function () {
$('.slideTogglebox').slideToggle();
});
$("#reset").click(function(){
location.reload();
});
HTML:
<button id=slideToggle>slide</button>
<br/>
<div class="slideTogglebox">
slideToggle()
</div>
$(document).ready(function() {
var isClicked = false; //assuming its closed but its just logic
$('.button').click(function() {
if (isClicked) {
isClicked = true;
$(this).closest('div').animate({
height: "150px",
}, 400, "swing");
}
else
{
isClicked = false;
$(this).closest('div').animate({
height: "50px",
}, 400, "swing");
}
});
});
This is pretty bad way of doing it any way. You should consider trying to use CSS3 instead and then jsut using jQueries toggleClass
.toggleClass('animateUpwards)
Lets the browser use hardware capabilities to animate all the stuff and also its a nice one liner in JavaScript.
Try jQuery slideUp or as posted elsewhere jQuery slideToggle - Alternatively CSS3 Example
or from the questions you posted, perhaps this is what you meant:
http://jsbin.com/ogaje
Clicking the (visible part of) the div
$(document).ready(function() {
$('.featureBox').toggle(function() {
$(this).animate({top: '-390px', height:'540px'},{duration:'slow', queue:'no'});
// or $(this).slideUp()
},
function() {
$(this).animate({top: '0px', height:'150px'},{duration:'slow', queue:'no'});
// or $(this).slideDown()
});
});
Clicking something else
$(document).ready(function() {
$("#button").toggle(function() {
$("#someDiv").animate({top: '-390px', height:'540px'},{duration:'slow', queue:'no'});
// or $("#someDiv").slideUp()
},
function() {
$("#someDiv").animate({top: '0px', height:'150px'},{duration:'slow', queue:'no'});
// or $("#someDiv").slideDown()
});
});
I'm trying to make it so that my dropdown menu shows when you click a button, and hides when you click anywhere except the dropdown menu.
I have some code working, as far as not closing when you click the menu, however when you click the document when the menu is closed, it shows the menu, so it continuously toggles no matter where you click.
$(document).click(function(event) {
if ($(event.target).parents().index($('.notification-container')) == -1) {
if ($('.notification-container').is(":visible")) {
$('.notification-container').animate({
"margin-top": "-15px"
}, 75, function() {
$(this).fadeOut(75)
});
} else {
//This should only show when you click: ".notification-button" not document
$('.notification-container').show().animate({
"margin-top": "0px"
}, 75);
}
}
});
jQuery's closest() function can be used to see if the click is not within the menu:
$('body').click(function(e) {
if ($(e.target).closest('.notification-container').length === 0) {
// close/animate your div
}
});
you can do something like this if your item is not clicked then hide its dropping list in case of drop down
$(':not(#country)').click(function() {
$('#countrylist').hide();
});
I am using a very simple code for this as :-
$(document).click(function(e){
if($(e.target).closest('#dropdownID').length != 0) return false;
$('#dropdownID').hide();
});
Hope it will useful.
Thanks!!
I usually do like this:
$('.drop-down').click(function () {
// The code to open the dropdown
$('body').click(function () {
// The code to close the dropdown
});
});
So put your body (elsewhere) click function inside the drop-down open click function.
This might not be a complete solution but I´ve created a demo to help you out. Let me know it´s not working as you´d expect.
$(document).click(function(e) {
var isModalBox = (e.target.className == 'modal-box');
if (!isModalBox) {
$('.modal-box:visible').animate({
"margin-top": "-15px"
}, 75, function() {
$(this).fadeOut(75);
});
}
});
$('a').click(function(e) {
e.stopPropagation(); // Important if you´d like other links to work as usual.
});
$('#temp-button').click(function(e) {
e.preventDefault();
$('.modal-box').show().animate({
"margin-top": "0px"
}, 75);
});
Try this :
// The code to close the dropdown
$(document).click(function() {
...
});
// The code to open the dropdown
$(".drop-down").click(function() {
...
return false;
});
try something like:
$(document).click(function(event) {
if($(event.target).parents().index($('.notification-container')) == -1) {
if($('.notification-container').is(":visible")) {
$('.notification-container').animate({"margin-top":"-15px"}, 75, function({$(this).fadeOut(75)});
}
}
});
$(".notification-button").click(function(event){
event.stopPropagation();
$('.notification-container').show().animate({"margin-top":"0px"}, 75);
});
This is what I've decided to use, it's a nice little jQuery plugin that works with little code.
Here's the plugin:
http://benalman.com/projects/jquery-outside-events-plugin/
This is the code that makes my above code in my question work.
$(document).ready(function(){
$(".notification-button").click(function(){
$('.notification-container').toggle().animate({"margin-top":"0px"}, 75);
});
$('.notification-wrapper').bind('clickoutside', function (event) {
$('.notification-container').animate({"margin-top":"-15px"}, 75, function(){$(this).fadeOut(75)});
});
});
$(function () {
$('#button').click(function () {
$('html, body').animate({
scrollTop: $(document).height()
},
400);
return false;
});
$('#top').click(function () {
$('html, body').animate({
scrollTop: '0px'
},
400);
return false;
});
});
I'm using that code to scroll to the bottom/top of the page. I'm wondering if there is a better way to write that? I'm new to jquery so I'm not sure but I've heard using event.preventDefault() may be better instead of return false? If so, where would I insert that?
How about just using a ternary to select the scroll? eg
$(function () {
$('#button').add('#top').click(function () {
$('html, body').animate({
scrollTop : ((this.id=='button') ? $(document).height() : '0px')
},
400);
return false;
});
});
JSFiddle for this code here
You could make this better by adding a class eg 'navButton' to each of these buttons and then using that as the selection ie $('.navButton') - This will eliminate the .add() call.
Also I'd recommend giving the bottom button the id bottom rather than button :) eg
$(function () {
$('.navButton').click(function () {
$('html, body').animate({
scrollTop : ((this.id=='bottom') ? $(document).height() : '0px')
},
400);
});
});
Sure:
$(function() {
var map = {'#button': $(document).height, '#top': '0px'};
jQuery.each(map, function(k, v) {
$(k).click(function() {
$(document.body).animate({
scrollTop:(typeof v === 'function') ? v() : v
},
400);
});
});
});
According to jQuery manual return false and preventDefault does different things:
Example: Cancel a default action and prevent it from bubbling up, return false:
$("a").live("click", function() { return false; })
Example: To cancel only the default action by using the preventDefault method.
$("a").live("click", function(event){
event.preventDefault();
});
So preventDefault is more limited.
Using a specialized plugin jquery.scrollTo.
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-scrollTo/1.4.11/jquery.scrollTo.min.js"></script>
Makes code nice and easy
$(function() {
$('#button').click(function() {
$.scrollTo('max', 400);
return false;
});
$('#top').click(function() {
$.scrollTo(0, 400);
return false;
});
});
Demo: http://jsfiddle.net/disfated/mkZp3/
Also if you want a more flexible code, you could do something like
$(function() {
$(document).on('click', '[data-scroll]', function(e) {
e.preventDefault();
$.scrollTo($(this).data('scroll'), jQuery.fx.speeds._default);
});
});
Then, define scroll behaviour directly in html, example
<button data-scroll="max">scroll to page bottom</button>
<button data-scroll="0">scroll to page top</button>
<button data-scroll="#my_selector">scroll to #my_selector element</button>
Demo: http://jsfiddle.net/disfated/Sj8m7/