Click not recognized on element with dynamically added class - javascript

I have the following javascript object:
TeamExpand = {
trigger: '.team-info h2.initial',
container: '.team-info',
closeTrigger: '.team-info h2.expanded',
init: function() {
jQuery(this.trigger).click(this.expandInfo.bind(this));
jQuery(this.closeTrigger).click(this.closeInfo.bind(this));
},
expandInfo: function(e) {
jQuery(e.currentTarget).closest('.team-info').css("height", "100%");
jQuery(e.currentTarget).removeClass("initial");
jQuery(e.currentTarget).addClass("expanded");
jQuery(this.socialSVG).attr("fill", "#ffc40c");
},
closeInfo: function(e) {
jQuery(e.currentTarget).closest('.team-info').css("height", "64px");
jQuery(e.currentTarget).removeClass("expanded");
jQuery(e.currentTarget).addClass("initial");
jQuery(this.socialSVG).attr("fill", "white");
}
}
My html is as follow:
<div class="team-info">
<h2 class="initial">Header</h2>
<h3>Job Title</h3>
<p>Bio</p>
</div><!--end team-info-->
The 'expandInfo' function is running just fine and changed the 'container' height to 100%; The 'initial' class is removed from the h2 and the 'expanded' class is added to the h2. But the click event on the 'closeTrigger' variable (the h2.expanded) element is not registering. What am I doing wrong?

I'd rewrite this a bit to make the event handlers simpler. Use one handler for all the h2 and just check the class. This way you avoid attaching detaching handlers.
TeamExpand = {
trigger: '.team-info h2',
container: '.team-info',
init: function() {
jQuery(this.trigger).click(this.doTriger.bind(this));
},
doTriger: function(e) {
var element = jQuery(e.currentTarget);
if (element.hasClass('initial')) {
this.expandInfo(element);
} else {
this.closeInfo(element);
}
},
expandInfo: function(element) {
element.closest('.team-info').css("height", "100%");
element.removeClass("initial");
element.addClass("expanded");
jQuery(this.socialSVG).attr("fill", "#ffc40c");
},
closeInfo: function(element) {
element.closest('.team-info').css("height", "64px");
element.removeClass("expanded");
element.addClass("initial");
jQuery(this.socialSVG).attr("fill", "white");
}
}

I think it's because you're applying the click event function to an element that doesn't actually exist (the h2 element doesn't yet have the .expanded class).
Try moving this line of code..
jQuery(this.closeTrigger).click(this.closeInfo.bind(this));
..to the end of your expandInfo function, and add this..
jQuery(this.closeTrigger).unbind('click');
..to your closeInfo function before this line..
jQuery(e.currentTarget).removeClass("expanded");
Hope this helps!
Full code..
TeamExpand = {
trigger: '.team-info h2.initial',
container: '.team-info',
closeTrigger: '.team-info h2.expanded',
init: function() {
jQuery(this.trigger).click(this.expandInfo.bind(this));
},
expandInfo: function(e) {
jQuery(e.currentTarget).closest('.team-info').css("height", "100%");
jQuery(e.currentTarget).removeClass("initial");
jQuery(this.trigger).unbind('click');
jQuery(e.currentTarget).addClass("expanded");
jQuery(this.socialSVG).attr("fill", "#ffc40c");
jQuery(this.closeTrigger).click(this.closeInfo.bind(this));
},
closeInfo: function(e) {
jQuery(e.currentTarget).closest('.team-info').css("height", "64px");
jQuery(this.closeTrigger).unbind('click');
jQuery(e.currentTarget).removeClass("expanded");
jQuery(e.currentTarget).addClass("initial");
jQuery(this.socialSVG).attr("fill", "white");
this.init();
}
}

Related

How do I write the jQuery in this code more efficient?

I have a basic todo list, with which I can click on the li element to toggle the .completed css class on and off. Besides when I click on the X, which is covered in a span inside the li, I can remove the li. Everything works fine, but my IDE told me I had a duplicated jQuery selector, which is $("ul"). How can I write this jQuery more efficiently?
// check off specific todo by clicking
$("ul").on("click", "li", function () {
$(this).toggleClass("completed");
});
// click on X to delete todo
$("ul").on("click", "span", function (event) {
// remove li
$(this).parent().fadeOut(500, function () {
$(this).remove();
});
// prevent event from affecting parents element
event.stopPropagation();
});
ul {
list-style: none;
}
.completed {
color: grey;
text-decoration: line-through;
}
#container {
width: 100px;
margin: 0 auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<ul>
<li><span>X</span> Code</li>
<li><span>X</span> Sleep</li>
<li><span>X</span> Eat</li>
<li><span>X</span> Run</li>
<li><span>X</span> Jump</li>
</ul>
</div>
The simplest thing to do is use chaining:
$("ul").on("click", "li", function () {
$(this).toggleClass("completed");
})
// click on X to delete todo
.on("click", "span", function (event) {
// remove li
$(this).parent().fadeOut(500, function () {
$(this).remove();
});
// prevent event from affecting parents element
event.stopPropagation();
});
The first call to .on() will return the jQuery object you constructed with the initial $("ul"). Thus, you can immediately make another call to .on().
In this particular case, the redundant $("ul") probably isn't that big of a problem, but it's good to get into the habit of minimizing your DOM lookups.
Alternatively, you can always just stash the jQuery object in a variable:
var $ul = $("ul");
// check off specific todo by clicking
$ul.on("click", "li", function () {
$(this).toggleClass("completed");
});
// click on X to delete todo
$ul.on("click", "span", function (event) {
// remove li
$(this).parent().fadeOut(500, function () {
$(this).remove();
});
// prevent event from affecting parents element
event.stopPropagation();
});
you can chain the methods together or store a reference to the selector object:
$("ul").on("click", "li", function () {
$(this).toggleClass("completed");
}).on("click", "span", function (event) {
// remove li
$(this).parent().fadeOut(500, function () {
$(this).remove();
});
// prevent event from affecting parents element
event.stopPropagation();
});
Or
var $ul = $("ul");
$ul.on("click", "li", function () {
$(this).toggleClass("completed");
});
$ul.on("click", "span", function (event) {
// remove li
$(this).parent().fadeOut(500, function () {
$(this).remove();
});
// prevent event from affecting parents element
event.stopPropagation();
});
Do chaining. jQuery is design to be used like that.
$("ul").on("click", "li", function () {
$(this).toggleClass("completed");
}).on("click", "span", function (event) {
// remove li
$(this).parent().fadeOut(500, function () {
$(this).remove();
});
// prevent event from affecting parents element
event.stopPropagation();
});

toggle text while dynamically animating div height

I have a fixed div height with some text that overflows. I've set the overflow to hidden and want to expand the div height to display the rest of text inside if a link is pressed; then return the div to its initial height when the link is pressed again. I came across the following question which is what I want, however their text is broken up into 2 p tags whereas I only have one. I tried this but I get the following error:
Unable to get property 'scrollHeight' of undefined or null reference
Here is my code
Any help would be appreciated.
the problem was getting the element..
check the result
$(function() {
if ($('#dialog-box').is(':visible')) {
showMoreTextDialog();
}
function showMoreTextDialog() {
var dialog_txt = $('.dialog_middle p').html();
if (dialog_txt.length > 350) {
var append_dialog = dialog_txt.substr(0, 350);
$('.dialog_middle p')
.html(append_dialog)
.append('<span class="showMore"> (.... Show More )</span>');
$('.dialog_middle')
.data("original-height", $(".dialog_middle")[0].scrollHeight);
$(document).on({
'mouseover': function() {
$(this).css('cursor', 'pointer');
},
'click': function() {
$('.dialog_middle p')
.html(dialog_txt)
.append('<span class="showLess"> (.... Show Less )</span>');
$('.dialog_middle')
.animate({
height: $(".dialog_middle")[0].scrollHeight
}, 2000);
}
}, '.dialog_middle .showMore');
$(document).on({
'mouseover': function() {
$(this).css('cursor', 'pointer');
},
'click': function() {
$('.dialog_middle')
.animate({
height: $(".dialog_middle").data("original-height")
}, 2000, function() {
$('.dialog_middle p')
.html(append_dialog)
.append('<span class="showMore"> (.... Show More )</span>');
});
}
}, '.dialog_middle .showLess');
}
}
});

mouseIsOver() is not working

I want to change margin of one tag when mouse is hovered on its parent.
mouseIsOver() method doesn't making any change.
function der(){
if($(".experience-div li").mouseIsOver()){
$(".star").css('margin-right','10px');
}
}
der();
I changed it to is() method, still nothing has changed.
>
function der(){
if($(".experience-div li").is(":hover")){
$(".star").css('margin-right','10px');
}
}
der();
There is no mouseIsOver function in jQuery or the DOM.
You can use jQuery's hover:
function der(){
$(".experience-div li").hover(
function() {
$(".star").css('margin-right','10px');
},
function() {
$(".star").css('margin-right','auto'); // Or whatever it should be when not hovered
}
);
}
der();
I wouldn't recommend manipulating the style directly like that, though, I'd use a class:
function der(){
$(".experience-div li").hover(
function() {
$(".star").addClass('hovered');
},
function() {
$(".star").removeClass('hovered')
}
);
}
der();
With
.star.hovered {
margin-right: 10px;
}
Live Example:
function der() {
$(".experience-div li").hover(
function() {
$(".star").addClass('hovered');
},
function() {
$(".star").removeClass('hovered')
}
);
}
der();
.star.hovered {
margin-right: 10px;
color: red;
}
<div class="star">I'm the star</div>
<div class="experience-div">
<ul>
<li>Hover me</li>
</ul>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
To listen to events (such as mouseover) in jQuery you need to use the .on function:
$(".experience-div")
.on('mouseenter', 'li', function () {
$(".star").css('margin-right', '10px');
})
.on('mouseleave', 'li', function () {
$(".star").css('margin-right', '0');
});
You don't need to use JS to complete this. you simply need to add a :hover state to the class in question.

JQuery Tooltip Not Allowing Button to be Clicked

I'm using JQuery tooltip plugin and I'm trying to simulate a input button on hover, which it does successfully but I cannot click on said button. It's like it never exists in the DOM, or maybe it does but then is instantly removed. I'm not sure why the click is not binding.
http://jsfiddle.net/BgDxs/126/
$("[title]").bind("mouseleave", function (event) {
var evt = event ? event : window.event;
var target = $(evt.srcElement || evt.target);
evt.stopImmediatePropagation();
var fixed = setTimeout(
function () {
target.tooltip("close");
}, 200);
$(".ui-tooltip").hover(
function () { clearTimeout(fixed); },
function () { target.tooltip("close"); }
);
});
$("[title]").tooltip({
content: "...wait...",
position: { my: "left top", at: "right center" },
open: function (event, ui) {
var _elem = ui.tooltip;
window.setTimeout(
function() {
var html = "<input type='button' value='Card Information' class='card_info_popup'></input>";
_elem.find(".ui-tooltip-content").html(html);
},
200);
},
track: false,
show: 100
});
$('.card_info_popup').on('click', '.container', function() {
alert('click');
});
You're using event delegation wrongly here since .container is not the child of your input with class card_info_popup, so you need to use:
$('body').on('click', '.card_info_popup', function() {
alert('click');
});
instead of:
$('.card_info_popup').on('click', '.container', function() {
alert('click');
});
Updated Fiddle
change:
$('.card_info_popup').on('click', '.container', function() {
alert('click');
});
to
$(document).on('click', '.card_info_popup', function() {
alert('click');
});
Updated Fiddle
Try this.
You have to use event delegation to enable the click event on the newly created tooltip button
http://learn.jquery.com/events/event-delegation/
$(document).on('click', '.card_info_popup', function() {
alert('click');
});
You have to delegate on('click'); to a static element then bind it to the dynamically generated popup.
I have updated your fiddle: http://jsfiddle.net/BgDxs/130/
Here is the updated code:
$('body').on('click', '.ui-tooltip input.card_info_popup', function() {
alert('click');
});

changing class of li dynamically after hovering

Hi I was wondering if there was anyway to dynamically change the class of a list when you hover over it. Here is my code and fiddle. When I hover over the li I want it to change the class. and on mouseout I want it to change back to original.
$('.navi > li').on("mouseover", function () {
($(this)).removeClass('.navi').addClass('.navi2');
$('.hover-name', this).show();
}).on("mouseout", function() {
$('.hover-name').hide();
});
http://jsfiddle.net/Samfr/8/
I think hover might be a little better for what you are doing.
http://api.jquery.com/hover/
Also, I'm not too clear on what you are asking but one of the examples on the above hover documentation page seems to describe something similar.
$( "td" ).hover(
function() {
$( this ).addClass( "hover" );
}, function() {
$( this ).removeClass( "hover" );
}
);
You had an extra period when adding and removing the class. Those should only be used to select the elements not change the class name.
$('.navi > li').on("mouseover", function () {
($(this)).removeClass('navi').addClass('navi2');
$('.hover-name', this).show();
}).on("mouseout", function() {
$('.hover-name').hide();
});
try this:
define a new class, for example dinamic-li
$('.dinamic-li').on("mouseenter", function () {
$(this).addclass('navi');
$(this).removeclass('navi2');
});
$('.dinamic-li').on("mouseleave", function () {
$(this).addclass('navi2');
$(this).removeclass('navi');
});
Will this work?
JSFiddle
Jquery:
$('.navi > li').on("mouseover", function () {
$('.hover-name', this).show();
$(this).attr('class', 'red');
}).on("mouseout", function() {
$('.hover-name').hide();
$(this).attr('class', '');
});
there is my solution:
$('.navi > li').on("mouseover", function () {
$(this).addClass('active').siblings().removeClass(active);
$('.hover-name', this).show();
}).on("mouseout", function() {
if( $(this).hasClass('active'))
$(this).removeClass('active');
$('.hover-name').hide();
});
Working fiddle
Why not use a CSS solution, it's much easier:
.hover-name { display: none; }
.navi li:hover .hover-name { display: block; }
Check your updated Fiddle
http://jsfiddle.net/Samfr/14/
This is that what u mean...
$('.navi > li').on("mouseover", function () {
$(this).removeClass('navi').addClass('navi2');
$('.hover-name', this).show();
}).on("mouseout", function() {
$('.hover-name').hide();
$(this).removeClass('navi2').addClass('navi');
});
When you hover a link the color will be red and when you mouseout the color will reset.
That way you can see how the script works!

Categories