why the code in jquery doesn't work? - javascript

the url is as this: http://example.com/download/
var pathname = window.location.pathname;
if(pathname=='download/'){
$("#subnav-content div:first").hide();
$("#subnav-content div:second").show();
}
why the above code in jquery doesn't work? i want to when the url is http://example.com/download/. show the secong div.
ps*:does this check affect the site performance?*

You need the leading slash.
'/download/'
If you expect query string parameters you may try a regular expression to just match the download portion of the url: the following matches /download/.
if (window.location.pathname.match(/^\/download\//i))
Regarding the jquery, there is no :second, you need to use :eq(1)
var pathname = window.location.pathname;
if(pathname=='/download/'){
$("#subnav-content div:first").hide();
$("#subnav-content div:eq(1)").show();
}
Response to comments
I'm putting my comment here because the formatting is horrible in the comments. The regular expression for matching download can be summed up as follows:
/ - start of regular expression matching syntax
^ - means start matching at the very start of the screen
\/ - means match the literal string '/', which is a special character which must be escaped
download - match the literal string 'download'
\/ - again means match the literal string '/'
/ - end of the matching syntax
i - regular expression options, i means ignore case
It was not clear to me what your other note was asking for.

Second is not a selector. You want:
$("#subnav-content div:nth-child(2)").show();

Try using
$("#subnav-content div:eq(0)")
$("#subnav-content div:eq(1)")
Also, you need to bind the code to an Event that will get fired when the Document is ready(load, or onDOMReady where supported) otherwise the divs might not exist in memory yet.
ps*:does this check affect the site performance?*
Every line of code has an effect on site performance. Not necessarily a visible one although.

Related

jQuery parameters replace and upload between two strings in all URL's

WordPress' FacetWP plugin has a 'facetwp-loaded' jQuery event that allows for changes when facets are refreshed.
This is the 'facetwp-loaded' event's usage from FacetWP's documentation:
(function($) {
$(document).on('facetwp-loaded', function() {
// Changes go here
});
})(jQuery);
Facets produce URL's like:
http://website.com/hotels?fwp_location=worldwide
or
http://website.com/hotels/worldwide?fwp_location=europe
So I would like to make a global Regex redirection to substitute what is between
hotels
and
=
with
/
In the above examples, that would result in:
http://website.com/hotels/worldwide
or
http://website.com/hotels/europe
Can someone help me with this?
Thanks in advance
UPDATE
I've tried different Regex methods, but it seems to need jQuery parameter replace/update.
I don't have a way to test this using the Wordpress regex engine, so you'll have to check it, but it works in the R regex engine. Hopefully Wordpress supports perl style regex expressions.
Regex: Match: (?<=hotels).*?= and replace with /
In this case the piece of the string we want to remove is preceded by "hotels" and ends with an equal sign. So we want to match everything immediately after hotels, ending at the equal sign. To start matching immediately after "hotels" but not include it, we need to look backwards. So we use a look behind before the match. (?<=hotels) means look backwards from the current position in the string, and see if "hotels" precedes the current position. So when the engine gets to the "/" after hotels, it looks back and sees hotels (but it doesn't match, because it's a look behind). . matches any character, * means match zero or more (so zero or more of any character), and ? modifies the * telling the star to match zero or more characters, but only until the next character can be matched, in this case =.

How do I match URLs with regular expressions?

We want to check if a URL matches mail.google.com or mail.yahoo.com (also a subdomain of them is accepted) but not a URL which contains this string after a question mark. We also want the strings "mail.google.com" and "mail.yahoo.com" to come before the third slash of the URL, for example https://mail.google.com/ is accepted, https://www.facebook.com/mail.google.com/ is not accepted, and https://www.facebook.com/?mail=https://mail.google.com/ is also not accepted. https://mail.google.com.au/ is also not accepted. Is it possible to do it with regular expressions?
var possibleURLs = /^[^\?]*(mail\.google\.com|mail\.yahoo\.com)\//gi;
var url;
// assign a value to var url.
if (url.match(possibleURLs) !== null) {
// Do something...
}
Currently this will match both https://mail.google.com/ and https://www.facebook.com/mail.google.com/ , but we don't want to match https://www.facebook.com/mail.google.com/.
Edit: I want to match any protocol (any string which doesn't contain "?" and "/") followed by a slash "/" twice (the string and the slash can both be twice), then any string which doesn't contain "?" and "/" (if it's not empty, it must end with a dot "."), and then (mail\.google\.com|mail\.yahoo\.com)\/. Case insensitive.
Not being funny - but why must it be a regular expression?
Is there are reason why you couldn't simplify the process using URL (or webkitURL in Chrome and Safari) - the URL constructor simply takes a string and then contains properties for each part of the URL. Whether it supports all the host types that you want to support, I don't know.
Granted, you might still need a regex after that (although really you'd just be checking that the hostname ends with either yahoo.com or google.com), but you would just be running it against the hostname of the URL object rather than the whole URI.
The API is not ubiquitous, but seems reasonably well supported and, anyway, if this is client-side validation then I hope you're checking it on the server, too, because sidestepping javascript validation is easy.
How about
^[a-z]+:\/\/([^.\/]+\.)*mail\.(google|yahoo).com\/
Regex Example Link
^ Anchors the regex at the start of the string
[a-z]+ Matches the protocol. If you want a specific set of protocols, then (https?|ftp) may do the work
([^.\/]+\.)* matches the subdomin part
^([-a-z]+://|^cid:|^//)([^/\?]+\.)?mail\.(google|yahoo)\.com/
Should do the trick
The first ^ means "match beginning of line", the second negates the allowed characters, thus making a slash / not allowed.
Nb. You still have to escape the slashes, or use it as a string in new RegExp(string):
new RegExp('^([-a-z]+://|^cid:|^//)([^/\?]+\.)?mail\.(google|yahoo)\.com/')
OK, I found that it works with:
var possibleURLs = /^([^\/\?]*\/){2}([^\.\/\?]+\.)*(mail\.google\.com|mail\.yahoo\.com)\//gi;

Allowing for wildcard at end of url for javascript conditional css style

I have a script working that switches stylesheet depending on the url.
It has to be done this way because the site uses smarty templates and I don't want to alter the core files or the core css.
Right now I have to add the URL pathname of each individual page. The more pages there are, the more impractical this is.
So for example, instead of /ojs/index.php/index/user/register and /ojs/index.php/index/user/profile I would like to call /ojs/index.php/index/user/* so then all pages under /user/ would have the stylesheet applied to them.
What is the best way to do this? I have seen a couple of similar posts but not exactly what I need.
var loc = window.location;
var currentURL = loc.pathname;
if (currentURL=='/ojs/index.php/index' || currentURL=='/ojs/' || currentURL=='/ojs/index.php/index/about' || currentURL=='/ojs/index.php/index/user/register' || currentURL=='/ojs/index.php/index/user/profile' || currentURL=='/ojs/index.php/index/admin/' || currentURL=='/ojs/index.php/index/admin/auth')
loadjscssfile("/ojs/plugins/themes/main-theme/main-theme.css", "css")
You could use a Regular Expression.
// unless you were using loc for something else, there is no need to store it,
// just chain to get the pathname
var currentURL = window.location.pathname,
// create a regular expression that will match all pages under user
usersPattern = new RegExp('^/ojs/index\.php/index/user/.*');
if (usersPattern.test(currentURL)) {
loadjscssfile("/ojs/plugins/themes/main-theme/main-theme.css", "css")
}
As always is the case with regex, you need to be careful what you are doing to get it right. Here's a short explanation of how this expression works:
^ tells it to only match if the string starts with /ojs/, etc
The \. in the middle escapes the ., telling it that the . in index.php is a literal dot
The . at the end will match any character
The * following the . will match 0 or more instances of the previous character (any character in this case)
I created this regex with the RegExp constructor function, but it could also have been done with a regular expression literal. Generally it is a better idea to use a literal but in this case I used the constructor because since it takes a string as an argument I didn't have to escape the / characters in the pattern. If we were to do it with a literal, instead of this:
usersPattern = new RegExp('^/ojs/index\.php/index/user/.*');
It would look like this:
usersPattern = /^\/ojs\/index\.php\/index\/user\/.*/;
Not needing to escape those / makes it a little more readable.

How to get data from string using Javascript Regex

I can't post the exact data i'm trying to extract but here's a basic scenario with the same outcome. I'm grabbing the body of a page and trying to extract a bit.ly link from it. So let's say for example, this is the chunk of data where i'm trying to grab the link from.
String:
http://bit.ly/Pq8AkS</div><div class="shareUnit"><div class="-cx-PRIVATE-fbTimelineExternalShareUnit__wrapper"><div><div class="-cx-PRIVATE-fbTimelineExternalShareUnit__root -cx-PRIVATE-fbTimelineExternalShareUnit__hasImage"><a class="-cx-PRIVATE-fbTimelineExternalShareUnit__video -cx-PRIVATE-fbTimelineExternalShareUnit__image -cx-PRIVATE-fbTimelineExternalShareUnit__content" ajaxify="/ajax/flash/expand_inline.php?target_div=uikk85_59&share_id=271663136271285&max_width=403&max_height=403&context=timelineSingle" rel="async" href="#" onclick="CSS.addClass(this, "-cx-PRIVATE-fbTimelineExternalShareUnit__loading");CSS.removeClass(this, "-cx-PRIVATE-fbTimelineExternalShareUnit__video");"><i class="-cx-PRIVATE-fbTimelineExternalShareUnit__play"></i><img class="img" src="http://external.ak.fbcdn.net/safe_image.php?d=AQDoyY7_wjAyUtX2&w=155&h=114&url=http%3A%2F%2Fi1.ytimg.com%2Fvi%2FDre21lBu2zU%2Fmqdefault.jpg" alt="" /></a>
Now, I can get what i'm looking for with the following code but the link isn't always going to be exactly 6 characters long. So this causes an issue...
Body = document.getElementsByTagName("body")[0].innerHTML;
regex = /2Fbit.ly%2F(.{6})&h/g;
Matches = regex.exec(Body);
Here's what I was orginally trying but the problem I have is that it grabs too much data. It's going all the way to the last "&h" in the string above instead of stopping at the first one it hits.
Body = document.getElementsByTagName("body")[0].innerHTML;
regex = /2Fbit.ly%2F(.*)&h/g;
Matches = regex.exec(Body);
So basically the main part of the string i'm trying to focus on is "%2Fbit.ly%2FPq8AkS&h" so that I can get the "Pq8AkS" out of it. When I use the (.*) it's grabbing everything between "%2F" and the very last "&h" in the large string above.
You should not be using a regex on HTML. Use DOM functions to get the desired link object, then get the href attribute from that, then you can use a regex on just the href.
By default .* is greedy meaning that it matches the most it can match and still find a match. If you want it to be non-greedy (match the least possible), you can use this .*? instead like this:
regex = /2Fbit.ly%2F(.*?)&h/;
I also don't think you want the g flag on the regex as there should only be one match in the right URL.
If you show the rest of your HTML, we could offer advice on finding the right link object rather than trying to match the entire body HTML.
FYI, another trick for a non-greedy match is to do something like this:
regex = /2Fbit.ly%2F([^&]*)&h/;
Which matches a series of characters that are not & followed by &h which accomplishes the same goal as long as & can't be in the matched sequence.
By default + and * are greedy and match as much as possible. You need a non-greedy match for your (.+). A quick search gives the solution as
? directly following a quantifier makes the quantifier non-greedy (makes it match minimum instead of maximum of the interval defined).
So try changing your regex= line to
regex = /2Fbit.ly%2F(.*?)&h/g;
Edit: #jfriend00's answer below is more complete.

Regular expression to remove a file's extension

I am in need of a regular expression that can remove the extension of a filename, returning only the name of the file.
Here are some examples of inputs and outputs:
myfile.png -> myfile
myfile.png.jpg -> myfile.png
I can obviously do this manually (ie removing everything from the last dot) but I'm sure that there is a regular expression that can do this by itself.
Just for the record, I am doing this in JavaScript
Just for completeness: How could this be achieved without Regular Expressions?
var input = 'myfile.png';
var output = input.substr(0, input.lastIndexOf('.')) || input;
The || input takes care of the case, where lastIndexOf() provides a -1. You see, it's still a one-liner.
/(.*)\.[^.]+$/
Result will be in that first capture group. However, it's probably more efficient to just find the position of the rightmost period and then take everything before it, without using regex.
The regular expression to match the pattern is:
/\.[^.]*$/
It finds a period character (\.), followed by 0 or more characters that are not periods ([^.]*), followed by the end of the string ($).
console.log(
"aaa.bbb.ccc".replace(/\.[^.]*$/,'')
)
/^(.+)(\.[^ .]+)?$/
Test cases where this works and others fail:
".htaccess" (leading period)
"file" (no file extension)
"send to mrs." (no extension, but ends in abbr.)
"version 1.2 of project" (no extension, yet still contains a period)
The common thread above is, of course, "malformed" file extensions. But you always have to think about those corner cases. :P
Test cases where this fails:
"version 1.2" (no file extension, but "appears" to have one)
"name.tar.gz" (if you view this as a "compound extension" and wanted it split into "name" and ".tar.gz")
How to handle these is problematic and best decided on a project-specific basis.
/^(.+)(\.[^ .]+)?$/
Above pattern is wrong - it will always include the extension too. It's because of how the javascript regex engine works. The (\.[^ .]+) token is optional so the engine will successfully match the entire string with (.+)
http://cl.ly/image/3G1I3h3M2Q0M
Here's my tested regexp solution.
The pattern will match filenameNoExt with/without extension in the path, respecting both slash and backslash separators
var path = "c:\some.path/subfolder/file.ext"
var m = path.match(/([^:\\/]*?)(?:\.([^ :\\/.]*))?$/)
var fileName = (m === null)? "" : m[0]
var fileExt = (m === null)? "" : m[1]
dissection of the above pattern:
([^:\\/]*?) // match any character, except slashes and colon, 0-or-more times,
// make the token non-greedy so that the regex engine
// will try to match the next token (the file extension)
// capture the file name token to subpattern \1
(?:\. // match the '.' but don't capture it
([^ :\\/.]*) // match file extension
// ensure that the last element of the path is matched by prohibiting slashes
// capture the file extension token to subpattern \2
)?$ // the whole file extension is optional
http://cl.ly/image/3t3N413g3K09
http://www.gethifi.com/tools/regex
This will cover all cases that was mentioned by #RogerPate but including full paths too
another no-regex way of doing it (the "oposite" of #Rahul's version, not using pop() to remove)
It doesn't require to refer to the variable twice, so it's easier to inline
filename.split('.').slice(0,-1).join()
This will do it as well :)
'myfile.png.jpg'.split('.').reverse().slice(1).reverse().join('.');
I'd stick to the regexp though... =P
return filename.split('.').pop();
it will make your wish come true. But not regular expression way.
In javascript you can call the Replace() method that will replace based on a regular expression.
This regular expression will match everything from the begining of the line to the end and remove anything after the last period including the period.
/^(.*)\..*$/
The how of implementing the replace can be found in this Stackoverflow question.
Javascript regex question

Categories