I have an element which has display:none initially. When I click a button, a jQuery event is triggered, and my script toggles the element's display attribute between block and none when the button is clicked.
I am trying to make it so the background of the element's parent changes color depending on whether or not the element is hidden.
$("#button").on('click', function(){
if($(".hidden-content").is(":hidden")) {
$(".other-element").css("background-color","rgba(20,20,20,.9)");
} else {
$(".other-element").css("background-color","rgba(20,20,20,0)");
}
})
For some reason, when I click the button to toggle the dropdown, the jQuery treats the .hidden-content like it's not hidden, even though when I inspect the element, it says
.other-element { display: none };
Does anyone know why this could be? Since the hiddenness is toggled using jQuery, it may not actually change .hidden-content's own css, but I don't see why that should be a problem on the very first click.
The easiest solution is to add a CSS class to the element whose background-color property you want to change. Check it out:
In your click function, you can use jQuery's .toggleClass() method to add and remove a CSS class every time the button is clicked. In your CSS, you can then override the default background color with the new class selector. There's an example below. It sounds like you have your own method of hiding and showing the content, so for this example I'm just going to use jQuery's .toggle() function to do that bit.
I've created a working example on CodePen for you as well :)
$('#button').on('click', function() {
// The important part: add and remove the CSS class to change colors!
$('#parent-element').toggleClass('content-on');
// Hide and show the content element. You can do this differently of course:
$('.content').toggle();
});
And your CSS would look something like this:
#parent-element {
background-color: rgba(20,20,20,.9);
}
#parent-element.content-on {
background-color: rgba(20,20,20,0);
}
Related
I'm working on a simple website to use at a conference and I'm looking for some help understand the implications of two ways to achieve an effect:
Using .toggle() to show or hide content
This is the method I started with because it is an intuitive action to tap an element to have it's content appear. However, a problem arises when I try to limit one open div at a time.
Summary I'm having trouble limiting the number of opened elements.
Applying an active class with jQuery
Using this method, I can display the hidden content by selecting the child element (see code below), but this stops the user from closing the content by tapping it again. Because I'm expanding divs horizontally, this isn't ideal because of the scroll space that's added.
Summary: How do you close the active div on a second click with this method?
CodePen Demo - Staged site
Relevant Code
This method is using CSS to apply the active class. It works, but like I said above, I'm having a hard time removing the active class from an element tapped again. Use the demo linked above to see how the toggle action works on the page (uncomment lines 8 and 9).
$(".title").click(function() {
//remove active class from other elements
$('.post').removeClass('active');
// Bind to the div
$post = $(this);
// Set active class on .post to control scroll position
$post.parent().toggleClass('active');
// Toggles the hidden .content div
//$post.next().toggle(250);
$('html, body').animate({scrollLeft: $('.active').offset().left},500);
});
The accompanying .active CSS:
.post .content {
display:none;
}
.active {
margin-top:-120px;
}
/* Shows the content div rather than toggling with jQuery */
.active > .content {
display:block;
}
Is there a way I can allow both behaviors (tap to open/close, one open div at a time)? Which method is best suited for that?
You certainly can use toggle() while hiding the other ones. Try something like this:
$(".title").click(function() {
$('.post').not($(this).parent()).hide();
$(this).toggle();
$('html, body').animate({scrollLeft: $(this).parent().offset().left},500);
});
Update: changed .not(this) to .not($(this).parent()) as .title is always child of .post.
Slightly optimised version of #Daniel's solution
$('.title').click(function() {
var clickedPost = $(this).parent('.post')
clickedPost.toggle().siblings('.active').hide();
$('html, body').animate({scrollLeft: clickedPost.offset().left},500);
});
Local var: If you access this, or any other DOM element more than once inside a scope, it's always more efficient to assign it to a local var than wrap it in a JQ object multiple times.
SIblings selector: I don't have a benchmark for this, but running a selector on a subset of the DOM rather than the whole DOM seems intuitively faster. This is more best practice than a large performance hit, but all the little functions add up too.
Chaining JQuery functions: Most JQ functions that act on a JQ element return that element. I can't say that this is more efficient but it's certainly more concise, but this all depends on personal preference.
With very little code you can do this with toggle.
$(".title").click(function() {
$(".post").hide();
$(this).children(".post").toggle();
});
I made it as simple as possible to show the functionality which you could then extend on.
Here is a jsfiddle
EDIT update after comment
I have edited it to now only show 1 at a time and if the 1 currently being shown is clicked it hides it
I also elected to use slideUp() and slideDown() as it seemed to better suit your needs
$(".title").on("click", function(){
if($(this).children(".post").is(":visible")){
$(this).children(".post").slideUp();
}else{
$(".post").not($(this).parent()).slideUp(500);
$(this).children(".post").slideDown(500);
}
});
updated jsfiddle
I need to hide a div if another div has a class.
I've created a very basic example HERE
I need the div on the bottom to hide when the word "click" is.. well.. clicked. It adds a class to the middle div just fine, but it seems hasClass() doesn't want to work?
NOTE: The structure needs to be like this. If "click" is clicked, modify the middle div (add class?), and manipulate the bottom div based on the middle div. With this setup - I can't just do "if CLICK is clicked, slideUp() the bottom div".
Also, once "ok" or "cancel" is clicked, it will revert, because the middle div will no longer have the class. Provided that's the method I can get working here, haha.
your if statement is outside of any function, so there is no reason for it to be called after the script is loaded.
See this fiddle, I think that's what you want.
On a side note, another variation to check if there's a class is:
if ( $('body.className').length ) {
Still recommend hasClass though. Just nice to see variation sometimes.
This is only getting called once, when the script loads. You need to have make sure it gets called in your .click(...) handler.
if($('#timestampdiv').hasClass('hidepub')) {
$('#major-publishing-actions').slideUp('slow');
}
As mentioned by others, you don't have a call to if on all click event handlers. Create a custom function with statement inside if and call it on all click handler.
Check this fiddle
After you append the class to the DOM element, this should properly hide the element.
$('.element').click(function()
{
$('.thisElement').addClass('hidepub');
if($('.thisElement').hasClass('hidepub')) {
$('.thisElement').hide();
}
});
You can combine them all into one function - And you want that check to be inside the click functions
You can reduce the addclass removeclass by using toggleClass and passing in a condition
$('a.edit-timestamp,a.save-timestamp,a.cancel-timestamp').click(function() {
var $tsdiv = $("#timestampdiv");
// add class showpub if edit is clicked
$tsdiv.toggleClass('showpub',$(this).hasClass('edit-timestamp'));
// add class hidepub only if it wasn't edit that was clicked
$tsdiv.toggleClass('hidepub',!$(this).hasClass('edit-timestamp'));
// then do your toggle
if ($tsdiv.hasClass('hidepub')) {
$('#major-publishing-actions').slideUp('slow');
}else{
$('#major-publishing-actions').slideDown('slow');
}
});
http://jsfiddle.net/JPcge/
You can reverse it by swapping the logic passed into the toggleClass() methods
I've found a couple of search results here but they're all for jQuery and the couple I looked at weren't applicable to my case.
This is a small project and I've avoided using jQuery so far. I want to keep it like that as to not need the library.
Basically, I'm dragging an <article> element to a <div> element. The div has the background-image of a closed trashbin. In the CSS it is set to display the same, but open, trashbin when :hover is triggered.
Now, when I pull my article element to the div, the :hover effect isn't being triggered.
How do I do this?
All required elements are set draggable and the needed event listeners have been added, Console.log confirms they work.
You can define a CSS class called 'open_trash' and set the background image of a open trash there and then you can use javascript to change the class of the dragged element on mousedown like this
document.getElementById("draggedItem").className = "open_trash";
You can set the class name to either an empty string or something else onmousedown.
I am trying to change the background colour of a label adjacent to an input element when the input becomes 'active'.
This will need to work for both clicking to the input and tabbing between input elements.
I was able to get this to work if the user clicked the input, but my solution didn't work if the user tabbed into an input element. I was also having to repeat the code for each input element. Considering I am likely to have quite a few input elements, I figured there must be a more graceful way?
Here is a link with the basic HTML + CSS.
http://jsfiddle.net/xXqhH/
Assuming I've understood what you're trying to do correctly, just bind event handlers to the focusin and focusout events. You can use prev to find the immediately preceding sibling, and css to set a CSS property:
$("input").focusin(function() {
$(this).prev("label").css("background-color", "red");
}).focusout(function() {
$(this).prev("label").css("background-color", "gray");
});
Here's an updated fiddle.
I lied in my comment - I am going to write this from scratch. I assume the problem you had where it was working with clicking, but not with tabbing, was due to using the .click() jQuery function. Using .focus() instead, along with a CSS class, should provide the desired result:
jQuery code:
$('input:text').focus(function(e) {
$('label').removeClass('active');
$(this).prev('label').addClass('active');
});
Extra CSS:
label.active {
background: red !important;
}
Working Demo
In my CSS I have:
li.sort:hover {color: #F00;}
All my LI elements under the sort class function properly when the DOM is ready.
If I create a new LI element (using mootools el.addClass(classname)) I can set the base class, but can't figure out how to add a hover class to it.
Any ideas?
The hover pseudoclass can be defined ahead of time in the stylesheet based on the classname that you're specifying. Such as:
li.classname:hover {color:#F000;}
So it's defined the same way, via the stylesheet. You would just plan ahead, knowing that you'll be defining the class name on JS-generated LI tags with a certain class, and style for it despite the fact that the list items don't exist until you create them with JavaScript.
Hover class is added automatically when you add the non hover class. E.g. if you have
.MyClass
{
...
}
.MyClass:hover
{
...
}
just add the MyClass, and the MyClass:hover will work.
:hover is not a class, but is a pseudo-selector that will select any elements the mouse is currently hovering over. If you create an li element, and add the sort class to it, then whenever you move your mouse over the element, the li.sort:hover rule should be activated, if the browser is working correctly.
Not all browsers will accept the hover pseudo class on all elements. You should consider using javascript for this effect. jQuery for example, makes this very easy.
Not all browsers will accept the hover pseudo class on all elements. You should consider using javascript for this effect. jQuery for example, makes this very easy.
To be more specific, IE6 only picks up :hover styles on anchor (a) elements.