I want the div to fadeOut(), then when it's not visible to change the color and text, and then but only then, reappear.
Here's the code
var changeColor = function() {
var div = document.getElementById("div");
var p = document.getElementById("p");
var pText = p.innerHTML;
if (pText == "Click Me!") {
$(document).ready(function() {
$("#div").fadeToggle("fast");
}, function() {
$("#div").css("background-color", "aquamarine");
p.innerHTML = "More!";
}, function() {
$("#div").fadeToggle("fast");
});
} else if (pText == "More!") {
$(document).ready(function() {
$("#div").fadeToggle("fast");
}, function() {
$("#div").css("background-color", "coral");
p.innerHTML = "Click Me!";
}, function() {
$("#div").fadeToggle("fast");
});
} else {
return;
}
}
This is the link to codepen.io, the project My Project
DEMO - Change the javascript to the following:
var changeColor = function() {
var div = document.getElementById("div");
var p = document.getElementById("p");
var pText = p.innerHTML;
if (pText == "Click Me!") {
$("#div").fadeToggle("fast", function(){
$("#div").css("background-color", "aquamarine");
$("#div").fadeToggle("slow");
p.innerHTML = "More!";
});
} else if (pText == "More!") {
$("#div").fadeOut("fast", function(){
$("#div").css("background-color", "color");
$("#div").fadeIn("fast");
});
} else {
return;
}
}
Explanation:
Functions like fadeToggle can take a callback function which triggers after the animation is complete:
$("#div").fadeOut("fast", function(){
/*code here will trigger after animation is complete*/
});
Related
I would like to stop the following "Slideshow with setTimeout" by mouseover of elements with the class ".imageWrapper" - start by mouseout. Thank you all for your help!
Here's the script:
let showNextPictureGalleryImageTimeout;
$(document).on("click", ".picture-gallery .images img", function() {
clearTimeout(showNextPictureGalleryImageTimeout);
const pictureGallery = $(this).closest(".picture-gallery");
const images = $('.images', pictureGallery);
const activeImage = $(this);
$('img', images).removeClass('active');
activeImage.addClass('active');
$(".title", pictureGallery).html("");
const currentActiveImage = $(".fullshow img", pictureGallery);
if(currentActiveImage.length === 0) {
$(".fullshow", pictureGallery).append(activeImage.clone());
$(".title", pictureGallery).html(activeImage.attr("title"));
} else {
currentActiveImage.fadeTo(400,0.30, function() {
currentActiveImage.attr("src", activeImage.attr("src"));
currentActiveImage.attr("title", activeImage.attr("title"));
}).fadeTo(400,1, function() {
$(".title", pictureGallery).html(activeImage.attr("title"));
});
}
showNextPictureGalleryImageTimeout = setTimeout(function() {
let nextActiveImage = $('img', activeImage.closest('.imageWrapper').next());
if(nextActiveImage.length === 0) {
nextActiveImage = $('img', $('.imageWrapper', pictureGallery).first());
}
nextActiveImage.trigger('click');
}, 8000);
});
I tried this code:
let showNextPictureGalleryImageTimeout;
$(document).on("click", ".picture-gallery .images img", function() {
clearTimeout(showNextPictureGalleryImageTimeout);
const pictureGallery = $(this).closest(".picture-gallery");
const images = $('.images', pictureGallery);
const activeImage = $(this);
$('img', images).removeClass('active');
activeImage.addClass('active');
$(".title", pictureGallery).html("");
const currentActiveImage = $(".fullshow img", pictureGallery);
if(currentActiveImage.length === 0) {
$(".fullshow", pictureGallery).append(activeImage.clone());
$(".title", pictureGallery).html(activeImage.attr("title"));
} else {
currentActiveImage.fadeTo(400,0.30, function() {
currentActiveImage.attr("src", activeImage.attr("src"));
currentActiveImage.attr("title", activeImage.attr("title"));
}).fadeTo(400,1, function() {
$(".title", pictureGallery).html(activeImage.attr("title"));
});
}
$('.imageWrapper img').mouseover(function(){
clearIntervall(showNextPictureGalleryImageTimeout);
}).mouseout(function(){
showNextPictureGalleryImageTimeout = setIntervall(function() {
let nextActiveImage = $('img', activeImage.closest('.imageWrapper').next());
if(nextActiveImage.length === 0) {
nextActiveImage = $('img', $('.imageWrapper', pictureGallery).first());
}
nextActiveImage.trigger('click');
}, 8000);
});
});
Sorry, I can't program at all. I thought it might be a very simple snippet of code from which I can learn something for the future.
I have this code:
jQuery.fn.extend({
SelectBox: function(options) {
return this.each(function() {
new jQuery.SelectBox(this, options);
});
}
});
jQuery.SelectBox = function(selectobj, options) {
var opt = options || {};
opt.inputClass = opt.inputClass || "inputClass";
opt.containerClass = opt.containerClass || "containerClass";
var inFocus = false;
var $select = $(selectobj);
var $container = setupContainer(opt);
var $input = setupInput(opt);
$select.hide();
hideMe();
$input
.click(function(){
if (!inFocus) {
showMe();
} else {
hideMe();
}
})
.keydown(function(event) {
switch(event.keyCode) {
case 27:
hideMe();
break;
}
})
.blur(function() {
if ($container.not(':visible')) {
hideMe();
}
});
function showMe() {
$container.show();
inFocus = true;
}
function hideMe() {
$container.hide();
inFocus = false;
}
function setupContainer(options){
$container = $("." + options.containerClass);
$input = $("." + options.inputClass);
var first = false;
var li = "";
$select.find('option').each(function(){
if($(this).is(':selected')){
$input.find('span').text($(this).text());
first = true;
}
//var $li = $container.find('ul').append('<li>' + $(this).text() + '</li>');
var li = document.createElement('li');
li.innerHTML = $(this).text();
$container.find('ul').append(li);
$(li).click(function(event){
$(li).remove();
});
});
return $container;
}
function setupInput(options){
$input = $("." + options.inputClass);
$input.attr('tabindex', '0');
return $input;
}
};
In this code, the "select" i choose hidden, and replaced by a list.
Now, i want click on some "li", and "li" removed.
But, i click on the "li" i have created, and nothing happened.
Why? how can i remove or do anything else when i click on the "li"?
There is no need to add event to each individual element. Use event delegation.
$(document).ready(function() {
$(commonParentSelector).on('click', 'li', function() {
// ^^^^^^^^^^^^^^^^^^^^
$(this).remove();
});
});
Update commonParentSelector according to your needs and it should work.
Docs: https://api.jquery.com/on
use var $li = $("<li>").text($(this).text()).appendTo($container.find('ul'));
on my website I have a div .toggle-search that if you click on it it expands to .search-expand where a search form is. This is the code in jQuery
/* Toggle header search
/* ------------------------------------ */
$('.toggle-search').click(function(){
$('.toggle-search').toggleClass('active');
$('.search-expand').fadeToggle(250);
setTimeout(function(){
$('.search-expand input').focus();
}, 300);
});
Now the only way to close the .search-expand is to click once again on the .toggle-search. But I want to change that it closes if you click anywhere else on the site. For an easier example I have the Hueman theme, and I'm talking about the top right corner search option. http://demo.alxmedia.se/hueman/
Thanks!
Add the event on all elements except the search area.
$('body *:not(".search-expand")').click(function(){
$('.toggle-search').removeClass('active');
$('.search-expand').fadeOut(250);
});
or another way,
$('body').click(function(e){
if(e.target.className.indexOf('search-expand') < 0){
$('.toggle-search').removeClass('active');
$('.search-expand').fadeOut(250);
}
});
var isSearchFieldOpen = false;
var $toggleSearch = $('.toggle-search');
var $searchExpand = $('.search-expand');
function toggleSearch() {
// Reverse state
isSearchFieldOpen = !isSearchFieldOpen;
$toggleSearch.toggleClass('active');
// You can use callback function instead of using setTimeout
$searchExpand.fadeToggle(250, function() {
if (isSearchFieldOpen) {
$searchExpand.find('input').focus();
}
});
}
$toggleSearch.on('click', function(e) {
e.stopPropagation();
toggleSearch();
});
$(document.body).on('click', function(e) {
if (isSearchFieldOpen) {
var target = e.target;
// Checking if user clicks outside .search-expand
if (!$searchExpand.is(target) && !$searchExpand.has(target).length) {
toggleSearch();
}
}
});
I have a second search on the site with the same code as before only
with div .toggle-serach2 and .expand-search2, how can i make your code
so it wont overlap. just changing the name to $('toggle-search2')
doesn't cut it
in that case, I would suggest you convert your code into a plugin:
(function($, document) {
var bodyHandlerAttached = false;
var openedForms = [];
var instances = {};
var defaults = {
activeClass: 'active'
};
function ToggleSearch(elem, options) {
this.options = $.extend({}, defaults, options);
this.$elem = $(elem);
this.$btn = $(options.toggleBtn);
this.isOpen = false;
this.id = generateId();
this.bindEvents();
instances[this.id] = this;
if (!bodyHandlerAttached) {
handleOutsideClick();
bodyHandlerAttached = true;
}
}
ToggleSearch.prototype = {
bindEvents: function() {
this.$btn.on('click', $.proxy(toggleHandler, this));
},
open: function() {
if (this.isOpen) { return; }
var _this = this;
this.$btn.addClass(this.options.activeClass);
this.$elem.fadeIn(250, function() {
_this.$elem.find('input').focus();
});
openedForms.push(this.id);
this.isOpen = true;
},
close: function(instantly) {
if (!this.isOpen) { return; }
this.$btn.removeClass(this.options.activeClass);
if (instantly) {
this.$elem.hide();
} else {
this.$elem.fadeOut(250);
}
openedForms.splice(openedForms.indexOf(this.id), 1);
this.isOpen = false;
},
toggle: function() {
if (this.isOpen) {
this.close();
} else {
this.open();
}
}
};
var toggleHandler = function(ev) {
ev.stopPropagation();
this.toggle();
};
var handleOutsideClick = function(e) {
$(document.body).on('click', function(e) {
if (openedForms.length) {
var target = e.target;
var instance;
for (var id in instances) {
instance = instances[id];
if (!instance.$elem.is(target) && !instance.$elem.has(target).length) {
instance.close(true);
}
}
}
});
};
function generateId() {
return Math.random().toString(36).substr(2, 8);
}
$.fn.toggleSearch = function(options) {
return this.each(function() {
if (!$.data(this, 'toggleSearch')) {
$.data(this, 'toggleSearch', new ToggleSearch(this, options));
}
});
};
})(window.jQuery, document);
And then use it like this:
$('.search-expand').toggleSearch({
toggleBtn: '.toggle-search'
});
$('.search-expand2').toggleSearch({
toggleBtn: '.toggle-search2'
});
JSFiddle example
You could add a click handler to the main window that removes the active class:
$(window).click(function(){
$('.toggle-search').removeClass('active');
}
and then prevent the class removal when you click inside of your toggle-search elem
$('.toggle-search').click(function(e){
e.stopPropagation();
// remainder of click code here
)};
Try to add body click listener
$('body').click(function(e){
if ($(e.target).is('.toggle-search')) return;
$('.toggle-search').removeClass('active');
$('.search-expand').fadeOut(250);
});
I am using a function that changes the title with the code below, and whenever the window is on focus than it must stop the changing.
//Set to true on first load
var window_focus = true;
$(window).focus(function () {
return window_focus = true;
})
.blur(function () {
return window_focus = false;
});
// THE CHANGE FUNCTION
function doHighlightNow (){
var highlightTimer = null;
var oldTitle = document.title;
function doHighlight() {
if (window_focus){
stopHighlight();
}
var doBlink = function() {
document.title = "Title one"
setTimeout(function(){
document.title = "Title two";
}, 1000);
}
doBlink();
}
function stopHighlight() {
document.title = 'stopped';
clearInterval(highlightTimer);
}
highlightTimer = setInterval(function(){doHighlight(nickname) }, 2500);
}
Now this will change the title everytime doHightlightNow() is triggered and windows_focus is not true else it clears the interval.
Now I want to make it trigger stopHighlight() directly whenever the window is on focus again and if doHighlightNow()is triggered, what is the best solution for this.
I now it must be something like,
$(window).on("click", "focus",function(){
trigger stopHighlightnow();
});
But i don't know exactly how to provide this, I hope someone can help me.
What you can do is,
var highlightTimer = null; // Create it outside the function
// So you can stop it outside the function
function doHighlightNow (){
var oldTitle = document.title;
function doHighlight() {
//No need for this inside the function
//if (window_focus){
//stopHighlight();
//}
var doBlink = function() {
document.title = "Title one"
setTimeout(function(){
document.title = "Title two";
}, 1000);
}
doBlink();
}
// Neither need this anymore inside the function
//function stopHighlight() {
//document.title = 'stopped';
//clearInterval(highlightTimer);
//}
highlightTimer = setInterval(function(){doHighlight(nickname) }, 2500);
}
$(window).on("focus", function(){
if (window_focus){
document.title = 'stopped';
clearInterval(highlightTimer);
}
});
You have a better way to do what you want, you have a built in event for this:
document.addEventListener("visibilitychange", function() {
if(document.visibilityState === 'hidden') {
document.title = "Title one";
} else {
document.title = "Title two";
}
});
Please check it. Here is the Fiddle: http://jsfiddle.net/4467yz37/
When I do click in the Link it works good (Show and Hide). The only problem existing it's when I want to hide the Items section doing click outside the Link and the Items (that is in the Body except in the Items section).
Here is the JavaScript code:
(function(document) {
var alterNav = function() {
var item = document.querySelector('.items');
var link = document.querySelector('.clickme');
var theClass = 'display';
var itemIsOpened = false;
if (link) {
link.addEventListener('click', function (event) {
event.preventDefault();
if (!itemIsOpened) {
itemIsOpened = true;
addClass(item, theClass);
} else {
itemIsOpened = false;
removeClass(item, theClass);
}
});
}
};
var addClass = function (element, className) {
if (!element) {
return;
}
element.className = element.className.replace(/\s+$/gi, '') + ' ' + className;
};
var removeClass = function(element, className) {
if (!element) {
return;
}
element.className = element.className.replace(className, '');
};
alterNav();
})(document);
I try to solve it creating another variable with the tag Html or Body and alter the JS code, but it still don't working good: http://jsfiddle.net/g1d321rv/2/
var link = document.querySelector('body');
I manipulated your code a bit. Do you use jquery? I assumend that you are not using jquery.Here jsfiddle :
http://jsfiddle.net/9fpf07mt/
window.onclick = function (e) {
console.log(e);
if (!itemIsOpened) {
if (e.target == link) {
itemIsOpened = true;
addClass(item, theClass);
}
} else {
if (!isChild(e.target, item)) {
itemIsOpened = false;
removeClass(item, theClass);
}
}
};
edit for last request:
link.addEventListener('click', function (event) {
event.preventDefault();
});