Jquery div strobe - javascript

I would like to have a div act like a strobe light with jquery. Basicly change the background color from black to white every 500 milliseconds.
How can I do that?
<div id="strobe"></div>
Thank you!

The setInterval() function is your friend here.
You don't need to use JQuery, you can do it inn pure javascript - this is how you'd do it:
var elem = document.getElementById("strobe");
var strobeBackground = function() {
(elem.style.backgroundColor == "white") ? elem.style.backgroundColor = "black" : elem.style.backgroundColor = "white";
}
setInterval(strobeBackground, 500);
However if you want to do it in jQuery, here it is: http://jsfiddle.net/Ru9xt/2/
The HTML would look like this:
<div id="strobe" class="white">Hello</div>
The CSS would look like this:
.white {
background-color: white;
}
.black {
background-color: black;
}
And the JS is here:
setInterval(function () {
$("#strobe").toggleClass('black');
}, 500);

You can use jQuery for both checking the background color of the element and for setting the interval at which it flickers with the $.css() method which gets or sets the style of an element and the setInterval() method which sets up a reoccurring method call.
function toggle(){
var strobe = $('#strobe');
if(strobe.css('background-color') == '#FFFFFF'){
strobe.css('background-color', '#000000');
}else{
strobe.css('background-color', '#FFFFFF');
}
}
setInterval(toggle, 500);

I used classes instead:
/**
* Initialise strobe using classes. By Emmanuel Mahuni - 2015
* #param {string} sel selector
* #param {int} i speed in milli-seconds
* #param {string} c1 class 1
* #param {string} c2 class 2
* #returns {int} the interval id so that you can clear it later
*/
function initStrobeClass(sel, i, c1, c2) {
return setInterval(strobeClass, i,sel,c1,c2);
}
/**
* Strobe using classes. By Emmanuel Mahuni - 2015
* #param {string} sel selector
* #param {string} c1 class 1
* #param {string} c2 class 2
*/
function strobeClass(sel, c1, c2) {
var s = $(sel);
s.toggleClass(c1 + " " + c2);
}
/**
* Clear the strobe to a particular class
* #param {int} t interval id
* #param {string} sel selector of the element
* #param {string} c the class to set after clearing the strobe
* #returns {null} returns null to make sure we don't come back here again, make sure the interval id is set by this and do the checking to eliminate errors.
*/
function clearStrobeToClass(t, sel, c) {
clearInterval(t);
$(sel).attr('class', c);
return null;
}
usage:
The code below will begin strobbing the logout button when the count down is below 181. It will restore it when it goes above 180.
if (autoLogoutCountdown <= 180 && (typeof strobeLogoutTimer !== typeof NaN)) {
strobeLogoutTimer = initStrobeClass('#logout', 1000, 'logoutflash', 'logout');
} else if (autoLogoutCountdown > 180 && (typeof strobeLogoutTimer === typeof NaN)) {
strobeLogoutTimer = clearStrobeToClass(strobeLogoutTimer, '#logout', 'logout');
}
I hope this helps someone

Related

VSCode imported method comment not displayed in intellisense

I have a method in utils file that is commented like this, the body is not important.
/**
* Calculates width of the column.
*
* #param {string} text text.
* #param {boolean} hasTooltip does title have tooltip?
* #return {number} width of the column.
*/
const getColumnWidth = (text, hasTooltip) => {
const padding = 8;
const tooltipWidth = hasTooltip ? 22 : 0;
const sortArrowWidth = 26;
const context = document.createElement('canvas').getContext('2d');
context.font = getComputedStyle(document.body).font;
return context.measureText(text).width + padding + tooltipWidth + sortArrowWidth;
}
export {
...
getColumnWidth
};
Then this method is imported in another file.
import {
...
getColumnWidth
} from "c/dceSoftwareUtils";
The problem is when i use intellisense (ctrl + space) i see import instead of method comment:
But i need it to be displayed same way as getComputedStyle:
I believe this is caused by imported method being seen as property and not a method. How can i change this?

One javascript for mutliple divs?

I have this HTML and a script
/**
* Increment value with random intervals.
* #param {string} id - Id of DOM Element.
* #param {number} start - Start counter value. Applied immediately.
* #param {number} end - End counter value.
* #duration {number} duration - Max duration of one iteration in ms.
*/
function animateValue(id, start, end, duration) {
let current = start;
const obj = document.getElementById(id);
obj.innerHTML = current; // immediately apply start value
const setIncrOut = () => {
let time = Math.random() * 500;
setTimeout(function() {
if (current < end) {
current += 1;
obj.innerHTML = current;
setIncrOut(time)
}
}, time);
}
setIncrOut();
}
animateValue("value", 100, 1000000);
<div id="value">100</div>
Basically I want to use this 1 script for multiple divs:
<div id="value2">100</div>
<div id="value3">100</div>
<div id="value4">100</div>
I know that div id must match the script id, is there a workaround, so that I wouldn't need to duplicate the same script and simply use just one?
I'm planning to use over 200 of them, so I thought it's not feasible and using just one will save a lot resources.
EDIT: I figured I can use:
animateValue("value", 100, 1000000);
animateValue("value2", 100, 1000000);
animateValue("value3", 100, 1000000);
But maybe there's even simpler solution?
Try this
Use a class and since you are using let, you can just call with the object
/**
* Increment value with random intervals.
* #param {string} id - Id of DOM Element.
* #param {number} start - Start counter value. Applied immediately.
* #param {number} end - End counter value.
* #duration {number} duration - Max duration of one iteration in ms.
*/
function animateValue(obj, start, end, duration) {
let current = start;
obj.innerHTML = current; // immediately apply start value
const setIncrOut = () => {
let time = Math.random() * 500;
setTimeout(function() {
if (current < end) {
current += 1;
obj.innerHTML = current;
setIncrOut(time)
}
}, time);
}
setIncrOut();
}
document.querySelectorAll(".incr").forEach(obj => animateValue(obj, 100, 1000000));
<div class="incr">100</div>
<div class="incr">100</div>

babel renamed function param isn't matching jsdoc

I have a js function:
/**
*
* #param {Object} obj function gets on param - an object
* #param {Number} obj.param1 - 1st num
* #param {Number} obj.param2 - 2nd num
*
* #returns {Number} - the result of the request
*/
const myFunc = ({ param1, param2 }) => {
return param1 * param2
}
After compiling it with babel I get:
/**
*
* #param {Object} obj function gets on param - an object
* #param {Number} obj.param1 - 1st num
* #param {Number} obj.param2 - 2nd num
*
* #returns {Number} - the result of the request
*/
var myFunc = (_ref) => {
var param1 = _ref.param1,
param2 = _ref.param2
return param1 * param2
}
At this point jsdoc is breaking because it is not connecting the jsdoc declaration to the function below anymore.
I also tried to use #function with #name but still no success.
I want to be able to see the relevant param type and comment when using the compiled version. Any idea how can I keep it consistent?
Thanks

Issue with offset while reading code points

Resume: I'm currently writting an ActionScript 3 lexer that transforms a source code into tokens. I chosen to interpret the input, a String with optional surrogate pairs wrapped in a class UString, by code points. Under the hood I cache the last read position by using the UStringPos class.
I've tested how it scans the identifier "huehuehue" with...
'use strict';
import {Lexer} from 'core/Lexer';
import {UString} from 'utils/UString';
import ErrorHandler from 'core/ErrorHandler';
const errorHandler = new ErrorHandler(true);
// Tell the length to the `Lexer` manually.
const lexer = new Lexer(
new UString('huehuehue'), 9, errorHandler);
// Scan first token
lexer.next();
const id = lexer.lookahead.value;
console.log(
id,
id.length
);
It should have logged "huehuehue", 9, but was another story...
Why is it missing the last 'e'? The innermost method related on scanning this is Lexer#getCommonIdentifier. I've already tested my UString part and it works okay, by the way.
Lexer Related Definitions
/*
* Class that turns AS3 code into tokens.
*/
export class Lexer
{
/*
* #param {UString} source
* #param {Number} length
* #param {ErrorHandler} errorHandler
*/
constructor(source, length, errorHandler)
{
this.source = source;
this.length = length;
this.index = 0;
this.lineStart = 0;
this.lineNumber = 1;
this.comments = [];
this.errorHandler = errorHandler;
this.previousToken = null;
this.token = null;
this.lookahead = null;
this._special = [];
}
/*
* Verifies the end of file.
*/
eof()
{
return this.index >= this.length;
}
/*
* Advance the previous, current and lookahead tokens.
* The lexer however does not depend on these tokens.
*/
next()
{
this.previousToken = this.token;
this.token = this.lookahead;
this.lookahead = this.lex();
}
/*
* Consumes the next token and return it.
*/
lex()
{
this.consumeWhiteSpaces();
while (this.consumeComment())
this.consumeWhiteSpaces();
let cp = this.source.codePointAt(this.index);
let pureIdentifier =
Character.isIdentifierStart(cp);
if (pureIdentifier || (cp === 0x5C))
return this.scanIdentifierOrKeyword(!pureIdentifier);
if (this.eof())
{
let loc = [ this.index, this.lineNumber ];
return new Token(TokenType.EOF, loc, loc, '<end>');
}
}
/*
* Scan an identifier, keyword or boolean literal.
*/
scanIdentifierOrKeyword(usingEscape)
{
const start = this.index;
let id;
/* Like Esprima does: only identifiers containing
* escapes need some overheads. */
if (usingEscape)
{
id = this.getEscapedIdentifier(
String.fromCodePoint(this.scanUnicodeEscapeSequence()));
}
else
id = this.getCommonIdentifier();
return new Token(
TokenType.IDENTIFIER,
[ start , this.lineNumber ],
[ this.index, this.lineNumber ],
id
);
}
/*
* Interprets an identifier. If any escape appears, switches to
* getEscapedIdentifier().
*/
getCommonIdentifier()
{
const start = this.source.position.offset;
let cp = 0;
// Jump the starting symbol.
++this.index;
while (!this.eof())
{
cp = this.source.codePointAt(this.index);
if (Character.isIdentifierPart(cp))
++this.index;
// Switches to escape-minded task...
else if (cp === 0x5C)
return this.getUnicodeEscapedIdentifier(
this.source.string.slice(
start, this.source.position.offset
)
);
else break;
}
return this.source.string.slice(
start, this.source.position.offset
);
}
/* ... */
}
utils/UString.js
'use strict';
/*
* String wrapper with methods _based_ on code points.
*/
export class UString
{
/*
* Constructs the {UString}.
*
* #param {String} s String to be wrapped.
*/
constructor(s)
{
/*
* #type {String}
*/
this.string = s;
/*
* Tracks the last accessed position.
*
* #type {UStringPos}
*/
this.position = new UStringPos(0, 0);
}
/*
* Reads a code point at specific index.
*
* #param {Number} index
* #return {Number}
*/
codePointAt(index)
{
this.position.walk(this.string, index);
return this.string.codePointAt(this.position.offset);
}
/*
* Slices the internal string by code point indices.
*
* #param {Number} i
* #param {Number} j
* #return {String}
*/
slice(i, j)
{
this.position.walk(this.string, i);
i = this.position.offset;
this.position.walk(this.string, j);
j = this.position.offset;
return this.string.slice(i, j);
}
};
/*
* Class that tracks the position of a code point on a string.
*/
export class UStringPos
{
/*
* Constructs the {UStringPos}.
*
* #param {Number} index The initial index.
* #param {Number} offset The initial offset.
*/
constructor(index, offset)
{
/*
* #type {Number}
*/
this.index = index;
/*
* #type {Number}
*/
this.offset = offset;
}
/*
* Walks to the given index.
*
* #param {String} s
* #param {Number} index
* #note No backward. Track the previous position instead.
* #return {void}
*/
walk(s, index)
{
for (; this.index < index; ++this.index)
this.offset += (
this._usingSurrogates(
s.charCodeAt(this.offset)
) ? 2 : 1
);
}
/*
* #private
*/
_usingSurrogates(ch)
{
return (ch >= 0xD800) && (ch <= 0xDBFF);
}
};
Anything?
Okay. So it was a problem with this.source.position.offset: when I do ++this.index, the offset of my UStringPos doesn't update. The problem was with the slice thing.
this.source.string.slice(
start, this.source.position.offset
);
This slice was based on offsets, since I had to track the previous offset where the identifier started.
Solution
I can use the slice of my own UString class and use the first parameter as an offset and the last one as a normal index.
'use strict';
export class UString
{
// ...
/*
* Slices the internal string by using a pair of
* offset and code point indices.
*
* #param {Number} i Offset
* #param {Number} j
* #return {String}
*/
slice(i, j)
{
this.position.walk(this.string, j);
j = this.position.offset;
return this.string.slice(i, j);
}
};

Serializing a JavaScript Object to JSON returns "{}", but why?

Hello StackOverflowers,
I'm implementing a LocalStorage system for my web application.
But my pity is that all the objects in the Model abstraction layer have to be serialized.
I am aware that functions don't get serialized when the object is converted to JSON.
I was about to use Option 1 described here. (Which is, creating a 'static' method which returns a brand new object including the functions).
However, the problem is that even the non-function members of the objects don't get converted as well.
For example at divvie.textContent = JSON.stringify( coffee );, divvie.textContent becomes "{}".
Why? What's going on?
Sample code, not my real application but the situation is much the same:
Check Coffee
var coffee = new Coffee( "0001", "DE Red Coarse",
"Douwe Egberts, red & coarse grounded." );
coffee.addSugarCube( "0x0F_BROWN", "15" );
coffee.addSugarCube( "0x0C_WHITE", "12" );
var divvie = document.getElementById( "run" );
divvie.textContent = JSON.stringify( coffee );
</script>
</body>
</html>
/**
* #class This class represents a coffee.
*
* #param {String} id
* #param {String} name
* #param {String} description
* #returns {Coffee}
*/
function Coffee( id, name, description )
{
var sugarCubes = new Array();
var maxAmountOfSweetness = 0;
/**
* #returns {String}
*/
this.getId = function()
{
return id;
};
/**
* #returns {String}
*/
this.getName = function()
{
return name;
};
/**
* #returns {String}
*/
this.getDescription = function()
{
return description;
};
/**
* #param {String} sugarCubeId
* #param {Number} amountOfSweetness
*/
this.addSugarCube = function( sugarCubeId, amountOfSweetness )
{
/// First check if this sugarCube is already in our coffee.
var sugarCubeFound = false;
for( var i = 0; i < sugarCubes.length; i++ )
{
if( sugarCubes[ i ].getId() === sugarCubeId )
{
sugarCubeFound = true;
i = sugarCubes.length;
}
}
if( !sugarCubeFound )
{
/// Oh Sweet! A new sugar cube to add in our coffee!
sugarCubes.push( new SugarCube( sugarCubeId, amountOfSweetness ) );
maxAmountOfSweetness = Math.max( maxAmountOfSweetness, amountOfSweetness );
}
};
/**
* #param {String} sugarCubeId
* #returns {SugarCube}
*/
this.getSugarCube = function( sugarCubeId )
{
for( var i = 0; i < sugarCubes.length; i++ )
{
if( sugarCubes[ i ].getId() === sugarCubeId )
{
return sugarCubes[ i ];
}
}
};
/**
* #returns {Boolean} True when the amount of sugar cubes in this coffee is 1 or more,
* false when not.
*/
this.isSweet = function()
{
if( 0 < sugarCubes.length )
{
return true;
}
return false;
};
}
/**
* #class This class represents a sugar cube
*
* #param {String} id
* #param {Number} amountOfSweetness
* #returns {SugarCube}
*/
function SugarCube( id, amountOfSweetness )
{
/**
* #returns {String}
*/
this.getId = function()
{
return id;
};
/**
* #returns {Number}
*/
this.getAmountOfSweetness = function()
{
return amountOfSweetness;
};
}
The only properties on instances created by the Coffee constructor seem to be the methods, which have no JSON representation (because they're functions). Your data is all kept as variables or parameters within the closures created. These are not properties and therefore again not something that JSON is designed for.
To get it working as you expect, you'll either need to write your own toJSON method, or move your data from vars to properties
For example, using properties
function Coffee(id, name, description) {
this.id = id;
this.name = name;
this.description = description;
this.sugarCubes = [];
this.maxAmountOfSweetness = 0;
}
// and now you could even move the methods into the prototype
Coffee.prototype = {
getId: function () {return this.id;}
// etc
};
// new Coffee() is now JSON-able
You probably used var to "hide" the data so it was only exposed through your methods, so the other way is to add a new method which converts it to JSON, e.g.
// in Coffee
this.toJSON = function (a, b) {
var o = {
id: id,
name: name
// etc
};
return JSON.stringify(o, a, b);
};

Categories

Resources