I'm having this div element that shows the time past since it got created. However it doesn't get updated and always remains on few seconds ago. It looks like this
var newMsg= "<div id="chat-time">'+ moment().fromNow()+'</div>";
$("#chat-list").html( newMsg);
How can I update this text. I know I can do it with sentInterval but I can't figure out how to do it properly.It just prints out seconds! I'm using this for a chatroom. So each message will have a timestamp in the formatof momentjs.fromNow().
Does setting timer for all these message create a problem? I'd appreciate a hint.
EDIT:I'm using this code as mentioned in below but it's not showing anything:
<div id="chat-time"></div>
var messageTimeStamp = new Date();
setInterval(function(){
var time = moment(messageTimeStamp).fromNow();
$("#chat-time").html(time);
}, 1000);
To make this work you need the element in the dom and the setInterval running without being included in any string concatenation
HTML
<div id="chat-time"></div>
JS
var $chatTime = $('#chat-time').text(moment().fromNow());
setInterval(function(){
var time = moment().fromNow();
$chatTime.txt( time );
}, 1000);
UPDATE 2
Given that you're using socket.io, you'd do something like this (demo: http://plnkr.co/edit/QuaMV6x1vNB0kYPaU6i1?p=preview):
// The messages the user can currently see.
var messages = [];
// You have something like this in your code, presumably.
socket.on('new message', function(data) {
addChatMessage(data);
});
function addChatMessage(data) {
// First add the message to the dome, with a unique id for the timestamp text.
var messageElementId = 'chat-message-' + data.messageId;
$("#chat-list").prepend($("<div>" + data.message + "<i> (sent: <span id='" + messageElementId + "'>just now</span>)</i></div>"));
// When you no longer display that message in the DOM it from clear this array. I'd render the DOM based on this list if I were you.
messages.push({
messageElementId: messageElementId,
timestamp: data.timestamp
});
}
// By updating all the messages at once you don't have memory leaks.
setInterval(function() {
messages.forEach(function(message) {
var time = moment(message.timestamp).fromNow();
$("#" + message.messageElementId).text(time);
});
}, 1000);
UPDATE 1
Given this is your code:
var newMsg= "<div id="chat-time">'+ moment().fromNow()+'</div>";
$("#chat-list").html(newMsg);
You would do this, instead:
var messageTimeStamp = new Date(); // You need to grab this from somewhere.
setInterval(function(){
var time = moment(messageTimeStamp).fromNow();
$("#chat-list").html(time);
}, 1000);
You need to use moment(TIMESTAMP_OF_MESSAGE) not moment() and do something like this:
$(function(){
$("body").append($('<div id="chat-time"></div>'));
var messageTimeStamp = new Date();
var i = 0;
setInterval(function(){
var time = moment(messageTimeStamp).fromNow();
$("#chat-time").html('moment().from(messageTimeStamp): ' + time + '; setInterval calls made ' + i++);
}, 1000);
});
Here's a demo.
http://plnkr.co/edit/QuaMV6x1vNB0kYPaU6i1?p=preview
I dont see any problem using setInterval (). AngularJS wrapper setInterval on $interval service module . Check out these urls: interval Angular and Wrapper SetInterval
Related
I am working on a piece of code that is supposed to randomly display a view count on my site. It all works fine, except that it only runs once on page load. Its supposed to change the view count every 10 seconds after the initial first run. E.g. run this code snippet every 10 seconds after page load. I have tried multiple ways with setInterval but found that it is supposedly bad practice to use anyways after so many failed attempts?
Could you guys point me in the right direction. I have been reading posts on Stack overflow for hours and none had an answer to my issue. I have a feeling, that I am overlooking something obvious here.
document.addEventListener('page:loaded', function() { //// Page has loaded and theme assets are ready
(function() {
var f = function() {
document.addEventListener('DOMContentLoaded', function() {
// Minimum view count
var minViews = 2;
// Maximum view count
var maxViews = 20;
// Text to show after the view count number
var text = 'people are viewing this product right now.';
// Create the new element to display on the page
$(".view-count").get().forEach(function(entry, index, array) {
var $viewCountElement = Math.floor(Math.random() * (maxViews - minViews) + minViews) + ' ' + text;
$(entry).html($viewCountElement);
});
});
};
window.setInterval(f, 10000); //10 sec interval
f();
})();
});
You may not need nested event listener. You can just call the setInterval in the call back function of DOMContentLoaded.
function elementDisplay() {
// Minimum view count
var minViews = 2;
// Maximum view count
var maxViews = 20;
// Text to show after the view count number
var text = 'people are viewing this product right now.';
// Create the new element to display on the page
$(".view-count").get().forEach(function(entry, index, array) {
var $viewCountElement = Math.floor(Math.random() * (maxViews - minViews) + minViews) + ' ' + text;
$(entry).html($viewCountElement);
});
}
document.addEventListener('DOMContentLoaded', function() {
window.setInterval(elementDisplay, 10000); //10 sec interval
});
setInterval is a browser based API, zo it should be cleaned up from the browser properly.
This is majorly for your proper implementation of setInterval. You can add your listeners, too.
FYI: jQuery.ready/DOMContentLoaded occurs when all of the HTML is ready to interact with, but often before its been rendered to the screen.
var interval;
$(document).ready(function(){
console.log("I am initialized")
var f = function() {
console.log("I am called")
// Minimum view count
var minViews = 2;
// Maximum view count
var maxViews = 20;
// Text to show after the view count number
var text = 'people are viewing this product right now.';
// Create the new element to display on the page
$(".view-count").get().forEach(function(entry, index, array) {
var $viewCountElement = Math.floor(Math.random() * (maxViews - minViews) + minViews) + ' ' + text;
$(entry).html($viewCountElement);
});
};
interval = setInterval(f, 10000);
});
$(window).on("beforeunload", function() {
// clear the interval when window closes
return clearInterval(interval);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Note: Check the console for output
I have a form with 2 fields: date field #datefromtoday and number of days #daysfromtoday. I use a javascript function to:
1) Automatically listen to the datefromtoday and (if there is a date) display the number of days from today when the page is loaded
2) adjust the date from today when entering/modify the number of days.
Here is the code:
$(document).ready(function (){
function modifyDays(){ //definy function to modify days
var endDateToDays = $( "#datefromtoday" ).val();
var endDateToDays_obj = new Date(endDateToDays); // convert in object
var endDateToDays_ms = endDateToDays_obj.getTime(); // convert in ms
var todayDate = new Date(); //
var todayDate_ms = todayDate.getTime(); //
var daysFromToday = parseInt(Math.ceil( (endDateToDays_ms - todayDate_ms) / 1000 / 60 / 60 / 24 ) ) || ''; //if not number display nothing
document.getElementById("daysfromtoday").value = daysFromToday; //outuput
}
modifyDays(); //here is the problem. If I delete this line of code, everything works perfectly
$("#datefromtoday").on('change', function(){ //run function when modify delay date
modifyDays();
});
});
PROBLEM
the modifyDays function works like a charm on the on.change event, but
when is loaded on document ready, it interferes with datatables www.datatables.net and also with other scripts, and they don't work anymore...
I'm probably using the wrong code to call the function on page load.... any ideas? Thanks for your help!!!
If you think it is because of calling the main function, in the body element of the html page, add an onload attribute:
<body onload="loaded()">
and declare loaded as that main function:
var loaded = function (){
function modifyDays(){ //definy function to modify days
var endDateToDays = $( "#datefromtoday" ).val();
var endDateToDays_obj = new Date(endDateToDays); // convert in object
var endDateToDays_ms = endDateToDays_obj.getTime(); // convert in ms
var todayDate = new Date(); //
var todayDate_ms = todayDate.getTime(); //
var daysFromToday = parseInt(Math.ceil( (endDateToDays_ms - todayDate_ms) / 1000 / 60 / 60 / 24 ) ) || ''; //if not number display nothing
document.getElementById("daysfromtoday").value = daysFromToday; //outuput
}
modifyDays(); //here is the problem. If I delete this line of code, everything works perfectly
$("#datefromtoday").on('change', function(){ //run function when modify delay date
modifyDays();
});
};
Then it should work if the problem is how the function is called.
I don't think the problem is because of you are calling the function on page load. The error might be coming from inside the function modifyDays. Only dependency I see is #datefromtoday and #daysfromtoday. Check whether those nodes are there when the function execute on dom ready event.
If the timing of the function call is the problem, you can put the modifyDays(); call in a window.setTimeout(modifyDays, 5000); or something of the sort to delay it until the other scripts finish loading, so this snippet doesn't interrupt or interfere with them. You may want to put a placeholder in the html for the seconds when it isn't loaded yet if this works.
I have a countdown which is activated after the page is loaded:
$(document).ready(function() {
var rem_hour = $("#user-card-second-remaining").attr("rem_hour");
var rem_min = $("#user-card-second-remaining").attr("rem_min");
var rem_sec = $("#user-card-second-remaining").attr("rem_sec");
var currentDate = new Date();
var targetDate = new Date(currentDate.getTime() + rem_hour * 60 * 60000 + rem_min*60000 + rem_sec * 1000);
$("#user-card-second-remaining").countdown(targetDate, function(event) {
$(this).html(event.strftime('%H:%M:%S'));
});
});
Every minute, I load a div partially of this page, and #user-card-second-remaining is inside this loaded div.
function fn60sec() {
// runs every 60 sec and runs on init.
var pathname = window.location.pathname;
var card = pathname + " #user-card";
$( "#user-card-wrapper" ).load(card);
}
The problem is that when I loaded new #user-card-second-remaining div, countdown event disappears.
It seems, I think, I should refresh dom (not page) such that .countdown method could be bind into fresh #user-card-second-remaining div.
How can I do that?
When the DOM is updated, all jquery stuff attached to DOM elements are removed.
Well actually, the DOM element with the jquery styff is removed, and replaced with another event, brand new, without jquery stuff.
What you need to do, is add the jquery stuff again after you update the DOM, as you suggested.
function fn60sec() {
// runs every 60 sec and runs on init.
var pathname = window.location.pathname;
var card = pathname + " #user-card";
$( "#user-card-wrapper" ).load(card, function() {
var rem_hour = $("#user-card-second-remaining").attr("rem_hour");
var rem_min = $("#user-card-second-remaining").attr("rem_min");
var rem_sec = $("#user-card-second-remaining").attr("rem_sec");
var currentDate = new Date();
var targetDate = new Date(currentDate.getTime() + rem_hour * 60 * 60000 + rem_min*60000 + rem_sec * 1000);
$("#user-card-second-remaining").countdown(targetDate, function(event) {
$(this).html(event.strftime('%H:%M:%S'));
});
});
});
should do the trick.
What library/plugin is .countdown( from? You need to look at their documentation for a delegated event overload, or an alternative using an event name so you can use jquery .on('eventname',
Usually in this situation you use a pattern
$('#staticSelector').on('countdown', '#user-card-second-remaining', function() ...
and this listens on #staticSelector for events bubbling up from '#user-card-second-remaining'. So #staticSelector needs to be an element that always exists, but the '#user-card-second-remaining' can come and go as needed being refreshed inside your div that is being refreshed.
The section here on Direct and delegated events explains this:
http://api.jquery.com/on/
Is anyone able to determine, how to stop the jQuery caching the image that it grabs, and displaying the same image around and around again?
Basically the image is been re-uploaded every 5 seconds, as it acts as a webcam (if you check the time stamp on the bottom right of the image, you can tell if it's been updated or not)
http://colourednoise.co.uk/scripts/index.htm
Thank you
(sorry I forgot to hit paste for the code)
$(function(){
$(document).ready(function() {
var imgs = ['http://www.ramseycommunityradio.co.uk/images/webcam.jpg', 'http://www.ramseycommunityradio.co.uk/images/webcam.jpg']
$("#webcam").attr('src', imgs[1]);
var refreshId = setInterval(function() {
$("#webcam").fadeOut("slow", function() {
var $el = $(this);
$el.attr('src', $.inArray($el.attr('src'), imgs) === 0 ? imgs[1] : imgs[0]);
$el.fadeIn("slow");
});
}, 2000);
});
You could try appending a changing query string onto the URL, this should stop caching if that is indeed your problem. I've seen this done with a time stamp here: how to generate and append a random string using jquery
So each time you generate an image you do:
var qs = (new Date).getTime();
var url = 'http://www.example.com/images/myimage.jpg?' + qs;
$(el).attr('src',url);
your code:
var imgs = ['http://www.ramseycommunityradio.co.uk/images/webcam.jpg', 'http://www.ramseycommunityradio.co.uk/images/webcam.jpg']
$("#webcam").attr('src', imgs[1]);
var refreshId = setInterval(function() {
$("#webcam").fadeOut("slow", function() {
var $el = $(this);
$el.attr('src', $.inArray($el.attr('src'), imgs) === 0 ? imgs[1] : imgs[0]);
// this condition is redundant, it will ultimately give the same result always
// because imgs[0]==imgs[1]
$el.fadeIn("slow");
});
}, 2000);
as far a JQuery is concerned you are not changing the SRC attribute (JQuery knows nothing about the content of the image). Try using two different names in the server-side like webcam0.jpg and webcam1.jpg and alternating between them.
One trick is t append a random query string URL which causes the image to reload from the server. The code could be something like:
setInterval(function() {
var img = $("#img").get(0);
img.src = img.src.replace(/\?.*/, "") + "?" + Math.random();
}, 5000);
Hi i am using Javascript set timeout to run a certain function.
How do i display the last 10 seconds of the timeout when it is nearing the end?
var a = setTimeout('someFunction()', 10000);
Is it able to display something using the value that it store into the variable?
Thanks
I have created a small demo for you,
http://jsfiddle.net/praveen_prasad/DYaan/1/
<div id="target" style="display:none">
target
</div>
var target,
allotedTimeForWork=100 /*you can change this*/
;
var handler = setTimeout(function(){
if(!target)
{
target=document.getElementById('target');
}
target.style.display="block";
startTicker();
}, allotedTimeForWork);
function startTicker()
{
var counter=10;
var tickerHandler= window.setInterval(function(){
if(counter>0)
{
//cache target
target.innerHTML="you have "+counter +" seconds left";
counter--;
}
else
{
target.innerHTML="time over";
clearInterval(tickerHandler);
}
},1000);
}
It is not possible to directly get the remaining time of a Timeout.
You could either try to make multiple Timeouts for every second, or have another variable where you store when the Timeout was started.
I would use two timeouts.
The first with time minus 5 seconds, that calls a function with the second timeout (5 seconds) which would have the timer displayed.
Take a look here: http://jsfiddle.net/VCAnm/
HTML:
<span id="aaa">10</span>
JavaScript:
setInterval(function() {
var elem = document.getElementById('aaa');
elem.innerHTML = elem.innerHTML - 1;
}, 1000);
set 2 timers one for the timeout and another for the warning
var warn_time = 5000;
var function_name = 'someFunction()';
var a = setTimeout('warnFunction(function_name, warn_time)', 10000 - warn_time);
function warnFunction(function_name, time) {
alert('only ' + time + ' seconds left'); //use a div or whatever to display
var b = setTimeout(function_name, time);
}