Increment strings like '20px' - javascript

I need something to increment string values representing length (css margins)
the current solution is:
function incPx(a,b){
return parseInt(a) + parseInt(b) +'px';
}
incPx($(el).css('margin-left'), '10px')
but there may be a jQuery thing for that maybe? to work with other units that 'px'

With jQuery 1.6+, you can pass relative amounts to .css(), indicated by += or -=, similar to .animate():
$(el).css('margin-left', '+=10px');

Others have already suggested jQuery.css()'s relative values, but keep in mind that you can easily use parseInt to convert a string like 50px to a Number, like so:
console.log(parseInt('50px', 10));
// 50
function incPx(a, b){
a = parseInt(a, 10) || 0;
b = parseInt(b, 10) || 0;
return (a + b) +'px';
}​
Don't forget to pass a radix of 10, though. More examples: Example: Using parseInt (MDN)

As of jQuery 1.6, .css() accepts relative values similar to .animate(). Relative values are a string starting with += or -= to increment or decrement the current value. For example, if an element's padding-left was 10px, .css( "padding-left", "+=15" ) would result in a total padding-left of 25px.
Source: http://api.jquery.com/css/

The other answers here, discussing the "jQuery way", are perfectly valid. However, I wanted to include a method that uses an approach similar to the one that the OP is using, which could be used with "vanilla" javascript too.
Note that the OP's code would, as it stands, work just fine -- this is basically the same thing with a little more care paid to giving defaults
function incPx (val, amt) {
var nv = parseInt(val.replace(/[^0-9]/, ''), 10);
return (
(nv ? nv : 0) + (amt || 1)
)+'px';
};
console.log(incPx('10px')); // 11px
console.log(incPx('let us hasten to the zoo, post haste!')); // 1px
console.log(incPx('10px', 10)); // 20px
console.log(incPx('10px', -2)); // 8px
Try it: http://jsfiddle.net/jxU6Q/2/
Documentation
parseInt on MDN - https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/parseInt
String.replace on MDN - https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/replace

Related

What is the purpose of +- on a Javascript number?

I came across some code recently that was like this:
const element = document.getElementById("myId")
const rect = element.getBoundingClientRect()
const height = +-(rect.height / 1)
First of all, what is the deal with the division by 1? And second, what does +- do?
I put that logic into a Fiddle and it appears that it flips the sign of whatever is in the parentheses (from positive to negative and from negative to positive). However, if I wanted to flip a sign, why wouldn't I just do -(myvariable)?
Regarding the division by 1, it appears that the type of rect.height is already a number with floating-point precision and the divide operator is also floating-point division so we're not trying to generate an int or anything.
I just need some help trying to understand what that's trying to do.
Edit: The code was found here: Check if element is partially in viewport
Using division / will implicitly convert both operands to numbers:
const str = "10.5"
const division = str / 1;
console.log(division);
console.log(typeof division);
Using a unary minus - will implicitly convert the operand and change its sign:
const str = "10.5";
const minusStr = -str;
console.log(minusStr);
console.log(typeof minusStr);
const negativeNum = -3;
const minusNegativeNum = -negativeNum;
console.log(minusNegativeNum);
Using a unary plus + will convert anything to a number. If supplied with a number, it leaves it as it is:
const str = "10.5";
const plusStr = +str;
console.log(plusStr);
console.log(typeof plusStr);
const negativeNum = -3;
const plusNegativeNum = +negativeNum;
console.log(plusNegativeNum);
The above is also the order of how the expression +-(rect.height / 1) would be evaluated.
So, what does +-(rect.height / 1) do? The same as -rect.height but tacks on two useless operators.
It should be noted, that none of the conversions are really needed - not because a unary minus already does it, but because the height property produces a number anyway:
const element = document.getElementById("myId")
const rect = element.getBoundingClientRect()
console.log(rect.height);
console.log(typeof rect.height);
const height = +-(rect.height / 1);
console.log(height);
#myId {
width: 400px;
height: 200px;
background: red;
}
<div id="myId"></div>
So the whole expression just gets the height and inverts its sign.
Can you provide the link where you found this code?
But from what you provided, I would agree with you. The + operator and the dividing by one wouldn't do anything. So I would say that it's a typo, bit of temporary code, or the developer having one too many drinks.
I think it´s a trap. I´m not shure but if you get numbers from document you get strings instead of numbers. this + before a number in a string (example "10") would turn it in type number.
For example
"11" + 1 = "111"
because javascript concanate this as 2 strings.
but
var a = "11"
+a makes it = 11
but the restit sadly out of context i think
Edit:
ah okay.
Math.floor(100 - (((rect.top >= 0 ? 0 : rect.top) / +-(rect.height / 1)) * 100)) < percentVisible
+-(rect.height / 1)) * 100
I think this parts makes this number to a percent value.JS don´t know percent. Everything is value / 100, but to get the right value, you should value / 1.

javascript float dynamic precision?

how can I get dynamic precision for float?
exemple what I need :
0.00019400000001.dynamicPrecision() //0.000194
0.0001940001.dynamicPrecision() //0.000194
0.0001941.dynamicPrecision() //0.0001941
0.0194.dynamicPrecision() //0.0194
0.01940000.dynamicPrecision() //0.0194
(its important to not have useless zero at the end)
I can't use toFixed or toPrecision because the significative number can change and is unknow. so what way to write this dynamicPrecision method with dynamic precision?
While it's a bit questionable what you are asking for, one approach would be to take slices of the decimal and then compare it to the original. If it is some threshold percentage different, consider it an answer.
const f = (v, threshold = .9999) => {
let shift = 1;
let part;
do {
shift *= 10;
part = Math.floor(v * shift) / shift;
} while (part / v < threshold);
return part;
}
[0.194, 0.194000001, 0.19401, 0.194101]
.forEach(v => console.log(f(v)));
This uses actual math to determine the significant digit.
Basically, for each step, it takes one more digit and compares it against the value. If it is within the threshold, then it will be returned.
For 1.9410001 it would:
part = 1.9
part = 1.94
part = 1.941 // part / v > threshold, returned
The threshold is then configurable. .9999 means it is 99.99% the same as the original value.
I hope it will help,
var number1 = 0.00019400000001
console.log(parseFloat(number1.toString().replace(/0+[1-9]$/, '')));
You could replace all endings with at least one zero and one one at the end. Then take the numererical value.
function precision(v) {
return +v.toString().replace(/0+1$/, '');
}
console.log([0.00019400000001, 0.0001940001, 0.0001941, 0.0194, 0.01940000].map(precision));
Number.prototype.dynamicPrecision = function(){
return parseFloat(this.valueOf().toString().replace(/0+1$/, ''));
}
console.log(
0.00019400000001.dynamicPrecision(), //0.000194
0.0001940001.dynamicPrecision(), //0.000194
0.0001941.dynamicPrecision(), //0.0001941
0.0194.dynamicPrecision(), //0.0194
0.01940000.dynamicPrecision() //0.0194
)

jQuery add two CSS property values

I was trying to get the top position of the element and the margin-bottom value.
that worked:
var top = -$('elem').postion().top; // lets say its -54
var margin = $('elem').css('margin-top'); // lets say its 0
Bud I need to add these up for my animate function. so top+margin but jQuery gives -540 px but it need to return -54 px.. or when its negative it just gives -54-10px when I need -64 px.
Is there someting to get this fixed? I can't come up with it and it annoys me!
My code:
var top = -$('#id1').position().top;
var margin = $('.scrollable').css('margin-top');
var combine = top+margin;
$('.animate').animate({'margin-top' : combine});
Bud i need to add these up for my animate function. so top+margin but jQuery gives 540 p
css values are strings, so since one of your operands is a string, the + is being interpreted as a concatenation operator (54 + "0" = "540"), not an addition operator. (Details) To turn them into numbers, use parseInt(str, 10), e.g.:
// I believe `top` will already be a number; check and if not, use parseInt here too,
// e.g. var top = -parseInt($('#id1').position().top, 10);
var top = -$('#id1').position().top;
// This will definitely be a string that needs parsing; note that we're assuming
// here that the margin has been given in `px` units.
var margin = parseInt($('.scrollable').css('margin-top'), 10);
// Now this + is an addition, not a concatenation
var combine = top+margin;
$('.animate').animate({'margin-top' : -combine});
It's because it returns the values as strings, and using the + operator on them concatenates. You can use parseInt to get a number from a string. It'll even work if there is a px suffix, though it will stop at that.
var top = $('elem').postion().top;
var margin = $('elem').css('margin-top');
var total = parseInt(top, 10) + parseInt(margin, 10);
Try this
var combine = parseInt(top) + parseInt(margin);

String format in javascript

I'd like to format a number and remove starting 0s from it. e.g.:
001 => 1
10 => 10
Actually, I have a jQuery method which does the following:
$('#myelement').text($('#myElement').text()+1);
When the element's text is 0, the function makes it 01, How can I make it to show 1 using jQuery or javascript?
Thanks.
what you need:
parseInt($('#myElement').text(), 10) + 1;
what you're asking for:
($('#myElement').text()+1).replace(/^0+/, '');
You can use parseInt("0010", 10).toString(). Ignore toString() if you need the int only.
Assuming you want to increment the value, convert the current text in to a number using unary +:
$('#myelement').text(function(i, v){
return +v + 1;
});
+"0001" //1
See above! .......
$('#myelement').text(parseInt($('#myElement').text(), 10) + 1);

javascript parseFloat '500,000' returns 500 when I need 500000

How would it be a nice way of handling this?
I already thought on removing the comma and then parsing to float.
Do you know a better/cleaner way?
Thanks
parseFloat( theString.replace(/,/g,'') );
I don't know why no one has suggested this expression-
parseFloat( theString.replace(/[^\d\.]/g,'') );
Removes any non-numeric characters except for periods. You don't need custom functions/loops for this either, that's just overkill.
Nope. Remove the comma.
You can use the string replace method, but not in a one liner as a regexp allows.
while(str.indexOf(',')!=-1)str= str.replace(',','');
parseFloat(str);
Or to make a single expression without a regexp=
return parseFloat(str.split(',').join(''));
I'd use the regexp.
I don't have enough reputation to add a comment, but for anyone wondering on the performance for regex vs split/join, here's a quick fiddle: https://jsfiddle.net/uh3mmgru/
var test = "1,123,214.19";
var t0 = performance.now();
for (var i = 0; i < 1000000; i++)
{
var a = parseFloat(test.replace(/,/g,''));
}
var t1 = performance.now();
document.write('Regex took: ' + (t1 - t0) + ' ms');
document.write('<br>')
var t0 = performance.now();
for (var i = 0; i < 1000000; i++)
{
var b = parseFloat(test.split(',').join(''));
}
var t1 = performance.now();
document.write('Split/join took: ' + (t1 - t0) + ' ms');
The results I get are (for 1 million loops each):
Regex: 263.335 ms
Split/join: 1035.875 ms
So I think its safe to say that regex is the way to go in this scenario
Building on the idea from #kennebec, if you want to make sure that the commas are correct, and you don't want to replace commas, you could try something like this:
function myParse(num) {
var n2 = num.split(",")
out = 0
for(var i = 0; i < n2.length; i++) {
out *= 1000;
out += parseFloat(n2[i])
}
return out
}
alert(myParse("1,432,85"));
// Returns 1432085, as the comma is misplaced.
It may not be as fast, but you wanted alternatives :)
What about a simple function to solve most of the common problems?
function getValue(obj) {
Value = parseFloat( $(obj).val().replace(/,/g,'') ).toFixed(2);
return +Value;
}
The above function gets values from fields (using jQuery) assuming the entered values are numeric (I rather validate fields while user is entering data, so I know for sure field content is numeric).
In case of floating point values, if well formatted in the field, the function will return a float point value correctly.
This function is far from complete, but it quickly fix the "," (comma) issue for values entered as 1,234.56 or 1,234,567. It will return valid number as far the content is numeric.
The + (plus) sign in front of the variable Value in the return command is a "dirty trick" used in JavaScript to assure the variable content returned will be numeric.
it is easy to modify the function to other purposes, such as (for instance), convert strings to numeric values taking care of the "," (comma) issue:
function parseValue(str) {
Value = parseFloat( str.replace(/,/g,'') ).toFixed(2);
return +Value;
}
Both operations can even be combined in one function. I.e.:
function parseNumber(item,isField=false) {
Value = (isField) ? parseFloat( $(item).val().replace(/,/g,'') ).toFixed(2) : parseFloat( item.replace(/,/g,'') ).toFixed(2)
return +Value;
}
In such case, if function is called result = parseNumber('12,092.98'); it will parse the value as it is a String. But if called as result = parseNumber('#MyField', true); it will try to obtain the value from '#MyField'.
As I said before, such functions are far from complete, and can be expanded in many ways. One idea is to check the first character of the given parameter (string) and decide based on the string format where to obtain the value to be parsed (if 1st character is = '#' then it is an ID from a DOM object, otherwise, if it begins with a number, it must be a string to be parsed).
Try it... Happy coding.

Categories

Resources