3

I have a jQuery plugin that overrides link behavior, to allow Ajax loading of page content. Simple enough with a delegated event like $(document).on('click','a', function(){});.

but I only want it to apply to links that are not like these ones (Ajax loading is not applicable to them, so links like these need to behave normally):

target="_blank"      // New browser window
target="_self"       // Force replacement of current window (specific to my plugins)
href="#..."          // Bookmark link (page is already loaded). 
href="afs://..."     // AFS file access. 
href="cid://..."     // Content identifiers for MIME body part.
href="file://..."    // Specifies the address of a file from the locally accessible drive.
href="ftp://..."     // Uses Internet File Transfer Protocol (FTP) to retrieve a file.
href="http://..."    // The most commonly used access method. 
href="https://..."   // Provide some level of security of transmission 
href="mailto://..."  // Opens an email program.
href="mid://..."     // The message identifier for email.
href="news://..."    // Usenet newsgroup.
href="x-exec://..."  // Executable program.
href="http://AnythingNotHere.com"  // External links

Sample code:

$(document).on('click', 'a:not([target="_blank"])', function(){
    var $this = $(this);
    if ('some additional check of href'){
        // Do ajax load and stop default behaviour
        return false;
    }
    // allow link to work normally
});

Q:

Is there a way to easily detect all "local links" that would only navigate within the current website? excluding all the variations mentioned above.

Note: This is for an MVC 5 Razor website, so absolute site URLs are unlikely to occur.

iCollect.it Ltd
  • 92,391
  • 25
  • 181
  • 202
  • 4
    Why downvote? I don't see anything wrong with this well composed question. – VisioN Jun 06 '14 at 14:50
  • 1
    Down-voter(s) (plural now)... Useful comments please? This is a perfectly valid question. – iCollect.it Ltd Jun 06 '14 at 14:50
  • I might use the selector `a:not([href*="://"])`, then combine it with the others. A single selector probably isn't possible. – Blazemonger Jun 06 '14 at 14:53
  • @Quentin: I saw that question already and this is not a duplicate (not exactly the same question). Please read the specific details. – iCollect.it Ltd Jun 06 '14 at 14:53
  • This discussion may be related: http://meta.stackoverflow.com/q/251758/1249581. – VisioN Jun 06 '14 at 14:54
  • 1
    In what way is it not a duplicate? being able to identify the links as external to add a class is the same as being able to identify them to exclude them from your selection. – Kevin B Jun 06 '14 at 14:55
  • I can't see how it isn't the same problem. – Quentin Jun 06 '14 at 14:56
  • I mean, it isn't an EXACT duplicate, but the answer definitely is there. – Kevin B Jun 06 '14 at 14:56
  • @Quentin: I have read the answers there and *if that were the case* we would not have the excellent NEW answer below :P Did anyone not see how *out of date* those 4 year old answer were??? – iCollect.it Ltd Jun 06 '14 at 14:58
  • @TrueBlueAussie — You've got multiple people unable to tell the difference between your problem and that problem. If there really is a different, then you haven't explained it well enough for us to tell what it is. Try adding further explanation. – Quentin Jun 06 '14 at 14:59
  • If you think an answer is out of date, then post a comment to that effect on it (explain what the problem with the answer is, just being old is not a problem). That will warn new people reading it and may encourage the person who wrote the answer to update it. – Quentin Jun 06 '14 at 15:00
  • `mailto` links don't use `://`, just `:` – Blazemonger Jun 06 '14 at 15:01
  • @Blazemonger: Just copied from http://www.java2s.com/Code/HTMLCSSReference/HTML-Attributes-Reference/hrefPossibleValues.htm – iCollect.it Ltd Jun 06 '14 at 15:02
  • @Quentin: You may well be right, but the chances of them competing with a 27 rated *old-as-the-hills* answer is slim. I don't think this new question, with additional requirements, diminishes SO so thank you for reopening. Cheers :) – iCollect.it Ltd Jun 06 '14 at 15:09
  • The person who wrote that answer is an active user of SO, i'd be surprised if he didn't respond/update his answer when prompted by a comment. – Kevin B Jun 06 '14 at 15:38
  • @Kevin B: Just saw your comment there. Also saw that Blazemonger has added another variation of his answer there, to match that *slightly different* question's *slightly different* requirements (*gosh, what a day*):) – iCollect.it Ltd Jun 06 '14 at 15:46
  • Unfortunately i forgot to @ target him, he may not see it. it's too late to edit now. In either case, future users to the question will at least have the chance to see my comment. – Kevin B Jun 06 '14 at 15:47

2 Answers2

4

I might use the selector:

$('a:not([href*="://"],[target="_blank"],[href^="#"],[href^="mailto:"])')

http://jsfiddle.net/mblase75/Pavg2/

Note that mailto: is correct, not mailto:// as in your original question.


In the interest of thoroughness, the following will also catch internal links that use absolute URLs (http://the-domain-you-are-on-now.com/whatever.html):

$('a:not([href*="://"],[target="_blank"],[href^="#"],[href^="mailto:"]),a[href^="'+location.protocol+'//'+location.hostname+'"]')

http://jsfiddle.net/mblase75/Pavg2/4/

Blazemonger
  • 90,923
  • 26
  • 142
  • 180
  • Suggest you also post this to http://stackoverflow.com/questions/2910946/test-if-links-are-external-with-jquery-javascript – iCollect.it Ltd Jun 06 '14 at 15:04
  • 1
    Are you admitting that it's a duplicate question? – Blazemonger Jun 06 '14 at 15:05
  • No, just that the answer also covers that one. You will note there is no `mailto` or other custom links in their question :) – iCollect.it Ltd Jun 06 '14 at 15:07
  • +1 and accepted: Works a treat. And looks nothing like the other answers on the *alleged duplicate* :> – iCollect.it Ltd Jun 06 '14 at 15:11
  • +1 for the nice jsFiddle but should handle case for internal links using absolute path too, or i'm wrong?! – A. Wolff Jun 06 '14 at 15:14
  • @A.Wolff You mean internal links using the same domain name? A reasonable constraint, but OP didn't ask for that. I'll see what I can come up with, though. – Blazemonger Jun 06 '14 at 15:15
  • It's an MVC Razor site (not mentioned, will update), so absolute site URLs are unlikely to occur. – iCollect.it Ltd Jun 06 '14 at 15:17
  • Very nice update... Quite complete now. Shame I can't up-vote twice :) – iCollect.it Ltd Jun 06 '14 at 15:28
  • Forgot I also needed to treat `target="_self"` as a normal link. Have added to question and changed your answer to `$('a:not([href*="://"],[target="_blank"],[target="_self"],[href^="#"],[href^="mailto:"]),a[href^="'+location.protocol+'//'+location.hostname+'"]')` – iCollect.it Ltd Jun 06 '14 at 15:39
  • Strictly speaking, `target` attributes are not an indication of whether a link is actually internal or external, so I think that would be of little value to others. – Blazemonger Jun 06 '14 at 15:42
  • True: `"_self" puts the new document in the same window and frame as the current document. "_self" works the same as if you had not used TARGET at all.` but in my situation I need to be able to force a local *full-page* change. Thanks – iCollect.it Ltd Jun 06 '14 at 15:48
  • How do you reverse the above? I need a full selector but only for external links. I somehow can't manage to do it. Can you help? – george Jan 28 '17 at 23:29
3

I don't know why you voted down my last answer but on reference url you will find exact condition

var a = new RegExp('/' + window.location.host + '/');
     if(!a.test(this.href)){
     //do stuff when it an external link
     }
    else{
    // do stuff when it's internal link
    }

Here is reference http://css-tricks.com/snippets/jquery/open-external-links-in-new-window/

Hitesh Chandwani
  • 159
  • 1
  • 1
  • 14
  • Your original answer was a link-only answer. It would have been fine if you included the important content from the link directly in your question (as you have now down, however you should still provide a reference link) – Kevin B Jun 06 '14 at 15:02
  • actually i am new in stackoverflow – Hitesh Chandwani Jun 06 '14 at 15:03
  • 2
    @TrueBlueAussie note that he is using the href property, not the href attribute. there IS a difference. That distinction is what makes this answer correct and the answer in the suspected duplicate incorrect. – Kevin B Jun 06 '14 at 15:16
  • it's just checking if the url is external link or link of same website so i guess it will work – Hitesh Chandwani Jun 06 '14 at 15:18
  • 1
    I've already confirmed in chrome, but i haven't cross-browser checked. wouldn't be surprised if there was some old version of IE that didn't work the same way http://jsfiddle.net/W5u8e/ – Kevin B Jun 06 '14 at 15:19
  • not necessarily, that's just two more easy checks. test the target property and hash property. – Kevin B Jun 06 '14 at 15:24
  • @Kevin B: And if he does that I will certainly up-vote it as *answering the question asked*. At the moment it only answers the other "duplicate" question :) – iCollect.it Ltd Jun 06 '14 at 15:26