function to define current class in js - javascript

What I want to do is to have a function that executes to define a "current" class to an <li> tag, depending on the page name. For example, if the page is named index.php, I want the function to determine if the link within the <li> tag is the same name as the page (index.php). I'm sorry I'm not the best at explaining this. Here's an example code.
<ul id="navigation"><li><a href="index.php"></li></ul>.
I want the class "current" defined into the <li> tag if the link is the same as the page name. Is there any way to do this? Or am I on a futile mission?

I think what you are asking is you want to change the look of links that are pointing to the present page. Here is what the code would look like.
var list=document.getElementsByTagName('a');
var page=window.location.pathname;
var i=list.length;
while(i--){
if(list[i].src.indexOf(page)>0){
list[i].className='current';
}
}
Note this is not a very accurate method. The basic structure is correct, but for example a link somewebsite.com is actually pointing to somewebsite.com/index.php. So depending on the link this could cause a problem on the home page. Also, depending on how your links are setup you are probably going to have to the parse the page variable. It will return something like. /help/faq/foo.php while the page may only have a link to faq/foo.php. This all depends a lot on the setup of your site so I will leave it for you to tweak.
You added more details since I posted so I thought I would note that you would only need to make a list of the links in the <li> tags not all the <a> tags in the page.

Well...okay...
function liClass(context) {
//Choose your parent node
context = context || document;
var pathparts = window.location.pathname.split('/'); //split on path
var curfile = pathparts[pathparts.length-1]; //last item is the filename right?
var lis = context.getElementsByTagName('li');
for (var i=0, l=lis.length; i<l; i++) {
var a = lis[i].getElementsByTagName('a');
if (!a.length) continue; //li has no a, moving on...
//Okay, this match might need some work, tried
//to make it fairly forgiving, tweak for your needs
if (a[0].href.indexOf(curfile) != -1) lis[i].className = 'current';
}
}
Feel free to try it out, let me know if it works or not, cause I did not test it...

Compare the href's of the location object, and the anchor DOM element. If they match, then that is the current class.
If the current page is http://www.example.com/home which contains a relative link,
Questions
Then the href property of the DOM object will contain the absolute path, and not just the relative part.
link.href = "http://www.example.com/questions"
A function that loops through each link could then be written as,
function markCurrent(list) {
var listItems = list.getElementsByTagName("li");
for(var i = 0; i < items.length; i++) {
var link = listItems[i].getElementsByTagName("a")[0];
if(link && (link.href == location.href)) {
listItems[i].className += ' current';
}
}
}
Pass the root <ul> node to the function.
markCurrent(document.getElementById("navigation"));

Related

Built relative URL in pages that are missing trailing slash /

We desperately need help with writing a small code that allows you to take the current page URL and the parameter in the href="parm" and create the link by joining the two with a slash.
The reason we need to do this is because we need relative links to the current page. The CMS system that we are working removes trailing slash from the end of URL.
Which is a problem because if you are at a page
domain.com/fruit/apple
and create a link such as href="calories" or href="./calories"
it will point to domain.com/fruit/calories
Instead, we want it to point to
domain.com/fruit/apple/calories
Which is relative to the current page.
We don't want to change the way that our CMS works, therefore, the need JS solution.
Below you can see one example of what we are trying to accomplish but this only works on one link.
link
Start JS
var x = window.location.href; // Current page URL
var link = document.getElementById("relurl"); // store the element
var curHref = link.getAttribute('href'); // Get HREF paramter
link.setAttribute('href', x + "/"+ curHref);
End JS
The idea is to build relative links every time links with id="relurl" is used.
As per previous example this link: a href="home" id="relurl" target="_blank" title="This is a relative link!">link
at this page: domain.com/fruit/apple
it should point to domain.com/fruit/apple/home
Meaning the link structure is the currentpageURL + / + href
One page may have multiple relative links.
Thanks for any help.
While you could just use relative URLs in your links (with href="./page"), it sounds like the problem is that you are using duplicate IDs (which results in invalid markup). You can test that you have valid markup with the W3C Markup Validation Service.
When you have duplicate IDs, JavaScript only applies to the first element. This can be seen in the following:
var x = window.location.href; // Current page URL
var link = document.getElementById("relurl"); // store the element
var curHref = link.getAttribute('href'); // Get HREF paramter
link.setAttribute('href', x + "/" + curHref);
Working Link
<br />
NOT Working
To resolve this, you should use classes instead of IDs for your links. You can then use document.getElementsByClassName to select the elements. Remember that this returns a NodeList collection of elements, so you'll need to set the new URLs inside of a loop, as can be seen in the following:
var x = window.location.href; // Current page URL
var links = document.getElementsByClassName("relurl"); // store the elements
for (var i = 0; i < links.length; i++) {
var curHref = links[i].getAttribute('href'); // Get HREF paramter
links[i].setAttribute('href', x + "/" + curHref);
}
Working Link
<br />
Another Working Link
Hope this helps! :)
This will update all links in the current page:
const updateNode = node =>
node.href = `${window.location}/${node.href}`
document.querySelectorAll('a').forEach(updateNode)

Passing URL Parameters in href Link

I’m a bit new to this JS stuff and have been surfing and surfing and reading up as much as I can, but I got stumped on this one issue.
I have a website that may contain parameters in the URL. A parameter named “who” to be exact.
If a user comes to the site and their url is http://example.com/?who=123, I want them to be able to click a href link and their parameter get carried on. So if the link goes to http://anotherexample.com, I’d want the link to contain the user’s parameter as well. http://anotherexample.com/?who=123.
What’s the best way to accomplish this? It only needs to be on one of the links, so no concerns about getting the whole site to pass on the parameter.
Thanks!
Would this suffice for you?
Source: https://css-tricks.com/snippets/javascript/get-url-variables/
var svalue=location.search.match(new RegExp("[\?\&]" + "who" + "=([^\&]*)(\&?)","i"));
yourelement.href=yourelement.href+(svalue?svalue[0]:"");
Here is one way you can do it in javascript
first when the document loads write a function in your js to get the parameters from the url
function getparms(variable)
{
let item = window.location.search.substring(1);
let vars = item.split("&");
for (let i=0;i< vars.length;i++) {
let pair = vars[i].split("=");
if(pair[0] == variable){return pair[1];}
}
return(false);
}
This function would return the following from a url
http://www.somesite.com/index.html?who=100&location=2
Calling getparams('who') would return "100"
So you would call it as:
let myParam = getparams('id');
You can build the url in a new function and navigate to it as:
function goToUrl(urlParam){
let hostAddress= 'yourwebsiteaddress';
let url = "http://" + hostAddress "/?=who" + urlParam;
//go to address
window.location.href = url;
}
which would be called as goToUrl(myParam);
*Disclaimer: I wrote this on the fly so it may not be 100% syntactically correct but it should be accurate enough as pseudo code to help you accomplish what you want.
You talked about href, so I assume all links are set with <a> tag.
There are many options to do that, I'll show you the easiest and cleanest one.
So, assuming the current URL is http://www.example.com/?who=123.
var who = window.location.href.split('?')[1]; // Get `?who=123` from current url
var a = document.getElementsByTagName('a'); // Get all `<a>`
var href;
// Loop through all `<a>`
for (var i = 0; i < a.length; i++){
// Add `?who=123` to all hrefs found.
a[i].href += who;
}
You can freely change document.getElementsByTagName('a') to document.getElementById() to suit your needs.

How to get multiple headers/footers in a document with Google Apps Script

Im trying to replace a text in a Google Document header which has "Different first page Header/Footer" active. I succesfully replace text in any other page header except on first page.
...
var something = "Some string.";
var copyId = DriveApp.getFileById(docTemplate).makeCopy(name).getId();
var copyDoc = DocumentApp.openById(copyId);
var copyHeader = copyDoc.getHeader();
copyHeader.replaceText('keySomething', something);
...
I looked at the documentation but didn't see how to do it. I even tried with "getHeaders()" (in plural) but that class doesn't exist.
How I can replace the text in the first page header/footer?
Thanks,
Iván
copyHeader.getParent().getChild(2); //I'm using your variable
This will point to the header on the first page. The "2" in getChild(2) may or may not vary but I have added a function, seeChildren(), on the third block of code in this answer.
If you are trying to replace all instances of a string in the document, use this with replaceText()
copyHeader.getParent(); /*this points to the whole document (unless the
header's parents is not the whole)*/
//getbody(), getfooter(), etc (i.e. siblings of header) should work
If you want to know the x of getChild(x) for the footer,
function seeChildren(){
var doc = DocumentApp.getActiveDocument();
var bod = doc.getBody();
var fol = bod.getParent();
for (i = 0; i<fol.getNumChildren(); i++){
var child = fol.getChild(i);
bod.appendParagraph(child + ": Index " + fol.getChildIndex(child));
}
}
This will append the names of the document's children (DocumentBodySection, HeaderSection, HeaderSection, FooterSection, FooterSection, etc) and their respective indices on the body section (0,1,2,...,number of children minus 1). Also, note that this uses getActiveDocument(), the file must be open for the function to work.
copyHeader.getParent().getChild(3).replaceText('current text','new text');
This will point to the header on the first different page.

Count all <a> on html page

I want to get all the <a> tags from an Html page with this JavaScript method:
function() {
var links = document.getElementsByTagName('a');
var i=0;
for (var link in links){i++;}
return i;
}
And i noticed it's won't return the correct number of a tags.
Any idea what can by the problem?
Any idea if there is any other way to get all the href in an Html ?
Edit
I tried this method on this html : http://mp3skull.com/mp3/nirvana.html .
And i get this result:"1". but there are more results in the page.
You don't need a loop here. You can read length property.
function getACount() {
return document.getElementsByTagName('a').length;
}
You don't have to loop over all of them just to count them. HTMLCollections (the type of Object that is returned by getElementsByTagName has a .length property:
$countAnchors = function () {
return document.getElementsByTagName('a').length;
}
Using getElementsByTagName("a") will return all anchor tags, not only the anchor tags that are links. An anchor tags needs a value for the href property to be a link.
You might be better off with the links property, that returns the links in the page:
var linkCount = document.links.length;
Note that this also includes area tags that has a href attribute, but I assume that you don't have any of those.
UPDATE Also gets href
You could do this
var linkCount = document.body.querySelectorAll('a').length,
hrefs= document.body.querySelectorAll('a[href]');
EDIT See the comment below, thanks to ttepasse
I would cast them to an array which you then slice up, etc.
var array = [];
var links = document.getElementsByTagName("a");
for(var i=0; i<links.length; i++) {
array.push(links[i].href);
}
var hrefs = array.length;
The JavaScript code in the question works as such or, rather, could be used to create a working solution (it’s now just an anonymous function declaration). It could be replaced by simpler code that just uses document.getElementsByTagName('a').length as others have remarked.
The problem however is how you use it: where it is placed, and when it is executed. If you run the code at a point where only one a element has been parsed, the result is 1. It needs to be executed when all a elements have been parsed. A simple way to ensure this is to put the code at the end of the document body. I tested by taking a local copy of the page mentioned and added the following right before the other script elements at the end of document body:
<script>
var f = function() {
var links = document.getElementsByTagName('a');
var i=0;
for (var link in links){i++;}
return i;
};
alert('a elements: ' + f());
</script>
The results are not consistent, even on repeated load of the page on the same browser, but this is probably caused by some dynamics on the page, making the number of a elements actually vary.
What you forget here was the length property. I think that code would be:
var count = 0;
for (var i = 0; i < links.length; i++) {
count++;
}
return count;
Or it would be:
for each (var link in links) {
i++;
}
length is used to determine or count the total number of the element which are the result.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for (For Loop)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for_each...in (Foreach Loop)

Rewrite links from an array

I have 2 index pages with approx. 150 links on each. I would rather maintain 1 page and just generate the links dynamically based on a variable value. For example create a list of links. link1, link2, link3... and based on a variable value being 'true' replace those links with list of alternate links i.e. altlink1, altlink2, altlink3...
I have figured out how to do this once but rather than writing the same code over and over for each link I was wondering if there was a faster way. Like creating a list "a" and corresponding list "b" or something like that. I have included my current code below and I look forward to your advice.
<script type="text/javascript">
// link rewriter
var hostadd = location.host;
var vendor = '999.99.999.99';
var localaccess = 'somesite.com';
$(document).ready (
function link_switcher(){
//if not a vendor route to alternate website
if (hostadd != vendor) { $("a[href= 'https://www.somelink1.com']").attr ('href', 'https://www.alternatelink1.com') }
});
</script>
is it possible to create an array and then javascript that would say replace link1 in array a with alternatelink1 in array b?
It's still not entirely clear what you're trying to do, but if you want to rewrite all links based on a lookup table that tells you what link to convert to what, here's how you could do that:
// Table of links.
// Key is original page source URL
// Data is link to change it to
var linkData = {
"http://www.google.com": "http://www.bing.com/",
"http://mail.google.com/mail/?shva=1#inbox": "http://www.hotmail.com"
};
// find every link in the page and change it if it's value is found in the linkData table
$("a").each(function() {
var link = this.getAttribute("href"); // use getAttribute to get what was actually in the page, perhaps not fully qualified
if (linkData[link]) {
this.href = linkData[link];
}
});
If the link is not found in the table, it will not be modified. If there was some pattern to the modification, it might be possible to code that pattern and not have to list every link in the table, but you haven't shared any info about a pattern.
And, a working jsFiddle example: http://jsfiddle.net/jfriend00/Cvj8C/.

Categories