Im using a function to start a count up timer using moment.js library , how could I make a stop timer function?
function startTimer()
{
var startTimestamp = moment().startOf("day");
setInterval(function() {
startTimestamp.add(1, 'second');
document.getElementById('timer').innerHTML =
startTimestamp.format('HH:mm:ss'); }, 1000);
}
startTimer();
<div id="timer"></div>
Thanks in advance
function startTimer() {
var startTimestamp = moment().startOf("day");
var myInterval = setInterval(function () {
startTimestamp.add(1, 'second');
document.getElementById('timer').innerHTML =
startTimestamp.format('HH:mm:ss');
}, 1000);
}
startTimer();
function stopTimer() {
clearInterval(myInterval);
}
Store your interval in a variable. I called it myInterval.
Create a new function called stopTimer(); that uses the clearInterval() method to clear your interval.
Create your button or whatever DOM element to trigger this, and set the onClick to stopTimer();
Related
This is weird but when I call a external function from Meteor.method function it will always return undefined in the client I tried Meteor.wrapAsync but I think I'm doing something wrong. Here is my code:
var demoFunction = function () {
//database operations
var user = this.userId;
if (!user)
return;
var count = Users.aggregate([
{ $group: {_id: null, count: {$sum: 1}} }
]);
if (count[0] && count[0].count)
return count[0].count;
return 0;
}
Meteor.methods({
// NOT WORKING, How can I make this work?
methodDemo: function () {
var result = demoFunction ();
return result;
},
// Works
methodDemo2: function () {
//database operations
var user = this.userId;
if (!user)
return;
var count = Users.aggregate([
{ $group: {_id: null, count: {$sum: 1}} }
]);
if (count[0] && count[0].count)
return count[0].count;
return 0;
}
});
// Call from client
Meteor.call("methodDemo", function (err, res) { });
calling external functions doesn't work the same way if I put the code inside the meteor method why?
Try using Meteor.userId() in your function instead of this.userId. I think you are loosing the value of this when calling your function causing it to exit early.
Since you declared the function with a var it is scoped outside of methodDemo().
You could declare the function globally by removing var or move the demoFunction() code into methodDemo().
I create something like calendar with events.
I want to popup message for user when the event come up.
My solution:
//this code runs in loop
var offsetRef = new Firebase("https://example.firebaseio-demo.com/.info/serverTimeOffset");
offsetRef.on("value", function(snap) {
var offset = snap.val();
var estimatedServerTimeMs = new Date().getTime() + offset;
fbRef.endAt(estimatedServerTimeMs).once("value", function(ss) {/*remove old events*/});
});
Is´t possible something like this (without loop)?
fbRef.endAt(Firebase.ServerValue.TIMESTAMP).on("child_added", function(snap) {/*...*/});
Thank you for reply
It's best to calculate the serverTimeOffset just once, and then wrap the popup in a setTimeout after you know what the current time (approximately) is:
var timeouts = [];
offsetRef.on("value", function(snap) {
// Cancel all previous timeouts.
timeouts.forEach(function(i) { clearTimeout(i); });
var estTime = new Date().getTime() + snap.val();
var promptTime = /* Get time at which you want to prompt */
timeouts.push(setTimeout(function showPrompt() {
...
}, promptTime));
});
In a application, I am using google map to display stations with google marker, because the google marker is static with icon not animated, so I decided to inherit OverlayView and use canvas to draw a station dynamically. And this works, however, I want this overlay to receive the google events like the marker, such as click, mouse over, mouse out...
For example,
function StationCanvas(map, position, name) {
this.map_ = map;
this.position_ = position;
this.name_ = name;
this.canvas_ = null;
this.labelDiv_ = null;
this.canvasWidth_ = 12;
this.canvasHeight_ = 50;
this.setMap(map);
console.log('canvas '+this.position_);
}
StationCanvas.prototype = new google.maps.OverlayView();
StationCanvas.prototype.onAdd = function() {
var canvas = document.createElement("canvas");
canvas.setAttribute("width", this.canvasWidth_);
canvas.setAttribute("height", this.canvasHeight_);
canvas.style.position = "absolute";
this.canvas_ = canvas;
var panes = this.getPanes();
panes.floatPane.appendChild(canvas);
this.labelDiv_ = document.createElement("div");
this.labelDiv_ .setAttribute("width", this.canvasWidth_);
this.labelDiv_ .setAttribute("height", this.canvasHeight_);
this.labelDiv_ .style.position = "absolute";
this.labelDiv_ .innerHTML = this.name_;
panes.floatPane.appendChild(this.labelDiv_ );
/////////////////////////////////////////////////////////////
this.listeners_ = [
google.maps.event.addListener(this.canvas_, "mouseover", function (e) {
//this.style.cursor = "pointer";
//google.maps.event.trigger(this, "mouseover", e);
console.log('mouse mover');
}),
google.maps.event.addListener(this.canvas_, "mouseout", function (e) {
//this.style.cursor = this.getCursor();
//google.maps.event.trigger(this, "mouseout", e);
console.log('mouse out');
}),
google.maps.event.addListener(this.canvas_, "click", function (e) {
google.maps.event.trigger(this, "click", e);
console.log('click');
}),
google.maps.event.addListener(this.canvas_, "dblclick", function (e) {
//google.maps.event.trigger(this, "dblclick", e);
}),
];
}
Intially, I use google.maps.event.addListener as showed above to listen the event, nothing happens, so it seems canvas doesn't work with google.maps.eventListener.
Then I found google has provided a addDomListener(instance:Object, eventName:string, handler:Function), but since it only support dom rather then canvas, so when I used that listener, the browser breaks down.
At last, I have tried to use
canvas.onmouseout = function() {
console.log("on mouse out");
}
}
It is supposed to work, but still no, I guess something wrong within the code. even this works, the next question is how can I trigger the event to outside, so that I can work this overlayview like the google marker
var test1 = new StationCanvas(map, new google.maps.LatLng(53.3234,-2.9178), "abc",13);
google.maps.event.addListener(test1, 'click', function(event){
console.log('test 1 click');
});
addDomListener works for me, even with <canvas/>
What would break your code is e.g. this:
google.maps.event.addListener(this.canvas_, "click", function (e) {
google.maps.event.trigger(this, "click", e);
console.log('click');
})
this , when used in a event-callback, refers to the object that triggers the event(here: the canvas-node), your code produces a recursion. When you want to trigger the click-event for the StationCanvas-instance, you may store the instance as a property of the canvas-element, so it will be easy accessible inside the click-callback
StationCanvas.prototype.onAdd = function() {
var canvas = document.createElement("canvas");
canvas.overlay=this;
//more code
}
this.listeners_ = [
google.maps.event.addDomListener(this.canvas_, "click", function (e) {
google.maps.event.trigger(this.overlay,'click')
}),
google.maps.event.addListener(this, "click", function (e) {
alert('click on the StationCanvas-instance');
})
];
Please, I need a help.
I want to check if my infowindow is opened.
For example:
if (infowindow.isOpened)
{
doSomething()
}
or
if (infowindow.close)
{
doAnotherthing();
}
I dont have any idea, how to do this
This is an undocumented feature, and is therefore subject to change without notice, however the infoWindow.close() method sets the map on the object to null (this is why infoWindow.open(map, [anchor]) requires that you pass in a Map), so you can check this property to tell if it is currently being displayed:
function isInfoWindowOpen(infoWindow){
var map = infoWindow.getMap();
return (map !== null && typeof map !== "undefined");
}
if (isInfoWindowOpen(infoWindow)){
// do something if it is open
} else {
// do something if it is closed
}
Update:
Another potentially useful way to write this is to add an isOpen() method to the InfoWindow prototype.
google.maps.InfoWindow.prototype.isOpen = function(){
var map = this.getMap();
return (map !== null && typeof map !== "undefined");
}
Until google doesn't give us any better way of doing this, you can add a property to the infoWindow objects. Something like:
google.maps.InfoWindow.prototype.opened = false;
infoWindow = new google.maps.InfoWindow({content: '<h1> Olá mundo </h1>'});
if(infoWindow.opened){
// do something
infoWindow.opened = false;
}
else{
// do something else
infoWindow.opened = true;
}
I modified the prototype for google.maps.InfoWindow and changed open/close to set/clear a property:
//
// modify the prototype for google.maps.Infowindow so that it is capable of tracking
// the opened state of the window. we track the state via boolean which is set when
// open() or close() are called. in addition to these, the closeclick event is
// monitored so that the value of _openedState can be set when the close button is
// clicked (see code at bottom of this file).
//
google.maps.InfoWindow.prototype._open = google.maps.InfoWindow.prototype.open;
google.maps.InfoWindow.prototype._close = google.maps.InfoWindow.prototype.close;
google.maps.InfoWindow.prototype._openedState = false;
google.maps.InfoWindow.prototype.open =
function (map, anchor) {
this._openedState = true;
this._open(map, anchor);
};
google.maps.InfoWindow.prototype.close =
function () {
this._openedState = false;
this._close();
};
google.maps.InfoWindow.prototype.getOpenedState =
function () {
return this._openedState;
};
google.maps.InfoWindow.prototype.setOpenedState =
function (val) {
this._openedState = val;
};
You also need to monitor the closeclick event because clicking on the close button does not call close().
//
// monitor the closelick event and set opened state false when the close
// button is clicked.
//
(function (w) {
google.maps.event.addListener(w, "closeclick", function (e) {
w.setOpenedState(false);
});
})(infowindow);
Calling InfoWindow.getOpenedState() returns a boolean which reflects the state (opened/closed) of the infowindow.
I chose to do it this way instead of the using the InfoWindow.getMap() or MVCObject.get('map') method because of the well known pitfalls of using undocumented behavior. However google uses MVCObject.set('map', null) to force the removal of the InfoWindow from the DOM, so it is unlikely that this will change...
infowindow.getMap() returns null if infowindow is closed.
So you can use simply:
if (infowindow.getMap());
You can simply set key and value for infoWindow: infoWindow.set('closed', true);
example:
const infoWindow = new google.maps.InfoWindow({
content: 'foo',
position: {
lat: some_number,
lng: some_number
}
});
infoWindow.set('closed', true);
// Clicking on polyline for this example
// Can be marker too
polyline.addListener(
'click',
() => {
if (infoWindow.get('closed')) {
infoWindow.open(map);
infoWindow.set('closed', false);
} else {
infoWindow.close();
infoWindow.set('closed', true);
}
}
);
I'm trying to simply return what I request in PHP to JSON.
My problem is that each Stock is not yet completed.
Indeed, it is the "render" but "this.collection.models" is not yet completed because the request is not yet finished.
What should I do to correct this problem, wait until the request is finished so that the loop is done correctly.
Thank you in advance
var Article = Backbone.Model.extend({});
var Articles = Backbone.Collection.extend({
model:Article,
url: function() {
return _BASE_URL+'/sync/getLastArticles';
},
initialize:function () {
this.fetch();
}
});
var ArticlesView = Backbone.View.extend({
template:$('#articles').html(),
initialize:function () {
this.collection = new Articles();
this.render();
},
render:function () {
console.log(this.collection);
var that = this;
_.each(this.collection.models, function (item) {
console.log(item);
}, this);
},
renderArticle:function () {
;
}
});
You render before the fetch is done. What you want to do, is to wait for the fetch to complete and then render. Now how would you get notification of when the fetch is done? You have 2 options:
The success function (Not recommended by me)
// ArticlesView
initialize: function() {
_.bindAll(this); // Don't forget to BIND
this.collection = new Articles();
this.collection.fetch({
success: this.render
});
}
Now when the fetch has been successful, render is called. This however can cause scoping problems and Backbone.js offers a much nicer alternative to callback functions: events.
Event callback (prefer this)
// ArticlesView
initialize: function() {
_.bindAll(this);
this.collection = new Articles();
this.collection.on('reset', this.render); // bind the reset event to render
this.collection.fetch();
}