Highlight tab on new event - javascript

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";
}
});

Related

jQuery Title Change with array elements

I'm trying to get this code to change the page title based on array elements. But there is something wrong with this code. I need the page title show the entire array only when the browser tab is inactive. When the browser tab is active show the real page title. This is the code that I got so far
Here is a fiddle: https://jsfiddle.net/hgmvqasn/2/
/*
*
Title Change Plugin, adapted
*
*/
window.onload = function() {
var pageTitle = document.title;
var appeal = ["Hello! ♥","Welcome Back!", "Are you sure?"];
var blinkEvent = null;
document.addEventListener('visibilitychange', function(e){
var isPageActive = document.visibilityState;
console.log(isPageActive);
if (isPageActive == "hidden") {
blinkEvent;
} else {
document.title = pageTitle;
clearInterval(blinkEvent);
}
})
blinkEvent = setInterval(function() {
function blink(){
for (i = 0; i < appeal.length; i++){
document.title = appeal[i];
console.log(appeal[i]);
}
// To make instant page title change (no wait the interval)
document.title = appeal[1];
}
}, 1900);
};
The code above does not display all items in the array or displays them in wrong way. In addition the interval is not interrupted when the tab becomes active again.Can someone help me?
You shouldn't have the for loop. You just want one timer, not a timer for each string in the appeal array. That timer should increment the index and display the next title.
window.onload = function() {
var pageTitle = document.title;
var appeal = ["Hello! ♥", "Welcome Back!", "Are you sure?"];
var appeal_index = 0;
var blinkEvent = null;
document.addEventListener('visibilitychange', function(e) {
var isPageActive = document.visibilityState;
console.log(isPageActive);
if (isPageActive == "hidden") {
start_timer();
} else {
document.title = pageTitle;
clearInterval(blinkEvent);
}
})
function blink() {
document.title = appeal[appeal_index];
console.log(appeal[appeal_index]);
appeal_index++;
if (appeal_index >= appeal.length) { // wrap around to beginning
appeal_index = 0;
}
}
function start_timer() {
blink();
blinkEvent = setInterval(blink, 1900);
}
};

Getting global var to use in a function

I'm working with this code to play and pause several audios:
jQuery(document).ready(function(){
var getaudio;
var audiostatus = 'off';
var current_id;
jQuery(document).on('click touchend', '.speaker', function() {
elemento = jQuery(this);
current_id = elemento.children("audio").attr("id");
clase = current_id.replace(/player/, '');
if (!jQuery('.c'+clase).hasClass("speakerplay")) {
getaudio = jQuery('#'+current_id)[0];
if (audiostatus == 'off') {
jQuery('.c'+clase).addClass('speakerplay');
getaudio.load();
getaudio.play();
audiostatus = 'on';
return false;
} else if (audiostatus == 'on') {
jQuery('.c'+clase).addClass('speakerplay');
getaudio.play()
}
} else if (jQuery('.speaker').hasClass("speakerplay")) {
getaudio.pause();
jQuery('.c'+clase).removeClass('speakerplay');
audiostatus = 'on';
}
});
// Here is my problem: I need to get the value of current_id...
jQuery('#'+current_id).on('ended', function() {
jQuery('.speaker').removeClass('speakerplay');
audiostatus = 'off';
});
});
In the last function I want to remove the class 'speakerplay' once the audio reached the end, but I can't get the value of current_id
Could anybody help me with this?
Thanks in advance!
don't use
var current_id;
use window.current_id directly
window.current_id = elemento.children("audio").attr("id");
jQuery('#'+window.current_id).on('ended', function() {

jQuery Pause Between Animation And Color Change

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*/
});

jQuery search toggle

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);
});

Youtube api does not load on firefox

I have the following code snippet that controls an embedded youtube player. It works great on Chrome and Safari but not on Firefox.
jsfiddle : http://jsfiddle.net/fuSSn/4/
Code from my app:
the iframe:
<div class="tubeframe" id="video-frame-155" style="">
<iframe title="YouTube video player" width="350" height="262" src="http://www.youtube.com/embed/hc5xkf9JqoE?HD=1;rel=0;showinfo=0;autohide=1" frameborder="0" allowfullscreen="" id="video-frame-155-frame"></iframe>
</div>
my javascript:
var source_tag = document.createElement("script");
var first_source_tag = document.getElementsByTagName("script")[0];
first_source_tag.parentNode.insertBefore(source_tag, first_source_tag);
// This function will be called when the API is fully loaded
function onYouTubeIframeAPIReady() {
YT_ready(true)
console.log("api loaded! yikes")
}
function getFrameID(id){
var elem = document.getElementById(id);
if (elem) {
if(/^iframe$/i.test(elem.tagName)) return id; //Frame, OK
// else: Look for frame
var elems = elem.getElementsByTagName("iframe");
if (!elems.length) return null; //No iframe found, FAILURE
for (var i=0; i<elems.length; i++) {
if (/^https?:\/\/(?:www\.)?youtube(?:-nocookie)?\.com(\/|$)/i.test(elems[i].src)) break;
}
elem = elems[i]; //The only, or the best iFrame
if (elem.id) return elem.id; //Existing ID, return it
// else: Create a new ID
do { //Keep postfixing `-frame` until the ID is unique
id += "-frame";
} while (document.getElementById(id));
elem.id = id;
return id;
}
// If no element, return null.
return null;
}
// Define YT_ready function.
var YT_ready = (function(){
var onReady_funcs = [], api_isReady = false;
return function(func, b_before){
if (func === true) {
api_isReady = true;
while(onReady_funcs.length > 0){
// Removes the first func from the array, and execute func
onReady_funcs.shift()();
}
}
else if(typeof func == "function") {
if (api_isReady) func();
else onReady_funcs[b_before?"unshift":"push"](func);
}
}
})();
var video = function ( videoid, frameid) {
var player;
var that;
var seconds;
var duration;
var stateChangeCallback;
var update_play = 0;
return {
setOnStateChangeCallback: function(callback) {
stateChangeCallback = callback;
},
getCurrentTime: function() {
return player.getCurrentTime();
},
getPlayer: function () {
return player;
},
getVideoFrameId: function () {
return "video-frame-" + videoid;
},
initVideo: function (second) {
console.log("initing")
that = this;
YT_ready(function(){
var frameID = getFrameID("video-frame-" + videoid);
console.log("creating player")
console.log(frameID)
if (frameID) { //If the frame exists
console.log("frame exists")
player = new YT.Player(frameID, {
events: {
"onStateChange": that.stateChange
}
});
console.log("Player Created!");
if (second) {
console.log(second)
setTimeout(function() { console.log("seek to"); player.seekTo(second, false); player.stopVideo()}, 1000);
}
}
});
},
stateChange: function (event) {
console.log("event.data = ", event.data);
switch(event.data) {
case YT.PlayerState.PLAYING:
{
if (stateChangeCallback)
stateChangeCallback("play", player.getCurrentTime(), player.getDuration());
onsole.log("play");
}
break;
case YT.PlayerState.PAUSED:
case YT.PlayerState.CUED:
case YT.PlayerState.ENDED:
{
if (stateChangeCallback)
stateChangeCallback("pause", player.getCurrentTime(), player.getDuration());
console.log("pause");
}
break;
}
},
pauseVideo: function () {
player.stopVideo();
console.log('player.stopVid()');
},
seekTo: function(second) {
player.seekTo(second, false);
}
};
};
function onStateChange(vid, action, second, total) {
if (Videos[vid]) {
console.log( (second / total) * 100);
}
};
$(document).ready(function () {
var Videos = {};
logger.info("heyyy")
var videoId=155;
//if (videoId) {
Videos[videoId] = video(videoId, 155);
console.log(Videos[155])
Videos[155].initVideo();
Videos[155].setOnStateChangeCallback(function(action, second, total) {
onStateChange(155, action, second, total);
});
//}
Videos[155].seekTo(1000, false);
onStateChange(155, "start", 0, 0);
});
I know that the required script tags are being added, I can test that from console. I also know that onYouTubePlayerAPIReady() is actually called. But I still receive errors like
TypeError: player.stopVideo is not a function
When I run the three lines that adds the source tag again from the web console on firefox, the api seems to load and everything starts working again.
I have been struggling with this for days and I really need help figuring out what might be wrong. If it helps my application is developed in ruby on rails but I don't think this is relevant information.
Thanks
There is no problem with the above code. My video was loaded in a bootstrap modal. Modal's hide property would make it invisible to firefox and firefox would not load the api at all. So I removed the modal hide class and instead of display:none I used item.css("visibility", "visible"); and item.css("visibility", "hidden"); which made firefox load the api.

Categories