Check if url hash exists - javascript

I want to check if there is a hash in the url :
This should return true:
domain.com/balbla#hash
This should return false:
domain.com/balbla
So I use URI.js to grab the hash
var uriFragment = new URI(window.location.href).fragment();
if (uriFragment.length) {
console.log('yep')
} else {
console.log('nope')
}
But that never returns nope even if there is no hash in the url.

Why not using directly location.hash
if(location.hash.length > 0) {
console.log('yep')
}else {
console.log('nop')
}

Below code will give the list of hash tags in array format.
var hash = window.location.hash;
return result = hash.split('#').reduce(function (result, item) {
var parts = item.split('=');
result[parts[0]] = parts[1];
return result;
}, {});

Related

To get a specific value at a specific location using Url indexOf

Url
/product/product/4415/category/44/display/1/
var url = location.href;
var getAr0 = url.indexOf("44");
if(getAr0 != -1) {
$("#asideNav-top").addClass("open");
}
Try to execute the if statement only when /category/44/.
The problem is when the URL is
Url
/product/product/4415/category/71/display/1/
//Even if the above statement is executed.
if(getAr0 != -1) {
$("#asideNav-top").addClass("open");
}
What I want is to run the if statement only when /category/44/.
You need to find /category/44/ but not just 44 like below;
var url = location.href;
var getAr0 = url.indexOf('/category/44/');
if(getAr0 != -1) {
$("#asideNav-top").addClass("open");
}

chrome.webRequest.onBeforeRequest.addListener not blocking an array of urls

I am trying to block an array of urls based on user input. I have the url array in JSON format, but the sites are not actually being blocked when I navigate to them. If I use only one site, instead of an array, it does get blocked successfully. Here is the function.
function addListener(){
chrome.webRequest.onBeforeRequest.addListener(
function(){ return {cancel: true}; },
{
urls: blockedUrls()
},
["blocking"]
);
}
And here is my function blockedUrls.
var blockedUrls = function () {
chrome.storage.sync.get(['block'], function(result) {
if (typeof result.block === 'undefined') {
//blocks is not yet set
var jobj = ["*://www.whatever.com/*"];
return [jobj[0]];
console.log("not set");
}
else{
var xt = JSON.parse(result.block);
console.log(JSON.stringify(xt.urls));
return JSON.stringify(xt.urls);
}
});
return ["*://www.whatever.com/*"];
}
The console.log does print out what I want, which is this (some were just used for testing obviously)
["doesntexist.com","*://www.yahoo.com/*","*://www.xbox.com/*","*://www.hello.com/*","*://www.es/*"]
And, if it helps, here is where the sites get initially set into chrome storage, from the variable request.newSites.
var jsonStr = '{"urls":["doesntexist.com"]}';
var obj = JSON.parse(jsonStr);
//add url matching patterns to the urls from user input
for (var i = 0; i < request.newSite.length; i++){
obj['urls'].push( '*://www.' + request.newSite[i] + '/*');
}
jsonStr = JSON.stringify(obj);
chrome.storage.sync.set({'block': jsonStr}, function(){
addListener();
});
Thanks in advance.
There are a couple of problems with your code:
1) chrome.storage.sync.get's callback function is asynchronous. Therefore, in your function blockedUrls the return value will always be ["*://www.whatever.com/*"], because the line return ["*://www.whatever.com/*"]; will run before chrome.storage.sync.get's callback function.
2) The second argument of chrome.webRequest.onBeforeRequest listener should be an object in the following form:
{urls: theUrls} where theUrls is an Array of strings, not a string.
Apart from that, you can take advantage of the fact that chrome.storage can store objects and arrays directly, so there is no need to stringify them.
Try with:
var obj = {urls: ['*://doesntexist.com/*']};
for (var i = 0, j = request.newSite.length; i < j; i++){
obj.urls.push( '*://www.' + request.newSite[i] + '/*');
}
chrome.storage.sync.set({block: obj}, function(){
addListener();
});
function addListener() {
chrome.storage.sync.get('block', function (result) {
var myUrls = result.block || ["*://www.whatever.com/*"];
chrome.webRequest.onBeforeRequest.addListener(function(){
return {cancel: true}
},
{urls: myUrls},
["blocking"] );
});
}
chrome.storage.sync.get is an asyncronous function. Therefor it will not return your url list.
What you probably meant to do was the following:
function addListener(){
chrome.storage.sync.get(['block'], function(result) {
let urls;
if (typeof result.block === 'undefined') {
//blocks is not yet set
var jobj = ["*://www.whatever.com/*"];
urls = [jobj[0]];
console.log("not set");
}
else{
var xt = JSON.parse(result.block);
console.log(JSON.stringify(xt.urls));
urls = JSON.stringify(xt.urls);
}
chrome.webRequest.onBeforeRequest.addListener(
function(){ return {cancel: true}; },
{
urls: urls
},
["blocking"]
);
});
}

Change string on each loop iteration

I have the following problem:
I have a string and I need to replace for different regex parts.
therefore I want to loop over it:
In my case its a URL and I want to empty for specific parameters:
cleanURL(url, params) {
params.forEach((param) => {
url = this.updateUrlParameter(url, param, '');
});
Whereas I have:
updateUrlParameter(url, param, value) {
const regex = new RegExp(`(${param}=)[^&]+`);
const newURL = url.replace(regex, `$1${value}`);
return newURL;
}
This is the only way I got it to work, but now I am reassigning a function parameter.
this is not what I want.
My problem is, that
cleanURL(url, params) {
params.forEach((param) => {
this.updateUrlParameter(url, param, '');
});
}
Would always for each iteration pass the SAME url into the loop. And I end up with just the last replacement.
I somehow would have to pass a changed string into the next loop iteration.
How could I achieve this?
Maybe into this direction?
With somehow nesting and calling the function again?
while(outerI--){
(function(i){
i+=1;//doesn't affect outerI and you wanted 1-length so we add one.
//crap inside your forEach loop but without the i++
})(outerI)
}
which I found here:
.forEach loop: use variable
Woudl be very glad for a hint here.
thank you
Cheers
Reassigning the function parameter would be perfectly fine in this use-case.
If you really don't want to reassign a function parameter for whatever reason, you can introduce a new variable to store the updated URL for you.
cleanURL(url, params) {
let newUrl = url;
params.forEach((param) => {
newUrl = this.updateUrlParameter(newUrl, param, '');
});
return newUrl;
}
If you don't want to mutate parameter, use a temporary variable to hold the result.
function updateUrlParameter(url, param, value) {
const newURL = url + param;
return newURL;
}
function cleanURL(url, params) {
let temp = url;
params.forEach((param) => {
temp = updateUrlParameter(temp, param, '');
});
return temp;
}
const params = [1, 2, 3, 4, 5];
const url = 'string';
console.log(cleanURL(url, params));
The String.prototype.replace does not modify the original string, rather it creates a new string.
If you update your clearUrl method to reassign url in each iteration you should get replacements for all the parameters
cleanURL(url, params) {
params.forEach((param) => {
url = this.updateUrlParameter(url, param, '');
});
}
I also found a way in the meantime:
cleanURL(url, params) {
const paramsLength = params.length;
const cleanURL = url;
const recursive = (i, originalURL) => {
this.log('i: ', i);
this.log('originalURL: ', originalURL);
if (i > 0) {
const changedURL = this.updateUrlParameter(originalURL, params[i - 1], '');
return recursive(i - 1, changedURL);
}
return originalURL;
};
// this.log('url: ', url);
return recursive(paramsLength, cleanURL);
}
updateUrlParameter(url, param, value) {
const regex = new RegExp(`(${param}=)[^&]+`);
// this.log('regex: ', regex);
const newURL = url.replace(regex, `$1${value}`);
// this.log('newURL: ', newURL);
return newURL;
}
Thoughts on that?

How to search in array

I have JavaScript array contains links something like this:
var urls = ['url1','url2','url3'];
if (urls.indexOf(window.location.hostname) > -1)
{
// do something ...
}
else {
window.location.href = 'redirect url';
}
this code work well, but I tried to convert it to an array of objects like this:
var urls = [
{
'url':'url1'
},
{
'url':'url2'
},
{
'url':'url3'
},
];
if (urls.url.indexOf(window.location.hostname) > -1)
{
// do something ...
}
else {
window.location.href = 'redirect url';
}
But this code is not working!!
How I can convert the first code into array of objects, or how I can search in array?
Easiest solution is to use array.some
if(urls.some(function(item) { return item.url == window.location.hostname;})) {
// do something ...
} else {
window.location.href = 'redirect url';
}
more readably
var found = urls.some(function(item) {
return item.url == window.location.hostname;
});
if(found) {
// do something ...
} else {
window.location.href = 'redirect url';
}
First of all: Both definitions of your urls variable are JSON:
first definition is an array of Strings in JSON notation
second definition is an array of objects, each consisting of one property url as a string.
In order to search through the second one, you need to iterate over the objects array explicitly and compare the property explicitly (as one approach):
var found = false;
for ( var n = 0; n < urls.length; n++ )
{
if ( urls[n].url == window.location.hostname )
{
/// do something
found = true;
break;
}
}
if ( !found )
{
// do something other
}
Or may be
if(urls.map(function(obj){ return obj.url}).indexOf(window.location.hostname)>0){
// do something ...
}
else {
window.location.href = 'redirect url';
}
Using lodash version 4 or later, you could do this:
if (_(urls).map('url').includes(window.location.hostname)) {
// do something...
} else {
window.location.href = 'redirect url';
}
When it comes to arrays of objects you cannot access elements like what you have done in your code. You have to use a loop to travers through the elements or an inbuilt functions like filter,map.Without using inbuilt functions you can do something like this to get your work done.
function to search for a particular url in the array
function findURL(array,url) {
for (var i = 0; i < array.length; i++) {
if (array[i].url == url) {
return i;
}
}
return -1;
}
Put below piece of code where you want to check the condition
var urls = [
{
'url':'url1'
},
{
'url':'url2'
},
];
if(findURL(urls,window.location.hostname) > -1){
//do something ..
}else{
window.location.href = 'redirect url';
}
There are some answers which describe how to apply filter and map methods in your scenario.Therefore I thing i don't want to put those in my answer.
If you use jquery there is a function called grep which returns an array of items found.
var urls = [
{
'url':'url1'
},
{
'url':'url2'
},
];
var result = $.grep(urls, function(e){ return e.url == window.location.hostname; });
if (result.length == 0) { // nothing found
window.location.href = 'redirect url';
} else if (result.length == 1) { // one item found
//do something ..
// you can access the found item by result[0].foo if you want
} else { // multiple items found
}

Check if value is in array always returning true

i'm checking to see if pages are in array currently when clicking on hsc.html and index.html i'm still seeing the alert("debug") which is == to requested page not !=
experimentPages = new Array();
experimentPages[1] = "index.html"
experimentPages[2] = "hsc.html"
$('a').click(function () {
var reqestedPage = $(this).attr("href");
if ($.inArray(experimentPages) != reqestedPage) {
alert("debug")
}
The method works as follows
$.inArray( value, array_to_check )
and returns -1 if not found, otherwise it returns the position of the value in the array.
var experimentPages = [
"index.html",
"hsc.html"
];
$('a').click(function () {
var reqestedPage = $(this).attr("href");
if ($.inArray(reqestedPage, experimentPages) != -1) {
alert("it exists");
}else{
alert("no luck");
}
});
note that the href has to match exactly the values in the array

Categories