jquery click .addClass issue - javascript

Hi i have been having trouble all day with this, it almost works but not quite, i need the corresponding p (#p-1 etc) to stay highlighted once the thumb nail is clicked. I have used a Plug in for an image slider which i have customized slightly and the mouseover and mouseleave events are working fine but the click event doesn't appear to add the class to the target paragraph.
Example on jsfiddle http://jsfiddle.net/RVYnb/7/
The relevant jQuery is written inline on the example.
this is driving me crazy, please help!

The error is in the image slider plugin. It also binds to the click event in the code.
Here's the relevant code part in the plugin:
jQuery("div#thumbSlider" + j + " a").each(function(z) {
jQuery(this).bind("click", function(){
jQuery(this).find("p.tmbrdr").css({borderColor: settings.thumbsActiveBorderColor, opacity: settings.thumbsActiveBorderOpacity});
jQuery(this).parent().parent().find("p.tmbrdr").not(jQuery(this).find("p.tmbrdr")).css({borderColor: settings.thumbsBorderColor, opacity: settings.thumbsBorderOpacity});
var cnt = -(pictWidth*z);
(cnt != container.find("ul").css("left").replace(/px/, "")) ? container.find("span.typo").animate({"opacity": 0}, 250) : null ;
container.find("ul").animate({ left: cnt}, settings.easeTime, settings.easeFunc, function(){container.find("span.typo").animate({"opacity": settings.typoFullOpacity}, 250)});
return false;
});
});
The problem is the "return false" at the end. It stopps the propagation to other click events.
Change the code to the following:
Query(this).bind("click", function(e){
jQuery(this).find("p.tmbrdr").css({borderColor: settings.thumbsActiveBorderColor, opacity: settings.thumbsActiveBorderOpacity});
jQuery(this).parent().parent().find("p.tmbrdr").not(jQuery(this).find("p.tmbrdr")).css({borderColor: settings.thumbsBorderColor, opacity: settings.thumbsBorderOpacity});
var cnt = -(pictWidth*z);
(cnt != container.find("ul").css("left").replace(/px/, "")) ? container.find("span.typo").animate({"opacity": 0}, 250) : null ;
container.find("ul").animate({ left: cnt}, settings.easeTime, settings.easeFunc, function(){container.find("span.typo").animate({"opacity": settings.typoFullOpacity}, 250)});
e.preventDefault();
});
});
and it should work.

It looks to me, according to the "fiddle", that your "click" event isn't working on your thumbnails. It's never adding the "clicked" class to your .
I threw an "alert" into this:
$("#t1").live("click", function() {
alert('clicking');
$("#p-1").addClass("clicked").addClass("highlighted");
});
and the alert never popped.

Related

Faking a toggle switch with an Input Range, dealing with custom range

I need to fake a toggle switch with an input range.
The idea is to create a short range, with just 2 values, min and max. the css button will match one end of the range. So far you click on it, the div containing the range will move a bit bringing the other end of the ranger under your mouse.
I have this function, which applies on all input ranges on the page. But i need to apply it only on some classes, not all. But i can't find the right syntax and it doesn't work.
The Javascript:
$('input[type="range"]').on('change', function() {
$('div#launcher01').css('margin-top', parseInt($(this).val() ) > 0 ? parseInt($(this).val() ) + 'px' : '0px');
});
CSS:
.fakbl input {
height: 50px;
width: 50px;
HTML:
<div id="launcher01">
<div class="fakbl">
<input type="range" id="launch01" name="launch01" min="0" max="50" step="50"" />
</div>
</div>
Fiddle
Since you are already using jQuery, you can phrase your widget-maker as a jQuery plugin as follows :
$.fn.rangeButton = function(containerSelector) {
return this.each(function() {
var $self = $(this);
$self.on('change', function() {
$self.closest(containerSelector).css('margin-left', ($self.val()/3) > 0 ? ($self.val()/3) + 'px' : '0px');
}).trigger('change'); // trigger 'change' immediately to initialize everything.
});
};
Now, invoke the widget on each of your ranges, and pass a selector for the appropriate container :
$('#launcher01 input[type="range"]').rangeButton('#launcher01');
$('#launcher02 input[type="range"]').rangeButton('#launcher02');
Demo
Alternatively, by giving all containers the same class, you can invoke all your widgets with a single command :
$('.myClass input[type="range"]').rangeButton('.myClass');
Demo
May I ask a refinement please?
I completed the fake button. As you can see in this FIDDLE
(the white box will disappear, I added some opacity to it just to show that the button is working)
The red box (now green due to my buggy code part) is in the background and I would need it to change color depending on the status. I tried this but it doesn't work.
Here the code:
$.fn.rangeButton = function(containerSelector) {
return this.each(function() {
var $self = $(this);
$self.on('change', function() {
$self.closest(containerSelector).css('margin-left', ($self.val()/3) > 0 ? ($self.val()/3) + 'px' : '0px');
// this part is not working, if you remove this part, the button works flawlessy
if ($self = 100) {
document.getElementById("fakbuttonsfondo01").style.backgroundColor="rgb(0, 191, 1)";
} else {
document.getElementById("fakbuttonsfondo01").style.backgroundColor="rgb(0, 0, 255)";
}
// end of buggy code
}).trigger('change'); // trigger 'change' immediately to initialize everything.
});
};
$('#launcher01 input[type="range"]').rangeButton('#launcher01');
$('#launcher02 input[type="range"]').rangeButton('#launcher02');
Thanks:)

jquery keeps on selecting element after changing the class

I have a button which must change what it does after meeting some condition.
So I'm selecting the button by it's class and I want to remove that class upon meeting the condition and add a new class to the element and do something else with it. but it's not working.
I just made up an example for my problem.
this is the code:
$('.button-1').click(function(){
$('.box').width(function(){
return $(this).width() + 10;
});
$(this).removeClass('button-1').addClass('button-2');
});
$('.button-2').click(function(){
$('.box').width(function(){
return $(this).width() - 10;
});
$(this).removeClass('button-2').addClass('button-1');
});
and it's Fiddle
I expect this to toggle between increasing and decreasing the black box width, but it keeps on increasing.
That's because the event is bound statically on the button, use event delegation like this:
$(document).on('click','.button-1', function(){
$('.box').width(function(){
return $(this).width() + 10;
});
$(this).removeClass('button-1').addClass('button-2');
});
$(document).on('click','.button-2', function(){
$('.box').width(function(){
return $(this).width() - 10;
});
$(this).removeClass('button-2').addClass('button-1');
});
DEMO
Offcourse you could do it like that...but isn't it easier to add an another variable that checks whether or not there has been a click? The code is much simpler and you can check later on whether or not the box has been enlarged.
This method also seperates style from computing, which is generally regarded as a good idea.
var large = false;
$('body').on('click', '.button', function(){
if (large) {
$('.box').addClass('clicked');
large = false;
} else {
$('.box').removeClass('clicked');
large = true;
}
});
additionally, you need a css class like so:
.clicked {
width: 110px;
}
and I removed that button-1 and button-2 classes, gave the div the class 'button' instead

Use Jquery :visible in an if ( x && y ) statement OR how do I stop mid-animation input?

http://rockforddriveline.com/newrdl/index.html
That is the test website. Its a WIP, don't discuss the design. Just the functionality.
So, I've edited my post, and I've changed my code to the bare minimum to the point to where it works. My issue is that during the transition between the .tile and main, it hides both of them which then displays nothing. I want to be able to make sure that doesn't happen. I have two methods I think that'll solve it. Either by stopping input of the mouse during the animation or use a listener to see when both .m1/2/3/4 and .t1/2/3/4 are :hidden. I don't know how to do either of those.
.stop() did not solve my problem.
var varMainHide = '.m1, .m2, .m3, .m4',
varTileHide = '.t1, .t2, .t3, .t4',
varAllHide = varMainHide + ', ' + varMainHide;
function funcSimpleTransition(fMain, button){
$(button).click(function() {
$(varMainHide).hide();
$('.tile').hide(500);
$(fMain).show(300);
});
$('.overide').click(function() {
$(varMainHide).hide(200);
$('.tile').show();
});
};
function funcMasterScript(){
$(varMainHide).hide();
funcSimpleTransition('.m1', '.t1');
funcSimpleTransition('.m2', '.t2');
funcSimpleTransition('.m3', '.t3');
funcSimpleTransition('.m4', '.t4');
};

Div Transitions - IE vs. others

I have a JSFiddle that displays a series of boxes. If one of the boxes is clicked, it expands to cover the other boxes, then displays text. When the now expanded box is clicked, it retracts to its original width and height. This javascript works flawlessly in Firefox, Chrome, and Safari. However, in Internet Explorer (v10), the box expands but fails to retract. Any Insight on why this may be?
JSFiddle: http://jsfiddle.net/QBdDE/
Javascript:
$('div').on('click', function (e) {
if ($(this).hasClass('clicked')) {
setTimeout(function (div) {
return function () { div.css('z-index', '') ; } ;
} ($(this)), 1000) ;
$('.overlay-text').hide();
}
else {
$(this).css('z-index', 400) ;
setTimeout(function(){$('.overlay-text').show();},1000);
}
$(this).toggleClass('clicked') ;
});
What's Going On
Problem:
pointer-events support was added in IE11. IE10 is ignoring this, and because your overlay is on top, the mouse is interacting with it. We can get around this though!
Solution:
We need to remove dependency on that CSS rule. To do this, we need to do two things:
1.) We need to make the hover color stays applied even if the :hover effect isn't happening. We can add another selector to our CSS so that the .clicked class will cause the colors.
2.) We need to address what happens when .overlay_text is clicked, and use that to trigger the shrinking animation.
Code
1.) Hover Effect
We need to add in another select to every place :hover is used:
Old CSS:
.first_box:hover {
...background color rule ...
}
New CSS:
.first_box:hover, .first_box.clicked {
...background color rule ...
}
Duplicate the above for all 4 box rules.
2.) .overlay-text Trigger
We need to cause a click on .overlay-text to trigger the shrinking.
Old JS:
$('div').on('click', function (e) {
if ($(this).hasClass('clicked')) {
setTimeout(function (div) {
return function () { div.css('z-index', '') ; } ;
} ($(this)), 1000) ;
$('.overlay-text').hide();
}
else {
$(this).css('z-index', 400) ;
setTimeout(function(){$('.overlay-text').show();},1000);
}
$(this).toggleClass('clicked') ;
});
New JS:
We have to add a new selector to the .on() code, then we have to add .clicked to both the selected square, add the overlaying section. Finally we have to remove .clicked from both. We can't use .toggleClass() because we are adding to $(this) and removing from all divs.
$('div, .overlay-text').on('click', function (e) {
if ($(this).hasClass('clicked')) {
setTimeout(function (div) {
return function () { div.css('z-index', '') ; } ;
} ($(this)), 1000) ;
$('.overlay-text').hide();
$('div').removeClass('clicked');
$('.overlay-text').removeClass('clicked');
}
else {
$(this).css('z-index', 400) ;
setTimeout(function(){$('.overlay-text').show();},1000);
$(this).addClass('clicked');
$('.overlay-text').addClass('clicked');
}
});
Summary
I've tested in IE10 and it works.
Working Example:
Extra
If I may say, the CSS structure you are using could be improved and your animations will look a lot better. Chrome and IE both flicker during the animation of the two left blocks.
This is because their width AND position is being animated. If you position them from right:0, only their width will animate and it'll look a lot smoother.
I've created a Fiddle for you to address the above. I used absolute positioning. The CSS ends up being shorter, but mainly the animation doesn't flicker. Take a look:
Working Example:
Extra 2
As per comments from OP, we are going to prevent users from double clicking. Since all animations take 1 second, we will disable clicking from triggering anything for 1 second after each click.
It's actually pretty simple to do. In the Extra 1 above, we cleaned up the JS, and it became this:
$('div, .overlay-text').on('click', function (e) {
if ($(this).hasClass('clicked')) {
$('.overlay-text').hide();
$('div').removeClass('clicked');
$('.overlay-text').removeClass('clicked');
}
else {
setTimeout(function(){$('.overlay-text').show();},1000);
$(this).addClass('clicked');
$('.overlay-text').addClass('clicked');
}
});
We just need to add a global variable that starts true. When once the click happens, set it to false immediately, and after 1 second, set it to true. Then we just check to see if it's true, and don't do anything at all if it's false:
var notdouble = 1;
$('div, .overlay-text').on('click', function (e) {
if (notdouble) {
if ($(this).hasClass('clicked')) {
$('.overlay-text').hide();
$('div').removeClass('clicked');
$('.overlay-text').removeClass('clicked');
}
else {
setTimeout(function(){$('.overlay-text').show();},1000);
$(this).addClass('clicked');
$('.overlay-text').addClass('clicked');
}
notdouble=0;
setTimeout(function(){notdouble=1;},1000);
}
});
Working Example:
Note, this builds from the new structure in the Fiddle version 13, so it won't work exactly with the fixed version of the original structure. The concept can be adapted though.
Not working in IE 9 as the div click event never fires. I think it's covered by the section with class="overlay-text". But I've got a workaround by handling the click event of the section and triggering the div click event
$('section').on('click', function (e) {
$('.overlay-text').hide();
$( "div" ).addClass('clicked') ;
$( "div" ).trigger( "click" );
});

Jquery toggleClass issue

initially hovering works and the "over" class is added on mouseenter and removed on mouseout, but after doing some hovering over paragraphs with class="risk" the toggle class becomes stuck, and mouseover removes it instead of adding the class (opposite of expected functionality)
//changes risk map point color when hovering over
// risk list item on right hand side
$("p.risk").bind("mouseenter mouseleave", function(e){
$(this).toggleClass("over");
var pointId= "ctl00_ContentPlaceHolderMain_" + $(this).attr("id");
var pointArray = $(".riskMapPoint");
for(i=0; i<pointArray.length; i++){
if( $(pointArray[i]).attr("id") == pointId )
{
$(pointArray[i]).css({'background-color' : '#3D698A'});
$(pointArray[i]).css({'z-index' : '2'});
}
else
{
$(pointArray[i]).css({'background-color' : '#000000'});
$(pointArray[i]).css({'z-index' : '1'});
}
}
});
Why not simply use the hover method? Set the background/z-index of the associated point on hover and remove it when leaving the element.
$('p.risk').hover(
function() {
var $this = $(this);
$this.addClass('over');
$('.riskMapPoint')
.find('[id$=' + $this.attr('id') + ']')
.css({ 'background-color' : '#3D698A', 'z-index' : 2 } );
},
function() {
var $this = $(this);
$this.removeClass('over');
$('.riskMapPoint')
.find('[id$=' + $this.attr('id') + ']')
.css({ 'background-color' : '#000000', 'z-index' : 1 } );
}
});
Why not have two separate functions for mouseenter and mouseleave. Have mouseenter add the class and mouseleave remove the class. I think the problem is that if for example the mouseleave event is not fired (browser looses focus I think can cause this) then the mouseenter function will remove the class instead of adding it.
Try not to change css values in code but instead use jquery to addClass and removeClass. I had a hover problem a couple months ago and applying css classes instead of manually changing values fixed my problem.

Categories