I want to launch one script if one off several browsers are detected. I made an array with regulars and I want to check if one of them exists in navigator.userAgent string. I want to do it with underscore without FOR EACH.
var browsers = [/chrome/, /opera/];
/* something like: */
if (!_.contains(browsers, navigator.userAgent.toLowerCase()) return;
Using _.some():
if (!_.some(browsers, function(item){
return navigator.userAgent.toLowerCase().test(item);
}) return;
However, I'd recommend using #dystroy's single-regex solution. It's faster, shorter code.
You could do that like this:
var arr = ["chrome", "opera"]; // Strings, not regexes.
var regexp = new RegExp(arr.join('|'), 'i');
if (!regexp.test(navigator.userAgent)) return;
Or, as a one-liner:
if (!RegExp(["chrome", "opera"].join('|'), 'i').test(navigator.userAgent)) return;
A better solution would be to have only one regex, so that you don't have to iterate. And using the i flag lets you avoid the toLowerCase :
if (!/chrome|opera/i.test(navigator.userAgent)) return;
Related
I have a two dimensional array which consists of versions like,
say,
var version = [[B2.0.2.1],[B3.0.2.1], and many more];
How do I split B from these versions because I am only interested in the version that is 2.0.2.1 and so on?
The slice method will be useful in solving your problem.
Here is an example:
var str = "B2.0.2.1";
var res = str.slice(1); // Will result in second character until the end.
// res = "2.0.2.1"
If you use it with a single parameter str.slice(1); you will effectively cut off the first character leaving you with just the version number.. This is assuming that only one letter ever prefixes the versions numbers.
Use array.map to manipulate each element in array
var version = [['B2.0.2.1'],['B3.0.2.1']];
version = version.map(function(ver){
return [ver[0].slice(1)];
});
The simplest way, without loops is using JSON methods
var stripped = JSON.parse(JSON.stringify(version).replace(/B/g, ''));
console.log(stripped);
In this case, I don't even care that your original code is invalid javascript, nor what you'd need to do to fix it, this will get rid of all B's regardless
Here's what's going on. I have a select element, for which I need to get a comma delimited string of all its options, regardless of whether or not it's selected.
How can I, in jQuery/javascript take this:
<select id="currentTags" multiple>
<option>Nature</option>
<option>Cats</option>
<option>Space</option>
</select>
and turn it into this:
"Nature, Cats, Space"
I tried to find ways of doing this and couldn't... I'm still learning javascript, and my limited knowledge is stopping me in my tracks.
Any help would be appreciated, even if it's just to guide me in the right direction.
Thank you for your time.
With jQuery:
var result = $('#currentTags option').map(function(i, opt) {
return $(opt).text();
}).toArray().join(', ');
In plain JavaScript you can do something similar like this:
// Convert pseudo-arrays to real arrays
var __slice = Array.prototype.slice;
// Get select options as real array
var opts = __slice.call(document.querySelectorAll('#currentTags option'));
// Map the text of each option
var result = opts.map(function(x) {
return x.textContent;
}).join(', ');
console.log(result); //=> "Nature, Cats, Space"
The advantage of abstracting elements into collections instead of looping is that you maintain a consistent API (like jQuery), and you don't need to create extra variables to loop pseudo-arrays, as real arrays can use all array methods.
See the MDN to learn more about the DOM and the methods and properties you can use, like querySelectorAll, children, textContent and more.
Edit: This should work in IE9+ and all modern browsers.
The plain old javascript (POJS) way is to get the select's options collection, then loop over it to get the values and generate a string with the required format, e.g.
var options = document.getElementById('currentTags').options;
var values = [];
for (var i=0, iLen=options.length; i<iLen; i++) {
values.push(options[i].text);
}
alert(values.join(','));
You can write that in much more concise form but performance may suffer and depending on features used, may fail in some browsers. The above puts a premium on clarity and maintainability of code, performance will be at least as fast as any alternative.
How about just:
var tags = [];
$('#currentTags option').each(function() {
tags.push($(this).val());
});
console.log(tags.join(', ')); // 'Nature, Cats, Space'
http://jsfiddle.net/wN2Dk/
Here is a simple jQuery example:
var arr = []; // create array
$('#currentTags').children().each(function() {
arr.push($(this).text()); // add option text to array
});
alert(arr.join(', ')); // Nature, Cats, Space
If you want the option value, switch text() to val() ;)
A simple solution would be:
// Initialize your string
var output_string = "";
// For each 'option' tag, append its value to the string with the comma
$('#currentTags option').each(function() {
output_string = output_string+this.text;
});
// Removing the last ', ' which were added during the loop
output_string = output_string.substr(0, output_string.length-2);
Here's a Fiddle to see it into action :)
The question is simple, assume the following string:
var str = 'aaaaab\'s'
How do you extract the value of href. I would think something like
var arr = str.match(/(?:href=")(\w+)/g) ;
--> ["href="aaaa", "href="bb"]
Of course I want
["aaaa", "bb"]
Withoug the /g it get close, but it only matches "aaaa". Any suggestions how to fix this ?
Thanks!
DOM parsing with JS is so easy.
var str = 'aaaaab\'s',
help = document.createElement('div');
helper.innerHTML = str;
Array.prototype.forEach.call(help.querySelectorAll("a[href]"), function (elem) {
console.log(elem.getAttribute('href'));
});
http://jsfiddle.net/ExplosionPIlls/gtdFh/
Because Javascript doesn't have lookbehind, this may be what you want. Naturally there will be more elegant solutions:
input.match(/<[^href|/]*(href[\s]*=[\s]*")([^"]+)(?=">)/g).map(
function(x){return x.split('href')[1].replace(/[^"]+"(.*)/,'$1');
})
Additionally, you may be better off getting a HTML parsing plugin. And extracting the properties you need using that.
Cheers.
I want get my program parameters from rel attribute of element, first of all is it logical ?
and the rel attribute may contain this string rel="_p|b|w=300|h=200" or rel="_p|w=300"
, so I use split to split my string with | pattern :
var attr = $(this).attr('rel').split('|');
for _p and b there is no problem because I can check with indexOf but for w and h I should use regular expression because the w and h value will be change.
how can I use regular expression in indexOf ?
sorry for my bad English
EDIT:
if (attr.indexOf('b')) {
blank = true;
}
First of all, that isn't a very elegant way of retrieving data. Anyway, if you really want to do that in that way, then you can use regexes as follows:
var matches = $(this).attr('rel').match(/w=(\d+)/);
var w = (matches && matches[1]) || defaultValue;
Also, if there can be multiple elements that end in 'w', then you'd better change your regex to something like:
var matches = $(this).attr('rel').match(/(?:^|\|)w=(\d+)/);
I would have suggested the use of custom attributes as well, however these would not be w3-conform as you want them to.
A simple way would be to split the parameters and then loop through and check each index whether it is one of the attributes you are expecting:
var cust_params = $(this).attr('rel').split('|'); //or this.rel as GGG suggested in a comment?
for(var i=0;i<cust_params.length;i++) {
if('_p'==cust_params[i]) {
//...
}
//...
if(cust_params[i].match(/w=(\d+)/)) {
//you could even do this without a regular expression
}
}
I hope this doesn't violate some good practice that I'm unaware of because I always feel like there must be a more elegant way when I do this kind of thing :) As it is I get a kind of quick-and-dirty feel about this.
Sorry there is no way you can do it in one command with normal javascript, indexOf just doesn't support regular expression.
You can either loop through the array or use jquery supported command for array.
For example: once you have the array attr as you like, you can use jQuery.grep() http://api.jquery.com/jQuery.grep/
a_equal = jQuery.grep(attr, function(a, i){
return (a.match(/=/) and i > 0); // modify this as you like
});
to create an array a_equal with all the assignment argument.
disclaimer.. code not yet tested.
Like Paolo Bergantino I'd also suggest using data-attributes, or you could store the data in a JSON (again, in a data attribute) and parse that:
<a href="#" data-info='{"width": "300", "height": "200", "color": "#fff", "etc": "foo"}'>
var info = JSON.parse(a.getAttribute('data-info'));
Edit: replaced eval with Phrogz's suggestion.
(With eval: eval('(' + a.getAttribute('data-info') + ')'))
I have a string which I need to split into an array and then perform mathematical functions on each element of the array.
Currently I am doing something like this. (Actually, I am doing nothing like this, but this is a very simple example to explain my question!
var stringBits = theString.split('/');
var result = parseInt(stringBits[0]) + parseInt(stringBits[3]) / parseInt(stringBits[1]);
What I would like to know is if there is a way I can convert every element of an array into a certain type that would stop me from having to explicitly parse it each time.
An easier method is to map to the Number object
result= stringBits.map(Number);
javascript 1.6. has map() ( https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Array/Map ), so you can do something like
intArray = someArray.map(function(e) { return parseInt(e) })
You can just loop through it:
for(var i = 0; i < stringBits.length; i++) {
stringBits[i] = parseInt(stringBits[i]);
}
["1","2"].map(Number)
result: [1,2]
If you add a plus (+) sign in front of your strings they should be converted to numeric.
For example, this will print 3:
var x = "1";
var y = "2";
alert((+x) + (+y));
But I am not sure if this is portable to all browsers.
Your code will become:
var stringBits = theString.split('/');
var result = (+stringBits[0]) + (+stringBits[3]) / (+stringBits[1]);
But this is just a hack, so use with care.
I think the parseInt states better what you are trying to do, but you should delegate this responsibility to another method that returns the final data that you need to process. Convert and then process, don’t convert while processing. Your code will be easier to read.