Toggling HTML visibility using CSS and jQuery - javascript

Ok so I have a div that contains a canvas and a span which contains an image. I want it such that if the user hovers over or focuses on the div that the image inside of the span will appear. The image wil be invisible otherwise.
Long story short I want to have a canvas with a red 'X' on the corner that is only visible when the canvas is active
$('image-canvas').hover(function() {
$('delete-image').addClass('active');
}, function() {
$('delete-image').removeClass('active');
})
.delete-image {
position: absolute;
top: 0px;
right: 0px;
}
.delete-image>img {
width: 32px;
visibility: hidden;
}
.delete-image.active>img {
width: 32px;
visibility: visible;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="canvas-container" tabindex="1">
<canvas id="imageCanvas"></canvas>
<span class="delete-image">
<img src="file:///E:/Apps/Emoji-App/emojis/icons/if_erase_delete_remove_wipe_out_181387.png"/>
</span>
</div>
The hover event fires just fine but the image refuses to toggle visibility. Any help?

When you use a class within your selector, write it like this:
$('.myDiv')
When you use an ID within your selector, write it like this:
$('#myDiv')
For further informations, check out jQuery's learning center website.

Seems like you have misspelled or have not specified the jQuery selector type (class . or id #). Please try this:
$('#imageCanvas').hover(function () {
$('.delete-image').addClass('active');
}, function () {
$('.delete-image').removeClass('active');
})

See here .
$("#control").mouseover(function(){
$('#img').show();
});
$("#control").mouseout(function(){
$('#img').hide();
});
#img{
display:none;
}
#control{
margin-bottom:10px;
padding:5px;
background-color:#eee;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='control'>Show/Hide</div>
<img src='https://cdn.sstatic.net/Sites/stackoverflow/img/404.svg' id='img'>

The question is not well-phrased, so I ain't sure I totally understood what you wanted.
When you try to select by class, don't forget the dot '.'
$('image-canvas').hover(function () {
$('.delete-image').addClass('active');
}, function () {
$('.delete-image').removeClass('active');
})
When using functions 'addClass', 'removeClass', 'toggleClass', etc. - you don't use the '.' sign because it is a function that refers only to classes. On the other hand, when using jQuery selector $(' ') or vanilla querySelector(' '), you should declare what kind of attribute you are selecting by, those will be '#' for ID, '.' for Class, and if you want to select by anything else you can use $('*[anyattribute=anyvalue]'), in your clase it could be $('span[class=delete-image]').
Good luck

Related

Jquery will not select button after class has been toggled

I have some jquery that will, when a button is clicked, switch a class from a button to a different class (i.e. on click switch class from #testButton from .first to .second with an image toggle to show it works). The first click works well and it toggles the image, but the second click does not do anything. It seems as if it is not recognizing the new class. Here is a fiddle.
https://jsfiddle.net/myfb44yu/
This is the problematic javascript.
$(document).ready(function(){
$('.first').click(function(){
alert('works');
$('#testButton').toggleClass('first', 'second');
});
$('.second').click(function(){
alert("works");
$('#testButton').toggleClass('second', 'first');
});
});
The interesting thing is that it works when I use an alert() to check but not when I try to change an img src.
Your main issue here is a syntax error in regards to your .toggleClass, but seeing as others have addressed that, I'd like to point out that you should consider re-thinking how you apply your listeners - just as good habit moving forward.
An overview of jQuery Event Bindings
Think of the elements on your page as items in a store. You're an employee, and your manager says "Go put a red tag on anything in the toys department", and so you do. The next day, he puts 10 new toys in the toy department, and says to you "Why don't all the toys have red tags on them?" He then moves one of the toys to the clothing section and asks you, "Why does this item have a red tag on it?" It's simple. You put the red tags on anything in the toys department when he told you to do it - things got moved around afterwards.
The toys in this example would be your .first and .second elements.
This is how jQuery event bindings work - they only apply to elements that satisfied the selector at the time the event was initialized.
So, if you do $('.myClass').click();, then put .myClass on five buttons - none of those buttons will call this function, as they didn't have listeners put on them.
Similarly, if you put a listener on an element using class, but then remove the class from that element, it will maintain the bound event.
The Solution
$(document).on("click", ".first", function() { } );
This is known as event delegation.
In continuing with my analogy from before, this would be the equivalent of skipping tagging the items altogether, and instead just deciding whether or not they're a toy when the customer brings them to the cash register.
Instead of putting the listener on specific elements, we've put it on the entire page. By using ".first" as the second parameter (which takes a selector), the function will only be executed if the element has class first.
Hope this helps.
EDIT: As I was typing, JHecht left a good answer that points out the same issue I outlined above.
N number of elements can have the same class name ,so that's the reason if your trying to search it as $('.classname') returns an array ,so that's the reason your code is not working.class selector
Id is unique,each element should have a single id . In your code button has two id's and for the same button your trying to toggle first and second,you need not have two separate events for first and second
instead you can write as following
check this snippet
$(document).ready(function() {
var firstElements = $('.first')
var first = firstElements[0];
var secondElements = $('.second');
var second = secondElements[0]
$("#testButton").click(function() {
alert('works');
$(this).toggleClass('first').toggleClass('second');
});
});
.first {
color: red;
}
.second {
color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="img/images.jpeg" alt="" id="testImage">
<div id="testDiv">
<button type="button" id='testButton' class='first'>Hi</button>
</div>
Hope it helps
Ho about this solution. Hope it helps!
$(document).ready(function(){
$("#testButton").click(function(){
if($(this).prop("class") === "first"){
alert('first');
$(this).removeClass("first").addClass("second");
}
else if($(this).prop("class") === "second"){
alert("second");
$(this).removeClass("second").addClass("first");
}
});
});
.first{
color: red;
}
.second{
color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<img src="img/images.jpeg" alt="" id="testImage">
<div id="testDiv">
<button type="button" id='testButton' class='first'>Hi</button>
</div>
I hope that what I am about to say makes more sense than I feel it does.
Your issue is that when you assign the click events, there is not currently an element that has a class of .second.
Also, your code is wrong. toggleClass accepts a few arguments, the first is a string of classes, the second is an optional parameter to check whether or not to toggle the classes on or off.
A way to accomplish what you want without changing a whole lot of code is event delegation, shown below.
$(function() {
$(document).on('click', '.btn-first,.btn-second', function() {
//here we are adding the click event on the document object, and telling it that we only want to delegate this event to an object that matches the classes of .btn-first or .btn-second.
//Note: to those saying "why not just do it on the .btn class an avoid having to do this", it is so he can see what delegation looks like. But you are correct, with this markup it would be better to simply add the click event on the .btn class.
$(this).toggleClass('btn-first btn-second');
});
});
.btn {
padding: 4px 8px;
border-radius: 3px;
border: 1px solid grey;
}
.btn-first {
background-color: green;
border-color: green;
}
.btn-second {
background-color: orange;
border-color: orange
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="img/images.jpeg" alt="" id="testImage">
<div id="testDiv">
<button type="button" id='testButton' class='btn btn-first'>Hi</button>
</div>
A combination of javascript, CSS and HTML to toggle the class of #testButton when any element of class "first" or "second" is clicked, including the test button itself. The posted code was changed to supply JQuery's .toggleClass method with a space separated list of class names. Click "run snippet" to test the effect.
$(document).ready(function(){
$('.first').click(function(){
$('#testButton').toggleClass('first second');
});
$('.second').click(function(){
$('#testButton').toggleClass('first second');
});
});
.first { border: thick outset green;}
.second { border: thick inset red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="first">This paragraph has first class</p>
<p class="second">This paragraph has second class</p>
<button type="button" id="testButton" class="first">this button starts out first class</div>
The script can then be simplified by combining multiple class names in a single selector, leaving just:
$(document).ready(function(){
$('.first, .second').click(function(){
$('#testButton').toggleClass('first second');
});
});
Make a neutral class that the buttons both share (.btn).
Then add one of the state classes to each button (.first or .second).
Delegate the click event to the neutral class only ($('.btn').on('click',...).
Then toggle both state classes on this ($(this).toggleClass('first second');)
The images change by CSS, each button has 2 images which alternate between display:none/block according to the button's state class.
There is an example with the images outside of buttons and another example that doesn't toggle classes around.
SNIPPET
$('.btn').on('click', function() {
$(this).toggleClass('first second');
});
/* OR */
$('.alt').on('click', function() {
$('.img').toggle();
});
.first > .one {
display: block;
}
.first > .two {
display: none;
}
.second > .one {
display: none;
}
.second > .two {
display: block;
}
.first + .one {
display: block;
}
.first + .one + .two {
display: none;
}
.second + .one {
display: none;
}
.second + .one + .two {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Use jQuery with CSS</p>
<button class='btn first'>
<img src='http://placehold.it/50x50/000/fff?text=1' class='one'>
<img src='http://placehold.it/50x50/fff/000?text=2' class='two'>
</button>
<button class='btn second'>
<img src='http://placehold.it/50x50/0e0/960?text=1' class='one'>
<img src='http://placehold.it/50x50/fff/000?text=2' class='two'>
</button>
<br/>
<br/>
<button class='btn first'>Toggle</button>
<img src='http://placehold.it/50x50/fc0/00f?text=1' class='one'>
<img src='http://placehold.it/50x50/00f/fc0?text=2' class='two'>
<button class='btn second'>Toggle</button>
<img src='http://placehold.it/50x50/fc0/00f?text=1' class='one'>
<img src='http://placehold.it/50x50/00f/fc0?text=2' class='two'>
<p>Or use only jQuery no CSS</p>
<img src='http://placehold.it/50x50/0e0/930?text=1' class='img'>
<img src='http://placehold.it/50x50/930/0e0?text=2' class='img' style='display:none'>
<button class='alt' style='display:block;'>Toggle</button>

Select <divs> within parent <div> using jQuery

I have a parent <div>, #amwcontentwrapper, which has a series of divs within it with their own classes and ids.
I want to use jQuery to select these child divs, and IF they have the class .amwhidden, do nothing, but if not, remove the .amwshown class and add the .amwhidden class.
This is what I have so far, but it is not working. I think it may be my selecting of the child divs within the parent.
Can anybody see any obvious problems? Thanks for your help.
if ($('#amwcontentwrapper > div').hasClass('amwhidden')){
} else {
$('#amwcontentwrapper > div').fadeIn(600, function(){
$('#amwcontentwrapper > div').removeClass('amwshown');
$('#amwcontentwrapper > div').addClass('amwhidden');
});
}
And here is the basic html that I am using:
<div class="amwshown" id="amwintro">
Intro Section, which should have the 'amwshown' class removed, and the
'amwhidden' class added, when the jQuery runs. Currently, this does not happen.
</div>
UPDATE: Using War10ck's solution in the comments below (i.e. $('#amwcontentwrapper > div.amwshown')) I have managed to get the classes changing as I wished. However, those which have had the .amwshown class removed and .amwhidden class added still show on the page, despite the CSS looking like this:
.amwhidden {
display:none;
}
.amwshown {
display:block;
}
Looking at the Dev Tools, it seems that, when the jQuery is run (on a click event) the classes are changing, but any classes which are having the .amwshown class added (thus displaying them on the page) are also having the a <style> tag added to them which makes them display:block;
When I then press another button, which should hide the aformentioned <div> to make way for another one, the class is being changed to .amwhidden, but that <style> tag is not being deleted, so even though it has the .amwhidden class, it is still on the page.
I've created a JSFiddle here, if anybody still wants to help!
`
$(document).ready(function() {
$('#buybutton').click(function() {
$('#amwcontentwrapper > div.amwshown').fadeIn(600, function() {
$(this).removeClass('amwshown').addClass('amwhidden');
});
if ($('#amwbuy').hasClass('amwshown')) {} else {
$('#amwbuy').fadeIn(600, function() {
$('#amwbuy').removeClass('amwhidden');
$('#amwbuy').addClass('amwshown');
});
}
});
$('#phdbutton').click(function() {
$('#amwcontentwrapper > div.amwshown').fadeIn(600, function() {
$(this).removeClass('amwshown').addClass('amwhidden');
});
if ($('#amwphd').hasClass('amwshown')) {} else {
$('#amwphd').fadeIn(600, function() {
$('#amwphd').removeClass('amwhidden');
$('#amwphd').addClass('amwshown');
});
}
});
});
#sidebar {
position: absolute;
left: 1%;
top: 1%;
font-size: 5em;
color: #000000;
width: 10%;
display: block;
background-color: red;
}
#amwcontentwrapper {
position: absolute;
left: 20%;
top: 5%;
}
.amwshown {
display: block;
}
.amwhidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="amwsidebar">
<span class="sidebarbutton" id="phdbutton">PhD Button</span>
<br />
<br />
<span class="sidebarbutton" id="buybutton">Buy Button</span>
</div>
<div id="amwcontentwrapper">
<div class="amwshown" id="amwintro">
<p>An intro section to welcome the visitor. Disappears when one of the other sections is clicked.</p>
<br />
<br />
</div>
<div class="amwhidden" id="amwbuy">
Buy Section
</div>
<div class="amwhidden" id="amwphd">
PhD Section
</div>
</div>
`
You can use not to remove the elements you do not want, like this:
$('#amwcontentwrapper > div').not('.amwhidden')
.removeClass('amwshown')
.addClass('amwhidden');
And work with that.
Try this
$(document).ready(function() {
$("#amwcontentwrapper").children().each(function(elem, x) {
if ($(x).attr("class") == "amwhidden") {
alert($(x).attr("class"));
$(x).removeClass("amwhidden").addClass("amwshow");
alert($(x).attr("class"));
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div id="amwcontentwrapper">
<div class="amwhidden"></div>
<div></div>
<div></div>
</div>
You can try each as follow,
$("#amwcontentwrapper div").each(function(){
if($(this).hasClass('amwhidden'))
//DO something
else
//DO something
});
Thank you for all help, it has prompted some brainstorming which has solved this issue.
Instead of adding the .amwhidden class and removing the .amwhidden class using jQuery, I have just created a .amwsection class, which all the sections belong to which has an initial display value of none. So far, so good; all of the sections are not there when you load up the page.
Then I use the .css jQuery function to change the display:none to display:block when the corresponding button is clicked, and changing all other .amwsections to display:none. This works just fine, but the effect is quite abrupt; there is no fading in, as you would get if you used the .animate function. .animate, however, does not work with the display value.
.fadeOut and .fadeIn to the rescue! By wrapping the .css change in these, I can create a fading in/out effect and can still use the display value.
Here is one example of this code.
The #buybutton is the button to be pressed.
#amwintro is just something which appears when the page loads - it will now be set to display:none if this is the first button pressed.
The .amwsection are all of the hidden sections. This portion of the code just resets all of them. This and the #amwintro section happen very quickly (1/100th of a second) to keep response time good.
The #amwbuy is the specific section that I want to reveal. As you can see, this fades in over a longer period.
Currently only tested in Chrome, but I think I've got it!
$(document).ready(function () {
$('#buybutton').click(function() {
$('#amwintro').fadeOut(1, function() {
$(this).css({
display:'none',
});
});
$('.amwsection').fadeOut(1, function() {
$(this).css({
display:'none',
});
});
$('#amwbuy').fadeIn(600, function() {
$(this).css({
display:'block',
});
});
});
});

click to change background toggle

When I click on it changes background. It works fine. But what if I want to click on it again to restore the original background? I have this code:
jQuery(document).ready(function($) {
$(".select").on("click", function () {
$(this).css("background-image", "url(images/selected.png)");
});
});
Here is jsfiddle EXAMPLE
Basically when I click on the div it changes the background, which is fine. But I want to have ability to click on it again to restore the original background.
It will be an alternative solution for tick box, but just for demo purposes.
Thanks
JS
replace
$(this).css("background-image", "url(images/selected.png)");
with
$(this).toggleClass("active");
Style
#multiselect .active {
background-image: url('...');
}
Fiddle http://jsfiddle.net/09xgrhxo/4/
Instead of using .css() to change the background-image I would add a class in your CSS and use .toggleClass().
Also be aware that simply adding a class will not be specific enough because your css is using:
#multiselect .select
you're going to have to target the class you add as a child of #multiselect:
#multiselect .change
CSS
#multiselect .change{
background-image: url(http://t2.gstatic.com/images?q=tbn:ANd9GcSZ51HqKXkejWAFcSBrodHd5eUN2QaIJro0jhN1YpmljSdQ5dj2)
}
JS
$(".select").on("click", function () {
$(this).toggleClass("change");
});
FIDDLE
You could use data-* attribute.
$('.select').attr('data-img', $('.select').css('background-image'));
$(".select").on("click", function() {
$(this).css("background-image", ($(this).css('background-image') == $(this).data('img')) ? "url(http://t2.gstatic.com/images?q=tbn:ANd9GcSZ51HqKXkejWAFcSBrodHd5eUN2QaIJro0jhN1YpmljSdQ5dj2)" : $(this).data('img'));
});
#multiselect .select {
background: url(http://t0.gstatic.com/images?q=tbn:ANd9GcQF_ErOlc78eOGZaEWb-dwPkrv2uyAoKx0Pbn3-e0tAZoUDSQRCsA) center;
width: 250px;
height: 100px;
margin-bottom: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="multiselect">
<div class="select">Option1</div>
<div class="select">Option2</div>
<div class="select">Option3</div>
</div>
Instead of writing background-img url in javascrpt, I would suggest to create two classes having same properties but different background-img url which you want to toggle. so here we will be toggling class (ultimately background-img) in javascript.
see jsfiddle [example][1]
[1]: http://jsfiddle.net/09xgrhxo/13/

Selecting child of previous parent jQuery

Lately I've been trying my hand at animation using CSS and jQuery, it went well, however, now I want to do a bit more.
That is, once the user clicks information should show up on top of the image.
At the moment, I just have a few tags on which I perform the animations and class toggles.
My question is, I've thought about doing the following:
<div class= "singleImage">
<img src.... class="actualImage">
<p>text to put over the image</p>
</div>
This would be done per image which means that I'll have about 5 of them with different images.
However, I don't know how to go about selecting the previous element of class "actualImage".
Has anyone got any suggestions?
Thank you
Use the jQuery prev function. Example: Assume you want to select the image previous to the second image:
var foo = $(".singleImage").eq(1);
var bar = $(foo).prev().find('.actualImage');
Fiddle
Try this:
$('singleImage').children('.actualImage').prev();
I'm not sure why you are trying to select the previous element, but you could do something akin to this:
Bind a function to the click event for the element containing your image and caption.
Inside this function, toggle the caption.
Also, bind a click event handler to the body to detect clicks "off" the containing element.
HTML:
<a href="#" class="has-caption">
<img src="http://placehold.it/300x300" />
<span class="caption">This is a caption</span>
</a>
CSS:
a.has-caption { position: relative; }
a.has-caption .caption {
background: rgba(0, 0, 0, .25);
bottom: 0;
color: #fff;
display: none;
height: 20px;
left: 0;
line-height: 20px;
position: absolute;
width: 100%;
}
a.has-caption img { vertical-align: bottom }
JavaScript
$('a.has-caption').on('click', function(e) {
e.preventDefault(); e.stopPropagation();
var self = $(this)
, tmpId = 'toggle-' + Date.now();
self.addClass(tmpId);
$('span.caption', self).toggle();
$('body').one('click', function(e) {
if (!$(event.target).closest('.' + tmpId).length) {
$('span.caption', '.' + tmpId).hide();
self.removeClass(tmpId);
};
});
});
http://jsfiddle.net/83s7W/

On mouseover, changing an image's opacity and overlaying text

I want to drop the opacity and overlay text on a thumbnail image when I mouse over it. I have several ideas about how to do it, but I'm fairly certain they're inefficient and clumsy.
Make a duplicate image in Photoshop with the text overlay and reduced opacity. Swap the original out for the duplicate on mouseover.
Use CSS to drop the opacity on mouseover. Use Javascript to toggle visibility of a div containing the overlay text.
The problem I see with 1 is it seems like an unnecessary use of space and bandwidth, and will cause slow load times. With 2, it seems like I'd have to hard-code in the location of each div, which would be a pain to maintain and update. I know this is a somewhat general question, but I'm at a loss about how to go about this. How can I do this relatively simple task in a way that will make it easy to add new thumbnails?
Wrap your image in a <div class="thumb">
Add position: relative to .thumb.
Add <div class="text> inside .thumb.
Add display: none; position: absolute; bottom: 0 to .text.
Use .thumb:hover .text { display: block } to make the text visible on hover.
Like this: http://jsfiddle.net/dYxYs/
You could enhance this with some JavaScript/jQuery: http://jsfiddle.net/dYxYs/1/
$('.text').hide().removeClass('text').addClass('text-js');
$('.thumb').hover(function(){
$(this).find('.text-js').fadeToggle();
});
This way, the basic effect still works without JavaScript, and users with JavaScript get the appealing fade effect.
Go with option 2. There are ways to do it to not have to write a jQuery function for each image. As seen in my jsfiddle.
http://jsfiddle.net/daybreaker/dfJHZ/
HTML
<img src="http://placekitten.com/300/300" />
<span class="text" style="display:none">THIS IS A KITTEN</span>
<br><br>
<img src="http://placekitten.com/200/200" />
<span class="text" style="display:none">THIS IS A KITTEN</span>
jQuery
$('img').mouseover(function(){
$(this).css('opacity','.2');
$(this).next('span.text').show();
}).mouseout(function(){
$(this).css('opacity','1');
$(this).next('span.text').hide();
});
You would need to modify the span.text css to overlay it on top of the image, but that shouldnt be too bad.
Wrap it in an element and do something like this:
var t;
$('div.imgwrap img').hover(function(){
t = $('<div />').text($(this).attr('title')).appendTo($(this).parent());
$(this).fadeTo('fast',0.5);
},function(){
$(this).fadeTo('fast',1);
$(t).remove();
});
with a markup similar to:
<div class="imgwrap">
<img src="http://www.gravatar.com/avatar/3d561d41394ff0d5d0715b2695c3dcf0?s=128&d=identicon&r=PG" title="text" />
</div>
example: http://jsfiddle.net/niklasvh/Wtr9W/
Here's an example. You can position the text however you want, but the basic principle below.
http://jsfiddle.net/Xrvha/
#container { position: relative; }
#container img, #container div {
position: absolute;
width: 128px;
height: 128px;
}
#container img { z-index -1; }
#container div {
z-index 1;
line-height: 128px;
opacity: 0;
text-align: center;
}
#container:hover img {
opacity: 0.35;
}
#container:hover div {
opacity: 1;
}
If you don't want to change your HTML wraping things etc, I suggest you this way. Here is the jQuery:
$(function() {
$(".thumb").mouseenter(function() {
var $t = $(this);
var $d = $("<div>");
$d.addClass("desc").text($t.attr("alt")).css({
width: $t.width(),
height: $t.height() - 20,
top: $t.position().top
});
$t.after($d).fadeTo("fast", 0.3);
$d.mouseleave(function() {
$(this).fadeOut("fast", 0, function() {
$(this).remove();
}).siblings("img.thumb").fadeTo("fast", 1.0);
});
});
});
2 is a good solution, have done about the same as this and it isn't as hard as you would've tought;
Drop de opacity with css indeed, than position a div relative to the img, and over it. It can be done with plain css. The z-index is the trick. That div can just be shown with $('#div').slideUp() ie.

Categories