jquery .show() .hide() puzzle - javascript

I'm writing a simple jquery animation to show/hide a block of stuff when the title is clicked.
The markup looks like this:
<section class="infoblock off">
<h2><span class="sectiontitle rounded-right">TITLE (click to show/hide)</span></h2>
<div class="info"></div><!--info-->
</section>
My javascript looks like this:
$(".infoblock h2").click( function(event) {
//console.log('show info');
if ( $(this).parent( $('.infoblock') ).hasClass('off') ) {
$(this).parent( $('.infoblock') ).removeClass('off');
$(this).parent( $('.infoblock') ).addClass('on').children( $('.info') ).show(300);
console.log( 'On function. Parent class= '+$(this).parent( $('.infoblock') ).attr('class') );
} else if ( $(this).parent( $('.infoblock') ).hasClass('on') ) {
$(this).parent( $('.infoblock') ).removeClass('on');
$(this).parent( $('.infoblock') ).addClass('off');
$(this).parent( $('.infoblock') ).children( $('.info') ).hide(300);
console.log( 'Off function. Parent class= '+$(this).parent( $('.infoblock') ).attr('class') );
}
});
This works BUT when I click the title the second time to hide the .info <div> the title gets hidden as well. WHY?!

I think you are confused about how to specify selectors. For example, where you have
$(this).parent( $('.infoblock') ).hasClass('off')
I think you want
$(this).parent('.infoblock').hasClass('off')
Here is a working example

demo : http://jsfiddle.net/RQ2Cw/1/
instead of parent use closest, and instead ofchildren use find
$(".infoblock h2").click(function(event) {
//console.log('show info');
if ($(this).closest('.infoblock').hasClass('off')) {
$(this).closest('.infoblock').removeClass('off');
$(this).closest('.infoblock').addClass('on').find('.info').show(300);
console.log('On function. Parent class= ' + $(this).closest('.infoblock').attr('class'));
} else if ($(this).parent('.infoblock').hasClass('on')) {
$(this).closest('.infoblock').removeClass('on');
$(this).closest('.infoblock').addClass('off');
$(this).closest('.infoblock').find('.info').hide(300);
console.log('Off function. Parent class= ' + $(this).closest('.infoblock').attr('class'));
}
});​
or :
$(".infoblock h2").click(function(event) {
var _parent = $(this).closest('.infoblock');
if (_parent.hasClass('off')) {
_parent.removeClass('off').addClass('on').find('.info').show(300);
} else if (_parent.hasClass('on')) {
_parent.removeClass('on').addClass('off').find('.info').hide(300);
}
});​

If you don't use the 'info' class anywhere else, you could use it directly as a selector:
$('.info').show(300)
$('.info').hide(300)
If you do use the class somewhere else, you could give it an ID <div id="info" class="info"></div> and select it using $('#info')
Also, if the condition only purpose is to switch between hide() and show() (if there is no css associated with the classes), try using the toggle() function.

Store a reference to the parent element and make use of jQuery's function chaining, like this:
$(".infoblock h2").click( function(event) {
//console.log('show info');
var $parent = $(this).parent('.infoblock');
$parent.toggleClass("off").toggleClass("on").children($('.info')).toggle(300);
if ($parent.hasClass('on')) {
console.log( 'On function. Parent class= '+$parent.attr('class'));
} else if ($parent.hasClass('off')) {
console.log( 'Off function. Parent class= '+$parent.attr('class'));
}
});

You can do this in two lines:
$( '.infoblock' ).on( 'click', 'h2', function () {
var $elem = $( this ).closest( '.infoblock' ).toggleClass( 'on off' );
$elem.find( '.info' )[ $elem.hasClass( 'on' ) ? 'show' : 'hide' ]( 300 );
});
Live demo: http://jsfiddle.net/dpdvg/1/

Related

Conditionally add class to element based on other element status/class

I'm trying to hide an image after I scroll down my page. When scrolling my header gets a class fl-theme-builder-header-scrolled. My image div has a class hiding-image and I want to add a class image-off when the fl-theme-builder-header-scrolled class shows up in the header.
This is what I have:
$(document).ready(function() {
if($( 'header' ).hasClass( 'fl-theme-builder-header-scrolled' )) {
$( '.hiding-image' ).toggleClass( 'image-off' );
}
});
but this doesn't work. Any advice? Thx.
Your code only runs once after the document ready, as soon as the page loads. So if the header doesn't have the fl-theme-builder-header-scrolled class and only gets added later, your code will not run again.
You need a a mutation Observer.
Check this thread: Event trigger on a class change
Alternatively you can do as #Brewal is saying, putting the code evaluation on the scroll event. Although be careful so you don't run the code every time the scroll event is triggered since it can slow your website performance, specially on mobile devices.
Try something like this.
$(window).scroll(function() {
if($( 'header' ).hasClass( 'fl-theme-builder-header-scrolled' )) {
$( '.hiding-image' ).toggleClass( 'image-off' );
}
});
As pointed out in the comments, I think the best approach would be to find where the fl-theme-builder-header-scrolled class is already being controlled.
However, If you really would want to put the logic in a separate area, you can do it like this:
$(document).ready(function () {
$(window).scroll(function () { //attach to window scroll event
if ($('header').hasClass('fl-theme-builder-header-scrolled') && !$('.hiding-image').hasClass('image-off')) {
$('.hiding-image').addClass('image-off'); //add class only if it does not already exist;
} else {
if ($('.hiding-image').hasClass('image-off')) {
$('.hiding-image').removeClass('image-off'); //remove class
}
}
});
});
Check condition like this:
`$(window).scroll(function() {
if($( 'header' ).hasClass( 'fl-theme-builder-header-scrolled' ))
{
$( '.hiding-image' ).addClass( 'image-off' );
}
else
{
$( '.hiding-image' ).removeClass( 'image-off' );
}
});`
I finally managed to make it work doing this:
(function($){
$(function(){
var headerThemer = $( '.fl-builder-content[data-type=header]' ).eq(0);
$(window).on( 'scroll.fl-theme-builder-header-scrolled', function(){
if ( headerThemer.hasClass('fl-theme-builder-header-scrolled') ) {
$('.hiding-image').hide();
}
else {
$('.hiding-image').show();
}
});
})
})(jQuery);

Retrieving jQuery data from dynamic HTML element returns undefined

I am trying to retrieve data from a variable HTML element. On click, the id of the <span> element is retrieved, which I want to enable me to dynamically $([dynamic id]) select that element and request the data stored in the data attribute.
My jQuery looks like this:
$( document ).ready( function() {
$( ".checkmark" ).on( "click", ( event ) => {
let checkBoxId = "#" + event.target.id, // #checkBox1
checkBoxData = event.target.id + "-value", // checkBox1-value
checkBoxValue = $( checkBoxId ).data( checkBoxData ); // undefined
} );
} );
The HTML element targeted looks like this:
<span class="checkmark" id="checkBox1" data-checkBox1-value=-155></span>
The value of let checkBoxValue is undefined and I cannot figure out why.
Help would be greatly appreciated.
You can get attribute value of span using attr() function in jQuery
checkBoxValue = $(checkBoxId).attr(checkBoxData);
The checkBoxId variable is unnecessary because you can use the this keyword since it is the current element you are working with.
$(function() {
$(".checkmark").on("click", (event) => {
let checkBoxData = event.target.id + "-value";
let checkBoxValue = $(this).data(checkBoxData);
});
});
It seems you are having scope issues with the new ()=>{} syntax.
So, you will need to bind this to the function event handler using {self:this}. If you don't want to do this, you can use the old function(){} syntax instead.
$( document ).ready( function() {
$( ".checkmark" ).on( "click", {self:this}, ( event ) => {
var checkBoxValue = $(this).data("checkbox1-value")
alert(checkBoxValue);
} );
} );
And also as #Erwin mentioned, use only lowercase in your data- attribute name:
<span class="checkmark" id="checkbox1" data-checkbox1-value="-155"></span>
JsFiddle
It's returning undefined because it is declared incorrectly. The part after data- should be in lower case. In your case, it must be
<span class="checkmark" id="checkbox1" data-checkbox1-value=-155></span>
for the .data() to work.
this code works for me try it ;)
$( document ).ready( function() {
$( ".checkmark" ).on( "click", function() {
var checkBoxId = "#" + $(this).attr('id');
var checkBoxData = $(this).attr('id') + "-value";
$( this ).attr('data-'+ checkBoxData, 155 );
} );
});
jsfiddle link

$(document).on("click",".class_name",function() not working

Here is the HTML
<div id="menu" class='rmm' data-menu-title="Description">
<ul>
<li>Description</li>
<li>Features</li>
<li>Ratings</li>
<li>Activate</li>
</ul>
</div>
jquery portion to change menu title
function getMobileMenu() {
/* build toggled dropdown menu list */
$('.rmm').each(function() {
var menutitle = $(this).attr("data-menu-title");
if ( menutitle == "" ) {
menutitle = "Menu";
}
else if ( menutitle == undefined ) {
menutitle = "Menu";
}
var $menulist = $(this).children('.rmm-main-list').html();
var $menucontrols ="<div class='rmm-toggled-controls'><div class='rmm-toggled-title'>" + menutitle + "</div><div class='rmm-button'><span> </span><span> </span><span> </span></div></div>";
$(this).prepend("<div class='rmm-toggled rmm-closed'>"+$menucontrols+"<ul>"+$menulist+"</ul></div>");
});
}
I just want the menu title to be changed when I click the menu.
I tried the below but it won't work
$(document).on("click",".rmm_li_item",function()
var ctxt=this.innerHTML;
$(".rmm-toggled-title").text(ctxt);
})
complete design : responsivemobilemenu.com/en/
the code may syntax error you have missed callback function stating braket {, try this code
$(document).on("click",".rmm_li_item",function(e){
e.preventDefault();
var ctxt=this.innerHTML;
$(".rmm-toggled-title").text(ctxt);
})
Although add e.preventDefault() to stop reloading page
There seems to be some error in your on Click event.General syntax is for onClick event is
$( "#target" ).click(function() {
alert( "Handler for .click() called." );
});
According to the question is this what you need?
$(document).on("click",".rmm_li_item",function(e){
e.preventDefault()
var ctxt=this.innerHTML;
$(".rmm").text(ctxt);
})
IF not please make a JSFIDDLE and share the link I could not comprehend what you said

How to fade in closest image?

I tried writing a small script to Fadein the closest image using jQuery but for some reasons this code is not working. Can anyone help me with the syntax? Thanks
$( ".delimg" ).click(function() {
$(this).closest( "img" ).fadeTo( "slow" , 0.5, function() {
$("input[type='button']").toggle(
function(){
$(this).val("Undelete");
},
function(){
$(this).val("Delete");
}
);
});
});
HTML
<div class="swiper-slide">
<img src="http://20percents.com/backend/uploads/C0d49a7de7b635477125ffffa8df7b931.jpg" class="swipe-image">
<center><input type="button" class="delimg" value="Delete"></center>
</div>
<div class="swiper-slide">
<img src="http://20percents.com/backend/uploads/C0d49a7de7b635477125ffffa8df7b932.jpg" class="swipe-image">
<center><input type="button" class="delimg" value="Delete"></center>
</div>
Fiddle: http://jsfiddle.net/e27r8/597/
The img element is not a direct parent of the button which is clicked. You need to use closest to get the containing div, then search for the image within that. Try this:
$(".delimg").click(function () {
$(this).closest(".swiper-slide").find('img').fadeTo("slow", 0.5);
});
Updated fiddle
Also, note that toggle can no longer be used in the manner you are. It will only show/hide elements now, not run specific functions on successive clicks.
To change the text of the button as required, you can pass a function to val() like this:
$(".delimg").click(function () {
var $button = $(this);
$button.closest(".swiper-slide").find('img').fadeTo("slow", 0.5, function() {
$button.val(function(i, value) {
return value == "Delete" ? "Undelete" : "Delete";
});
});
});
Example fiddle
As img is not parent of input so,you have to do this way:
$(this).closest(".swiper-slide").find("img")
You have to get parent div with class swiper-slide and then get img from inside it.
It's not an ancestor, so you need to traverse -
$(this).closest( ".swiper-slide" ).find("img").fadeTo( "slow" , 0.5, function() {
you should go up one level, and then find
$(...).parent().find(...);
$( ".delimg" ).click(function() {
$(this).parent().find( "img" ).fadeTo( "slow" , 0.5, function() {
$("input[type='button']").toggle(
function(){
$(this).val("Undelete");
},
function(){
$(this).val("Delete");
}
);
});
});
edit
i missed <center> tag
use .parent().parent()

how to make the child div not alert something when i only defined the parent div's click function

this is my code:
<div id="a" style="position:absolute;width:200px;height:200px;background:red;word-wrap:break-word;">
<div id="b" style="width:50px;height:50px;background:blue;"></div>
</div>
the script is :
$( "#b" ).draggable({ containment: 'parent' });
$('#a').click(function(e){
alert(e.pageX)
//return false;
})
i want to alert when i click the red div , not the blue div ,
the demo is here :http://jsfiddle.net/KwYjr/2/
thanks
Test the e.target for its ID.
Example: http://jsfiddle.net/patrick_dw/KwYjr/6/
$('#a').click(function(e){
if( e.target.id === 'a' ) {
alert(e.pageX);
}
//return false;
});
Another option would be to add a click handler to your #b element that calls e.stopPropagation(), but I wouldn't recommend it. There are better ways to go (like the one above) than to assign a handler just for the purpose of stopping propagation.
EDIT:
Another way to run the test above, would be to do a direct comparison of the elements, instead of using its ID:
Example: http://jsfiddle.net/patrick_dw/KwYjr/8/
if( e.target === this ) {
alert(e.pageX);
}
If you use event.stopPropagation() like this it works:
$( "#b" ).draggable({ containment: 'parent' }).click(function(e){ e.stopPropagation(); });
$('#a').click(function(e){
alert(e.pageX);
})
use
event.preventDefault()
http://api.jquery.com/event.preventDefault/
e.preventDefault();
e.stopPropagate();

Categories

Resources