How to pass click event into setTimeout? - javascript

I have a click event and in that click event I need to use a setTimeOut function, reason is because when I try to show an overlay, it doesn't happen, but when I put it into a function then the remaining functions into a timeout then it works. Its the only solution I can find but the problem is is that the setTimeOut isn't recognizing the click event..If this isn't making much sense, then hopefully the code will speak for itself
function TurnItOn() {
$('#SiteOverlayFullScreen').css('display', 'block');
}
$(document).on('click', '#ddValidation ul li', function (e) {
TurnItOn();
let self = e;
setTimeout(function () {
let selectedItem = e.target.text;
let rightPanelWidth = $('#innerVertical').width();
$('#ddValidation ul li').removeClass('active-font-size');
//$('#SiteOverlayFullScreen').css('display', 'block');
//StartBusyIndicator('#SiteOverlayFullScreen');
switch (selectedItem) {
case 'Quote': {
//StartBusyIndicator('#SiteOverlayFullScreen');
e.currentTarget.classList.add('active-font-size');
$('#innerVertical').addClass('show-validation-window');
$('#ValidationWindow').css({ 'display': 'block', width: rightPanelWidth });
$('#btnSplitScreen').trigger('click');
CheckValidationResultsByRoomsInQuote();
//$('#SiteOverlayFullScreen').css('display', 'none');
} break;
case 'Room': {
e.currentTarget.classList.add('active-font-size');
$('#innerVertical').addClass('show-validation-window');
$('#ValidationWindow').css({ 'display': 'block', width: rightPanelWidth });
$('#btnSplitScreen').trigger('click');
CheckValidationResultsByRoomInQuote();
//$('#SiteOverlayFullScreen').css('display', 'none');
} break;
default: {
e.currentTarget.classList.add('active-font-size');
$('#ValidationWindow').css('display', 'none');
$('#innerVertical').removeClass('show-validation-window');
$('#btnSplitScreen').trigger('click');
ResetValidationErrorLabels();
//$('#SiteOverlayFullScreen').css('display', 'none');
} break;
}
});
});
The error that gets thrown, in any of the case statements, is
Cannot read property 'add' of undefined

try use $(this) instead of e.currentTarget and then addClass eg. $(this).addClass('my-class')

Related

To make certain JS code more important than another (disappear on mouse out)

I know this might be silly but I would like to know if there is a way to realize.
Basically, I would like the dropdown-content element to 'KEEP DISPLAYING' even after 3 secs of mouse moving-out of the parental 'dropbtn' button or element.
E.g. code:
$(function() {
$('#dropbtn').hover(function() {
$('.dropdown-content').css('display', 'block');
}, function() {
// on mouseout:
setTimeout(function(){$('.dropdown-content').css('display', 'none');}, 3000);
});
$('.dropdown-content').hover(function(){
$('.dropdown-content').css('display', 'block');
},function(){
$('.dropdown-content').css('display', 'none');
})
});
Current issue is that setTimeout() function is overriding my desired way on this particular line of JS code:
$('.dropdown-content').css('display', 'block');
In another word, I want setTimeout() to be effective if and only if I set not my mouse cursor on 'dropdown-content' div.
Hope someone can help out :)
Instead of using hover, you could use mouseenter/mouseleave to 'toggle' the .dropdown-content, except the delay of 3s on mouseleave:
$(function() {
var dropdownTimeout = null;
$('#dropbtn').mouseenter(function() {
if(dropdownTimeout) {
clearTimeout(dropdownTimeout);
dropdownTimeout = null;
}
$('.dropdown-content').css('display', 'block');
});
$('#dropbtn').mouseleave(function() {
dropdownTimeout = setTimeout(function(){$('.dropdown-content').css('display', 'none');}, 3000);
});
});

Jquery custom css on odd / even clicks

I want to rotate an object with .css
First click: 180°
Second click: back to normal position (+180°)
Now i need a function, to detect, if the current click is even or odd ...
Tried it with this:
$(function() {
$(".board-element").find(".category div").click(function() {
$(this).parent().parent().find(".board-boards").slideToggle(1000);
var clicks = $(this).data('clicks');
if (clicks) {
$(this).css("transform", "none");
} else {
//first click
$(this).css("transform", "rotate(180deg)");
}
});
});
It works fine, i klick on the element, the object rotates ...
But when i click again, nothing happens ...
I hope you can understand my problem,
Thanks :)
Cleaner approach would be toggling class name so you don't have to deal with click counts:
$(".board-element").find(".category div").click(function() {
$(this).parent().parent().find(".board-boards").slideToggle(1000);
$(this).toggleClass('rotate');
});
CSS:
.rotate {
transform: rotate(180deg);
}
Additional benefit is that if you decide to support vendor prefixes you don't have to change javascript code for this, just extend CSS.
You do not seem to be setting a data('clicks') value anywhere...
$(function() {
$(".board-element").find(".category div").click(function() {
$(this).parent().parent().find(".board-boards").slideToggle(1000);
var clicks = $(this).data('clicks');
// Save the new flag value
$(this).data('click', true);
if (clicks) {
$(this).css("transform", "none");
} else {
//first click
$(this).css("transform", "rotate(180deg)");
}
});
});
Notes:
You should avoid things like .parent().parent() and use closest('.board-element') or similar instead.
#dfsq has posted a cleaner solution. This one was just to explain where you went wrong :)
You could use a trigger variable, that changes its value after animation 2 directions (you have to inizialize it ouside the function):
var already_turned = false;
$(function() {
$(".board-element").find(".category div").click(function() {
$(this).parent().parent().find(".board-boards").slideToggle(1000);
var clicks = $(this).data('clicks');
if (clicks && already_turned) {
$(this).css("transform", "none");
already_turned = false;
} else {
//first click
$(this).css("transform", "rotate(180deg)");
already_turned = true;
}
});
});

jQuery menu does not show/hide

I have a little problem with this jquery code:
If I call the openMenu function, directly, it works, but inside the if it does not.
$(document).ready(function() {
function checkMenu() {
if($(this).find('ul').css('display') == 'none') {
openMenu();
} else {
closeMenu();
}
}
function openMenu() {
$(this).find('ul').css({display: "block"});
}
function closeMenu() {
$(this).find('ul').css({display: "none"});
}
$('ul li:has(ul)').click(checkMenu);
});
You could make it easy on yourself and use toggle()
$('ul li:has(ul)').click(function(){
$(this).find('ul').toggle();
});
http://api.jquery.com/toggle/
why don't you use .toggle() ? such as:
$(this).find('ul').toggle();
Also you can set the toggle speed either using slow, normal, fast:
$(this).find('ul').toggle('fast');
openMenu doesn't know what "this" is referring to. This should work...
$(document).ready(function() {
function checkMenu() {
var me = $(this);
if(me.find('ul').css('display') == 'none') {
openMenu(me);
} else {
closeMenu(me);
}
}
function openMenu(me) {
//this isn't defined..
me.find('ul').css({
display: "block"
});
}
function closeMenu(me) {
me.find('ul').css({
display: "none"
});
}
$('ul li:has(ul)').click(checkMenu);
});
But the others are right. The toggle function would work really well for something like this.

Link style with javascript

I have this code for hiding\showing link depends on state of cBoxoverlay. But when i click to close this item(display:none), and then click again to show it(display:block) my link(#close-news) still not showing.
jQuery(document).click(function () {
if (jQuery("#cBoxOverlay").css("display", "none")) {
jQuery("#close-news").css("display", "none");
} else if (jQuery("#cBoxOverlay").css("display", "block")) {
jQuery("#close-news").css("display", "block");
Where did i make mistake?
try this - no need for if statements. You can just set the #close-news to whatever #cBoxOverLay is
$(document).click(function () {
$("#close-news").css("display", $("#cBoxOverlay").css('display'));
}
Use classes, does a cleaner job.
In case you don't want to use classes, try to use jQuery's toggle, which does basically exactly what you try to achieve: http://api.jquery.com/toggle/
Use is(":visible") to check if the element is visible, and then either show or hide...
jQuery(document).click(function () {
if (jQuery("#cBoxOverlay").is(":visible")) {
jQuery("#close-news").hide();
} else {
jQuery("#close-news").show();
}
});
You can try:
if ($("#cBoxOverlay").css("display") == "none") {
// ...
}
however you can use is method:
if ( $("#cBoxOverlay").is(':hidden')) {
// ...
}
$(document).click(function(){
if ($("#cBoxOverlay").is(":hidden")) { // if #cBoxOverlay is hidden
$("#close-news").hide() // hide the #close-news
} else if ($("#cBoxOverlay").is(":visible")) { // if #cBoxOverlay is visible
$("#close-news").show() // // show the #close-news
}
})
you can remove the the second condition and use else instead as when element is not hidden it is visible, of course.
Try this, based on #Raminson's answer:
$(document).click(function () {
if ($("#cBoxOverlay").is(':hidden')) {
$("#close-news").css("display", "none");
} else{
$("#close-news").css("display", "block");
May be give a try on this one, too:
$(document).click(function(){
$('#close-news').css('display', function(){return $('#cBoxOverlay').css('display');});
});

Jquery switch statement works occasionally

I am quite new to writing my own jquery functions and I find debugging it very difficult as the error messages aren't too helpful when put into google.
I have a navigation menu for page anchors that when each one is clicked the screen scrolls to the anchor, the elements will change color depending on which one and the hover color will also change. Very simple really, I think.
The scrolling always works, the animate works occasionally and the hover works put usually I have to click the link twice. The return false only works on the first link you click.
This uses the scrollTo and animate-colors plugins.
Can anyone tell me what I'm doing wrong?
$(".scrolltoanchor").click(function() {
$('a').removeClass('selected');
$(this).addClass('selected');
$.scrollTo($($(this).attr("href")), {
duration: 750
});
switch ($(this).attr("id")) {
case 'personal':
$('.scrolltoanchor').animate({color: '#E4D8B8'});
$(".scrolltoanchor").hover(
function() {
$(this).css('color', 'blue');
},function(){
$(this).css('color', '#E4D8B8');
});
break;
case 'achievements':
$('.scrolltoanchor').animate({color: '#ffffff'});
$(".scrolltoanchor").hover(
function() {
$(this).css('color', 'red');
},function(){
$(this).css('color', '#ffffff');
});
break;
case 'skills':
$('.scrolltoanchor').animate({color: '#dddddd'});
$(".scrolltoanchor").hover(
function() {
$(this).css('color', 'orange');
},function(){
$(this).css('color', '#ffffff');
});
break;
}
return false;
});
Sorry to ask to be spoonfed, but I have followed what I believed to be the correct syntax from what I have learnt. Is there something I should know that is stopping this working as I expect?
EDIT: Sorry I forgot, I get this error on the (on average) every second click of a scrolltoanchor link
Uncaught TypeError: Cannot read property '0' of undefined
I can't spot a real pattern. Sometimes it seems to happen only on ones that havent been clicked before, sometimes not.
Thanks
You're taking the wrong approach.
You should bind the hover handlers once, and decide the colors based on which one was clicked.
Simplest way would probably to store the color data in a lookup table where the keys are the IDs of the elements.
var ids = {
personal: {
over:'blue',
out:'#E4D8B8'
},
achievements: {
over:'red',
out:'#ffffff'
},
skills: {
over:'orange',
out:'#dddddd'
}
};
var current = ids.personal;
Then bind the handlers once, and use the id of the one clicked to set the current color set.
var scroll_anchors = $(".scrolltoanchor");
scroll_anchors.hover( function() {
$(this).css( 'color', current.over );
},function(){
$(this).css( 'color', current.out );
});
scroll_anchors.click(function() {
$('a.selected').removeClass('selected');
$(this).addClass('selected');
$.scrollTo($($(this).attr("href")), { duration: 750 });
current = ids[ this.id ]; // set the current color set based on the ID
scroll_anchors.animate({ color: current.out });
return false;
});
When you call .hover() multiple times, you aren't removing the old event handlers, you are just adding a new one. Each handler will be called each time. You'll want to call .unbind("hover") first:
$(".scrolltoanchor").unbind("hover").hover(function () {
...
});
You can also bind to hover outside of the switch statement to eliminate some of the code duplication:
$(".scrolltoanchor").click(function () {
$('a').removeClass('selected');
$(this).addClass('selected');
$.scrollTo($(this.href), {
duration: 750
});
var off, on;
switch (this.id) {
case 'personal':
off = '#E4D8B8';
on = 'blue';
break;
case 'achievements':
off = '#ffffff';
on = 'red';
break;
case 'skills':
off = '#dddddd';
on = 'orange';
break;
}
$('.scrolltoanchor')
.animate({ color: off })
.unbind("hover")
.hover(function () {
$(this).css('color', on);
}, function () {
$(this).css('color', off);
});
return false;
});

Categories