jQuery basic toggling only working one way - javascript

I've created some quick jQuery toggle code:
$("#expander.closed").click(function(){
console.log("opening");
$("#expander").removeClass();
$("#expander").addClass("open");
});
$("#expander.open").click(function(){
console.log("closing");
$("#expander").removeClass();
$("#expander").addClass("closed");
});
The idea is that everytime you click #expander the class toggles between open and closed.
However, for some reason, it only works once, changing from closed to open, and then goes no further.
I have no clue why. Here's a jsFiddle.

I think in the beginning, when you bind the events, .closed class does not exists, so the event does not get bound
May be you should bind the event to some other criteria, or use live. which is deprecated though
Better way would be like this
$("#expander_parent").on('click', '#expander.closed', function(){
// Do your stuff
})

Just bind it using the id and toggle the classes using .toggleClass
$("#expander").click(function(){
$(this).toggleClass('open closed');
});
FIDDLE
if you need to do other functions depending on which class it has you can check like this
$("#expander").click(function(){
var $this = $(this);
$this.toggleClass('open closed');
if($this.hasClass('open')){
// do your open code
}else{
// do your close code
}
});
FIDDLE

You can do this and add your other related operations within the if/else conditions
HTML:
<div id="expander" class="closed">Click Me</div>
CSS:
.closed {
background-color: red;
}
.open {
background-color: blue;
}
Javascript:
$("#expander.closed").click(function (){
if ($('#expander').attr('class') === 'closed') {
$('#expander').attr('class', 'open');
// Add other related functions here
} else {
$('#expander').attr('class', 'closed');
// Add other related functions here
}
});
http://jsfiddle.net/mCDwy/1/

Related

slideUp and slideDown animation does not work after first use

I have used jQuery to build something like a dropdown, but it only works for the first two clicks, and then it doesn't. How can I make a dropdown? Can it be done with a loop? (I have not learnt loop yet, so any solution would work.)
For Each SLIDEUP and SLIDEDOWN I wanted to make different TIME....
jQuery(document).ready(function() {
jQuery(".click-on").click(function() {
jQuery(".box").slideUp(2000, function() {
jQuery(".click-on").click(function() {
jQuery(".box").slideDown(500);
});
return false;
});
return false;
});
});
.box {
width: 300px;
height: 300px;
background-color: skyblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p id="fan">THIS IS A FAN</p>
<p id="gun">THIS IS A GUN</p>
<p class="click-on">Click Here</p>
<div class="box"></div>
Do you want to achieve something like that?
$(document).ready(function(){
$(".click-on").click(function(){
$('.box').slideToggle();
});
});
https://jsfiddle.net/jsrc9mbd/1/
The answer by #hetious is what I would have given - but having just seen the comment that slide-up and slide-down should have different times, you'll have to do this instead. Basically, check when you click whether the box is visible or not, and either slideUp or dlideDown accordingly:
jQuery(document).ready(function() {
jQuery(".click-on").click(function() {
var box = jQuery(".box");
if (box.is(":visible")) {
box.slideUp(2000);
}
else {
box.slideDown(500);
}
});
);
(Note that I have extracted a variable for jQuery(".box"), just to save some typing. And you can also use $ as an alias for jQuery to save yet more (the only reason this wouldn't work is if you are using another library which defines a global $ variable, which a few do.)
This is because you misunderstand the meaning of the .click() function.
.click() sets the handler function each time when the click event is triggered from the selected DOM.
Since you have called another .click() within the callback of .slideUp(), you are actually replacing the handler function. In your current logic, the obvious fix is to do infinite callback after each click like:
jQuery(".click-on").click(function(){
jQuery(".box").slideUp(2000, function(){
jQuery(".click-on").click(function(){
jQuery(".box").slideDown(500,function(){
jQuery(".click-on").click(function(){
jQuery(".box").slideUp(2000, function(){//Repeating callbacks... ...
});
});
});
});
and seriously it is very bad. Such implementation should not be done.
Instead, it is better for you to have a conditional checking for each click, so the logic will determine itself either .slideUp() or .slideDown() should be called. It should be like
$(".click-on").click(function(){//you can also use $ instead of jQuery
//do some conditional check here
if(isSlidedUp)$(".box").slideDown(1000);
else $(".box").slideUp(1000)
});
or even better you use .slideToogle().
$(".click-on").click(function(){
$(".box").slideToggle(1000)
}

automatic close function for selection

I have a button which creates a pulldown in which you can select several categories.
Now i want this to close automatically when i click outside the pulldown.
Something like a lightbox or modal popup which closes if you click anywhere else on the page.
Now i have to click the button again to close it. If i dont and go elsewhere on the page, the dropdown stays visible (until i click it)
This is the code of the button:
$(function(){
$('#browse-btn').click(function(){
$('#browse-content').toggle('1000');
$(this).toggleClass('active');
if ($(this).hasClass('active')) $(this).find('span').html('▲')
else $(this).find('span').html('▼')
});
$(".scroll-top").scrollToTop();
$("#category_id").selectbox();
});
Is this possible?
thanks
Using jquery this is the code I used for a similar case scenario sometime ago:
$(document).click(function(event) {
if(!$(event.target).closest('.pulldown').length) {
if($('.pulldown').is(":visible")) {
$('.pulldown').slideUp()
}
}
})
You can read more about this in the original post How to detect a click outside an element? submitted by Art.
I'm not exactly sure of the elements you want to hide as you don't have a demo, so I cannot provide a fully working code, however you should do something like this:
$("body").click(function(event) {
if (event.target.id != "browse-btn") {
// Do something when there's a click outside of #browse-btn
// and the element you want to hide is currently visible
}
});
You can attach a click event to all chidren of the body tag that removes that active class, but you would want to make sure to unbind that event so it doesn't run every time a click takes place that doesn't have some sort of prevent default on it. Something like this:
$(function(){
var hidePulldown = function(){
$('#browse-btn').removeClass('active');
$('body *').unbind("click", hidePulldown);
}
$('#browse-btn').click(function(){
$('#browse-content').toggle('1000');
$(this).toggleClass('active');
if ($(this).hasClass('active')) $(this).find('span').html('▲')
else {
$(this).find('span').html('▼');
$(document).on('click', 'body *', hidePulldown);
}
});
$(".scroll-top").scrollToTop();
$("#category_id").selectbox();
});
Also, the
$(document).on('click', element, function(){function body})
is the preferred way to attach click events i believe: $(document).on('click', '#id', function() {}) vs $('#id').on('click', function(){})
This is what worked flawlessly for me after reading some of the answers here:
$(document).click(function(event) {
if(!$(event.target).closest('#menucontainer').length &&
!$(event.target).is('#menucontainer')) {
if($('#menucontainer').is(":visible")) {
$('#menucontainer').hide();
}
}
})
Thanks for pointing me in the right way!

jQuery - Hover after DOM change

With $('#sidebar').toggleClass('small'); Im adding adding/removing specified class from #sidebar.
When #sidebar has class small I should be able to perform additional actions when user hover over #sidebar.small.
I have tried to accomplish that with code bellow:
$("#sidebar.small").on({
mouseenter: function () {
alert(1); //doesn't work
},
mouseleave: function () {
//stuff to do on mouse leave
}
});
But that doesn't work.
How should I perform hover function on changed DOM element?
You should be able to use the jquery hover method to do this: https://api.jquery.com/hover/
Update:
Sorry noticed one other thing... when you originally set your event handler, does #sidebar have the css tag or not? The way your code is written, if it doesn't, it will try to attach to the element $("#sidebar.small"), so if the css tag is not there it won't attach to anything.
I think you want more like this:
$("#sidebar").on({
mouseenter: function() {
if($('#sidebar').hasClass('small')) {
alert(1);
}
}
});
Update again for a typo, sorry...
Jquery only binds the handlers for the found elements at the time of binding.
The solution is to rebind the appropriate handlers when you add the class.
jsfiddle
code from the fiddle:
$('#foo').click(function(){
$('<span></span>')
.text('A Span')
.appendTo('#container');
});
$('#bar').click(function(){
$('span').first().toggleClass('small');
bindHover();
})
function bindHover(){
$('span.small').unbind('hover'); // Avoid re-binding something
$('span.small').hover(function(){
alert('a')
});
}
bindHover();

JQuery click and hover function not working correctly

I have two buttons which im working with, I am trying to make a hover effect and when the user clicks on the button have a clicked event.
I have been playing around with a few jquery methods such as mouseover mouseout etc but still no luck. The idea is to get the hover to only work on elements that have not been selected already.
The issue with the code below is that once an button has been selected if the user hovers over the selected method it gets rid of its current state.
Is their a way of not getting rid of the current state once a button has been selected?
Thanks
$(".M").click(function(){
$(this).css('background-color','#515B69');
$(this).css('color','#fff');
$(".F").css('color','#515B69');
$(".F").css('background-color','#fff');
});
$(".M").mouseover(function() {
$(this).css('background-color','#515B69');
$(this).css('color','#fff');
});
$('.M').mouseleave(function(){
$(this).css('color','#515B69');
$(this).css('background-color','#fff');
});
$(".F").click(function(){
$(this).css('background-color','#515B69');
$(this).css('color','#fff');
$(".M").css('color','#515B69');
$(".M").css('background-color','#fff');
});
$(".M").mouseover(function() {
$(this).css('background-color','#515B69');
$(this).css('color','#fff');
});
$('.F').mouseleave(function(){
$(this).css('color','#515B69');
$(this).css('background-color','#fff');
});
I would recommend offloading a lot of these tasks with CSS
.M, .F {
background-color: #fff;
color: #515B69;
}
.M.active, .M:hover,
.F.active, .F:hover {
color: #fff;
background-color: #515B69;
}
And for your JS
$('.M, .F').on('click', function () {
$('.M, .F').removeClass('active');
$(this).addClass('active');
});
Set a variable in your click functions and then check it with if statements in your mouseover and mouseleave functions. For example:
var clicked = 0;
$(".F").click(function(){
$(this).css('background-color','#515B69');
$(this).css('color','#fff');
$(".M").css('color','#515B69');
$(".M").css('background-color','#fff');
clicked = 1;
});
if (clicked > 0){
$(".F").mouseover(function() {
$(this).css('background-color','#515B69');
$(this).css('color','#fff');
});
}
I'd prefer to use removeClass and addClass.
If You use removeClass without parameters, all classes will be removed from element. Then add Class, that You want. You can make it that way, for example:
$(selector).removeClass().addClass("your_class");
In that way, styles are seperated from scripts, which is always a good practice.
Try to rewrite Your code in that way. If You have any questions, just ask in a comment, I will update my answer :).
PS. Of course You must place "your_class" in style.css file :).
Best regards

Stop style HOVER behaviour with jQuery?

I have a div with style.
This style
body .d:hover
{
background-color:red;
}
But I want (if possible) that Jquery will stop this hover behaviour.
I tried with
$(".d").hover(function () { return false;});
$(".d").mouseenter(function () { return false;});
nothing helped.
any help ?
here is the JSBIN ( I want that after pressing the button - nothing will happen when hovering.)
If you want to stop this behavior constantly, you may remove the stylesheet rule, according to W3C wiki:
function stop(m) {
$.each(document.styleSheets, function(i, sheet) {
$.each(sheet.rules, function(i, rule) {
if (new RegExp(m + "\\s*:hover").test(rule.selectorText)) {
sheet.deleteRule(i);
} // TODO: improve RegExp
});
});
}
stop(".d");
If you want to change the state without removing, there is an option to change styleSheet.disabled property, in case you have the :hover rule set in a separate stylesheet.
Note, that I'm not sure about the compatibility issues here, it should be determined additionally.
DEMO: http://jsbin.com/akunew/10/edit
Add a new definition to your CSS:
.d.no-hover:hover {
background-color: black;
}
Now you can just add the no-hover class to the elements which should no longer have a hover effect:
$(obj).addClass('no-hover');
May be this kind of trick: http://jsbin.com/akunew/14/edit
<div style="border:solid 1px red;height:100px;width:100px;" class="d"> </div>
<input type="button" value="stop this hover" onclick="stop()" id="btn"/>
remove the class:
function stop(){
$(".d").addClass('e').removeClass('d');
}
When you calling onclick="stop(this)" it will get input as your $(obj), not your element .d.
EDIT There is no javascript solution to remove :hover
based on ur JSBIN example. below code will work
function stop(obj)
{
$(obj).hover(function () {
$(this).css('background-color','white');
return false;});
$(obj).mouseenter(function () {
$(this).css('background-color','white');
return false;});
$('body').append('<style>body div.d:hover {background-color:transparent !important}</style>');
}
u have overwrite :hover css of that particular element
CSS
.d:hover
{
background-color:Red;
}
.noClass
{
background-color:none;
}
JavaScript
function stop()
{
$(".d").addClass('noClass').removeClass('d');
}
I use a trick- when i am on hover onto an element (and click something inside that HOVERed element), then you can use this javascript method to cancel that hover css:
document.getElementById('sarchevi').className='active';
//on mouse move, remove class
(function(){
var moved = false
window.onmousemove = function(e)
{ if(!moved){ moved = true; document.getElementById('sarchevi').className ='a'; } }
})()
I know this question is four years old, but future visitors should know about the modern approach to this particular problem.
You can use a simple solution that (at its core) uses a CSS property and is supported by all browsers except IE < 11.
$('.d').css('pointer-events', 'none');
You might as well just copy this specific class from Bootstrap:
.disabled {
pointer-events: none;
}
And then apply it via jQuery:
$('.d').addClass('disabled');
Keep in mind, however, that this CSS property prevents the element from capturing any DOM events (such as hover, but also click, etc.)

Categories

Resources