Javascript: Which of these implementations is more efficient/better? - javascript

I have an icon that when clicked will increase the value of a number input.
I initially wrote it as:
$('.icon-chevron-up').click(function(){
var input = $(this).next();
var value = eval(input.val());
input.val((value+1).toString());
$(this).next.val(value+1);
});
I then rewrote it as:
$('.icon-chevron-up').click(function(){
$(this).next().val((eval($(this).next().val()) + 1).toString());
});
Is there a preferred way of doing this? And if so, why?

None of those would be the best for efficiency. eval is not needed and if you want performance you should cache your selectors. There are a couple ways you could make it more efficient but I would do it like this:
$('.icon-chevron-up').click(function() {
var $this = $(this),
val = $this.next().val();
$this.next().val( ++val + '' );
});
++ casts val to a number and adds 1. + '' casts the previous number to a string.
If you want something less terse (more readable I guess):
$this.next().val( (parseInt( val,10 ) + 1).toString() );

What do you mean by input? should it be text input or just a html tag?
<button class="icon-chevron-up">Increase</button>
<div id="numinput">12</div>
var input = $('#numinput').html();
$('.icon-chevron-up').click(function(){
input++;
$('#numinput').html(input);
});

Related

Take tag value and do an arithmetic operation with jquery

This can be sound ridiculous, but i really want to know if this is possible, and how to make it.
This is my first time in StackOverflow about asking, because i learn here how to code with style, sure with the questions of people like me. Thanks for make me feel like if Stackoverflow is were my house.
Let's ask.
I'm making a php script, more faster than Donald Trump begun to hate the Oreo's cookies.
The script prints this as code HTML
<strong>$</strong><h1>1800</h1>USD
<strong>$</strong><h1>800</h1>USD
So, this is when the mad situation comes...
Whit Jquery i want to take the both h1 elements and i want to make aritmetic operations whit them. I can do this with php and mysql, i know. But about time, i prefer to do this with jQuery.
¿Is there anybody to can help me?
Crazy and very very simple example:
H1 + H1 OR H1 - H1 = NUMBER RESULT OF THE OPERATION.
If you want to get the summation, you can use this code :
var total = 0;
$("h1").each(function(index, item) {
total += Number($(item).text());
});
alert(total);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<strong>$</strong><h1>1800</h1>USD
<strong>$</strong><h1>800</h1>USD
You can use jquery .each(function(){}) to iterate and find out text in each of h1 tag.For demo I put them inside an array and can apply any mathematical operation
var a=[];
$('h1').each(function(){
var tempText = $(this).text().trim(); // Remove white space
console.log(tempText)
a.push(tempText)
})
Edit
Use parseInt to convert it to integer
`var tempText = parseInt($(this).text().trim());` // Converts to integer
So a will be now an array of integers
Example
Hello you can do it like this
var sum = 0;
$('h1').each(function(k,v){
sum += parseInt($(v).text())
})
console.log(sum)
Crazy and very simple:
$("strong")
.next("h1")
.get()
.map(function(el){
return $(el).text();
})
.reduce(function(a,b){
return parseInt(a)+parseInt(b);
})
[ https://jsfiddle.net/hLwxrpoq/ ]
Try using .eq() to cache h1 elements , .html() to return results; + operator to cast text to Number
// select all `h1` elements
var h = $("h1");
// results
var result = $("#result");
// first `h1`
var first = h.eq(0).text();
var second = h.eq(1).text();
result.html(function() {
var add = +first + +second;
var subtract = +first - +second;
return "Add first `h1` to second `h1`:" + add
+ "<br>Substract second `h1` from first `h1`:" + subtract
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<strong>$</strong><h1>1800</h1>USD<br>
<strong>$</strong><h1>800</h1>USD<br>
<br>
<div id="result"></div>
You retrieve the inner text of the HTML by using .text() and parse it as an integer using parseInt as the others above have explained.
You can then append it to your HTML after that.
Your HTML might look like this:
<div id="math">
<h1>800</h1>
<h1>1800</h1>
</div>
<h1 id="answer"></h1>
And your jquery like this:
var math = $("#math"); //Get the math element
var numbers = math.find('h1'); //Get all the numbers from the math div
var answer = $("#answer"); //Get the element
var total = 0;
numbers.each( function() {
total += parseInt( $(this).text() ); // Add each number together
});
answer.append( total ); // Append the total to the answer element
Here is a fiddle.
https://jsfiddle.net/75qxy57d/1/

JQuery converting "option:contains" into an exact string value

Right now I am getting a select option's value (literal value attribute) from JQuery, the problem is that it takes the first value it finds that simply "contains" that keyword.
For example, if I had a select with two options: Silver Division (value=1) and Silver (value=2), if I called the following line of code it would return (value=1) rather than (value=2)
var ranking = "Silver"; // hard-coded for example
var setIndex = $("#userElo" +" > option:contains(" + ranking + ")").val();
Q: I have been trying to search, with no success, for something like option:equals so that it only looks for exact string matches. I have tried various test-and-guess things like the following.
var setIndex = $("#userElo" + ID + " > option:contains" + ranking).val();
var setIndex = $("#userElo" + ID + " > option[text=" + ranking + "]").val();
var setIndex = $("#userElo" + ID + " > option[text=" + ranking).val();
Here is a JSFiddle Demo on a simple scale showing the Silver Division and Silver issue.
I am running out of ideas though, so if anyone know of some syntax for this solution that'd be awesome!
Thanks!
You'll need to select all of the options that may potentially match, then use the filter() function to narrow them down to those that do actually match the text you want. This should do it:
var ranking = "Silver";
var setIndex = $("#userElo > option").filter(function() {
return $(this).text() === ranking;
}).val();

Incrementing Number Inside String

For a client's requirement, I have set out several images as follows:
img/img1.jpg
img/img2.jpg
img/img3.jpg
...
img/img4.jpg.
Now, I need to make the function that loads images dynamic. At the moment, the current solution is as follows:
// Grab the last image path
var lastImagePath = $("lastImage").attr("src");
// Increment the value.
var nextImagePath = "img/img" + (+lastImagePath.replace("img/img").replace(".jpg") + 1) + ".jpg";
// So on.
I was wondering if there's a cleaner way to increment the number?
Slightly cleaner:
var nextImagePath = lastImagePath.replace(/\d+/, function (n) { return ++n; });
This uses the version of replace that accepts a regular expression and a function.

How to fix Javascript NaN issue?

Here is my code
var total_center_buttons=$('.center_button').length;
var center_button_height=$('.center_button:first-child').height();
var total_center_button_height=total_center_buttons + center_button_height;
alert(total_center_button_height);
Here total_center_button value =3
and center_button_height is 40 while alerting them separately.It returns NaN. I tried ParseInt also but result is same.Please suggest me the solution.Thanks in advance.
Krishna
We have to guess, since you haven't quoted the DOM, but my guess is that $('.center_button:first-child') doesn't match any elements. Calling height() on an empty set returns undefined. When you try to add it to the number from the previous line, you get NaN.
I suspect you didn't want :first-child, but rather
var center_button_height=$('.center_button').first().height();
...but again without seeing the DOM, it's hard to say. To avoid repeated DOM lookups, you'd do this:
var buttons = $('.center_button');
var total_center_buttons = buttons.length;
var center_button_height = buttons.first().height();
var total_center_button_height = total_center_buttons + center_button_height;
alert(total_center_button_height);
.center_button:first-child will only match an element that both has the class center_button and is the first child of its parent element. My suggestion above is based on the assumption that you really wanted the first of the buttons, and that the buttons aren't the first thing in their parent.
Finally: That + in
var total_center_button_height = total_center_buttons + center_button_height;
looks suspicious. Again without seeing the markup it's hard to say, but you may have meant * there.
Mate,
there's a typo in your post. Notice the code line where you assign the value to total_center_button_height
var total_center_button_height = center_button_height + total_center_button_height;
That's where the problem is, the variable to the right of the addition operation (total_center_button_height) does not exist yet. Replace that line with...
var total_center_button_height = center_button_height + total_center_buttons;
Pretty straight forward
Hope it helps
Leo
may be you need to write this
var total_center_button_height=center_button_height + total_center_buttons;
alert(total_center_button_height);
you can check for "isNaN" function, this is to check whether the parameter is number or not.
Try this:
$(function(){
var total_center_buttons = $('.center_button').length > 0 ? $('.center_button').length : 0;
if(total_center_buttons !=0){
var center_button_height=$('.center_button:first-child').height();
var total_center_button_height = center_button_height + total_center_button_height;
alert(total_center_button_height);
}
});
you are doing this:
var total_center_button_height=center_button_height + total_center_button_height;
i.e. total_center_button_height is used in the same line where it is declared. At this time it is undefined.
i guess, you should be doing:
var total_center_button_height=center_button_height + total_center_buttons;
Try something like this:
var total_center_buttons=$('.center_button').length;
if (typeof total_center_buttons != 'undefined') {
var center_button_height=$('.center_button:first-child').height();
var total_center_button_height=total_center_buttons + center_button_height;
alert(total_center_button_height);
}

Check if number is between 2 values

I am currently building a filter based on div class's and contents.
I was wondering if it is possible to pass a string like follows into a function:
"£0.01 - £100.01"
and then have the function show all div's where the html of that div is between this range
so say I have a div with a class of "price" and its contents were: £10.30
from running this function and passing the string of "£0.01 - £100.01" into it it would hide all div's similar to how I have done it in the js below then only show the div's where the div class "price"'s contents were within the selected price range.
I have managed to do something similar with a brand filter which I will provide here:
function brand(string){
var brand = string;
$('.section-link').hide();
$('.section-link').children('.brand.' + brand).parent().show();
if (brand == "All Brands"){
$('.section-link').show();
}
}
Any general advice or code is greatly appreciated to help achieve this :)
Thanks,
Simon
Edit:
Target div example:
<div class="section-link">
<div class="price"> £56.99</div>
</div>
Reply's are helping a lot, the filter function looks awesome so thanks for pointing that out.
I am just trying to find a way to split the initial string being past in, into two values one low and one high as well as stripping the £ signs
Edit:
managed to split the original string:
var range = string.replace(/\u00A3/g, '');
var rangearray = range.split("-");
alert(rangearray[0]);
alert(rangearray[1]);
FINAL EDIT:
From the reply's I have kind of been able to make a function, however it is not entirely working :) can anyone spot what I have done wrong?
function price(string){
$('.section-link').hide();
var range = string.replace(/\u00A3/g, '');
var rangearray = range.split("-");
low = rangearray[0];
high = rangearray[1];
$('.section-link').children('.price').each(function() {
var divprice = $(this).text().replace(/\u00A3/g, '');
if (low <= divprice && high >= divprice){
$(this).parent().show();
}
})
}
Okay its working, I had spaces in my string. The final function (although messy :P) is:
function price(string){
$('.section-link').hide();
var range = string.replace(/\u00A3/g, '');
var rangearray = range.split("-");
low = rangearray[0].toString();
high = rangearray[1].toString();
lowmain = low.replace(/ /g,'');
highmain = high.replace(/ /g,'');
$('.section-link').children('.price').each(
function() {
var divprice = $(this).text().replace(/\u00A3/g, '');
var maindivprice = divprice.replace(/ /g,'');
if (lowmain <= maindivprice && highmain >= divprice){
$(this).parent().show();
}
})
}
I'd use a function like this one, where range is the string you gave
function highlightDivs(range) {
var lower = range.split(" ")[0].slice(1);
var upper = range.split(" ")[2].slice(1);
$('.section-link').hide();
$('.section-link').children('.price').each(function() {
if (lower <= $(this).val() && upper >= $(this).val()){
$(this).parent().show();
}
});
}
You can use jQuery's build in filter() function, and write a filter with the condition you described.
First, you should hide all the items with any price.
$(".price").parent().hide();
Then, you can filter all the items with in-range prices and show them:
$(".price").filter(function(){
var $this = $(this);
var value = $this.val();
return (value >= minNumber && value <= maxNumber); // returns boolean - true will keep this item in the filtered collection
}).parent().show();
Use jQuery's filter()
An example -> http://jsfiddle.net/H6mtY/1/
var minValue = 0.01,
maxValue = 100.01;
var filterFn = function(i){
var $this = $(this);
if($this.hasClass('amount')){
// assume that text is always a symbol with a number
var value = +$this.text().match(/\d+.?\d*/)[0];
if(value > minValue && value < maxValue){
return true;
}
}
return false;
};
// apply your filter to body for example
$('#target span')
.filter(filterFn)
.each(function(i,ele){
// do something with the selected ones
$(this).css('color','red');
});
I would go by something like:
Get all the divs that have prices.
Iterate through all:
Transform the strings (minus the pound symbol) to float numbers and compare with an IF statement if they are inside the provided range.
If they are just go to the next (use continue maybe)
Else (not in the range) add a class like .hide so it can be blended through css (or just use the blend function from jquery)

Categories