2

I've got some jQuery code that does some specific stuff on certain webpages, and doesn't load on others. Here is my current method of running said code:

if ((window.location.href).indexOf('somewebsite.com') >= 0){
    chrome.extension.sendMessage({greeting: "loadscript"});
    var stuff = new Stuff();
    //run some code
    dothiseverytime(withSomeParams);
} else if ((window.location.href).indexOf('someotherwebsite.com') >= 0){
    chrome.extension.sendMessage({greeting: "loadscript"});
    var stuff = new Stuff();
    //run some code
    dothiseverytime(withDifferentParams);
} else if
// etc..

I'm wondering if I could do something along the lines of a switch case using indexOf and an array. Maybe something along the lines of this pseudocode?

someWebsites = ['somewebsite.com','someotherwebsite.com']
function checkTabURL {
    switch ((window.location.href).indexOf(someWebsites) >= 0) 
    case 0 // first site in our list - index 0
        var stuff = new Stuff();
        // do some stuff
    case 1 // second site on our list - index 1
        var stuff = new Stuff();
        // do some other stuff
    case -1 // site isn't on the list
        // don't do anything
} 

I'd like to minimize my code and I think using something along those lines would reduce the amount of code written as well.

Since people are confusing what I need and providing the opposite (searching the URL against an array instead of an array against the URL) - I'd like to clarify.

My array may contain things like 'somesite.com/subdir' so I cannot match the URL to the array - I need to match the array to the URL. I need to see if ANYTHING in the array is in the current URL (and then execute a case), not the other way around.

IE: Is 'somesite.com/subdir' contained in the current URL? Is 'someothersite.com' in the current URL? Execute case 0 for the former, case 1 for the latter. Case -1 if neither.

Thirk
  • 571
  • 1
  • 7
  • 24
  • What do you mean by 'have a real switch/case statement'? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch. Your second question: Based on one basic condition you'll have to run a method twice in case another condition is set, otherwise only once? – axel.michel Jan 04 '15 at 09:24
  • It's late, I guess I was mistaken. Yes, I'd like to run a method twice if z & y, or once if y. But in the real code I have more code after the z condition before the y. – Thirk Jan 04 '15 at 09:27
  • please read your own comments. One time you write: 'I ask for Z, then execute some code. Then I check for Y, but Y might not be there, even if Z is. In this case I don't want x() at all.' And here you say: 'I'd like to run a method twice if z & y, or once if y.' – axel.michel Jan 04 '15 at 09:56
  • I may just be going insane from being up late. You're right here. I believe your solution for my second code section is correct. – Thirk Jan 04 '15 at 09:59

2 Answers2

1

Based on the comments and discussion here is my modified answer. First, there are two indexOf methods in JavaScript. One is the String Method indexOf, it returns the position of the first occurrence of a specified value in a string. Second is the Array Method indexOf, which searches an array for the specified item, and returns its position.

The first answers offered you the Array method as a solution, but what you'll need is a extended version of the string method. Since you can't use an array natively as parameter for the String method, you'll need to create a custom method:

/**
 * Extend the Array object
 * @param needle The string to search for
 * @returns Returns the index of the first match or -1 if not found
 */
Array.prototype.searchFor = function(needle) {
    for (var i=0; i<this.length; i++)
        if (this[i].indexOf(needle) == 0)
            return i;
    return -1;
};

With this method (or a similar one) you are able to test if one string (your URL) is a partial or full match of an element of a given array.

var someWebsites = ['somewebsite.com/subdirectory','someotherwebsite.com'];

function checkTabURL(url) {
    switch (someWebsites.searchFor(url)) {
        case 0:
            console.log('case 0');
            break;
        case 1:
            console.log('case 1');
            break;
        // you can also combinate different cases:
        case 2:
        case 3:
             // do your stuff here
             break;
        default:
            console.log('default');
            break;
    }

} 

// for testing: logs 0 (case 0) 
// since somewebsite.com is indexOf somewebsite.com/subdirectory
checkTabURL('somewebsite.com'); 
//checkTabURL(window.location.href);

The new fiddle is here.

axel.michel
  • 5,764
  • 1
  • 15
  • 25
  • I'll check out your answer to my first one. But the second one won't work, because I don't want x(); to occur if ONLY z is satisfied. I also can't just do z & y conditionals because I have more code before the y conditional. – Thirk Jan 04 '15 at 09:39
  • @Thirk To your second - but this is what you currently do? You ask for Z, if so, you ask if Y exists, in that case you call X twice, otherwise once? – axel.michel Jan 04 '15 at 09:41
  • It seems the first bit is a no go either. I need to compare the current tab's URL to an array of sites, then do different responses depending on the url. Your bit shows me supplying a URL 'manually', which doesn't work if I'm only searching things like partial matches (indexOf 'google.com' vs 'http://google.com/q?=etc'). – Thirk Jan 04 '15 at 09:43
  • I ask for Z, then execute some code. Then I check for Y, but Y might not be there, even if Z is. In this case I don't want x() at all. – Thirk Jan 04 '15 at 09:45
  • Your answer to question one is the inverse of what I need. You provided code to check if the current URL is in the array - not if the array contains the current URL. I need the latter for things such as partial matches and site subdirectories. Simply changing the parameter for checkTabURL to window.location won't solve this. Thank you for the help though. – Thirk Jan 04 '15 at 09:51
  • I've updated my code ten minutes ago. I added '// some code here' after the z conditional. – Thirk Jan 04 '15 at 09:52
  • @Thirk I have updated my answer one more time, trying to fulfill your requirements you describe in your comments, still not sure, what exactly you are looking for. It might be better to split an url to it's fragments before testing it against an array, anyway. – axel.michel Jan 04 '15 at 10:39
0

It sounds like what you want to do is execute some code depending on whether a substring (some domain) matches the URL string.

A bunch of if/else blocks work. If you have a lot of strings, it might be a bit more neat to organize it into a mapping of substrings to functions. Something like...

siteToFunction = {
  'example.com': function() {
    console.log('foo');
    console.log('bar');
  },
  'example2.com': function() {
    console.log('foo');
    console.log('bar');
  }
}

Then, we can iterate through each key in the object / map, check to see if it matches the current url, and then take the value, which is a function, and call it.

var url = window.location.href;

Object.keys(siteToFunction).forEach(function(site) {
  // if the current site matches the current url, run its associated function
  if (url.indexOf(site) > -1) { 
    siteToFunction[site](); 
  }
})

This might not be the most optimal way in terms of performance, since we're not escaping the forEach loop when we encounter a match (though we could).

Community
  • 1
  • 1
Gordon Zheng
  • 499
  • 3
  • 10