JavaScript Make Tabs - javascript

So, I am trying to make a "tabs menu", like this: http://flowplayer.org/tools/tabs/index.html
(but i dont want to use this.)
So, I tried to use url variables to set the active menu item.
Code:
onload=function(){
//Check if editPage is set
if (gup("editPage")) {
gupname = gup("editPage");
var x = "contentEditListItem"+gupname;
var y = document.getElementsByClassName(x);
y.className = "contentEditListItemActive";
}
}
function gup( name )
{
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( window.location.href );
if( results == null )
return "";
else
return results[1];
}
The gup function works well, I get the wanted classname ("contentEditListItem"+gupname).
Why it is staying unchanged?

getElementsByClassName returns a NodeList (kind of Array), so setting a property on that is not affecting the elements that it contains, but only the NodeList itself, which has no effect.
You could set the class name of the first element, for example, like this:
y[0].className = "contentEditListItemActive";
Or, if you want all elements have their class name changed, you could iterate over the NodeList:
for(var i = 0; i < y.length; i++) {
y[i].className = "contentEditListItemActive";
}

Related

How to find class by property

I'm doing some manipulations at the 'video' class at youtube, like change the currentTime property and read duration property of that class and I had success doing it. But when I go to other sites, sometimes they change the name of 'video' to 'video2' for example, and my code doesn't work in that site. I want to know if there is a easy way to make my code look for classes that have the currentTime property, and than set this as my variable, for example.
what I can do:
var videoClass = document.getElementsByTagName('video');
what I want to do:
var videoClass = document.getClassesByProperty('currentTime');
I'm guessing you mean attribute, not property, e.g. something like <video2 currentTime="xxx">. If so, you can use a query selector to match the attribute.
var videoClass = document.querySelectorAll('[currentTime]');
My temporary and probably permanent solution:
try{
var videoClass = document.querySelectorAll('[class^=video-stream');
}catch{}
function setVideoClass(){
try{
var videoList = document.querySelectorAll('*');
for (var i = 0; i < videoList.length; i++){
try{
var videoClassLocal = videoList[i].currentTime;
if ((videoClassLocal != undefined ) & (videoClassLocal != 0) ){
videoClass = videoList[i];
}
}catch{}
}
}catch{}
}
setInterval(setVideoClass,1000);

Error while selecting allElementsByID and adding a class to them

Hello I'm trying to add a class to all of my elements on a webpage. The overall goal is to grab all the elements on a webpage and add in a class. The class containing a font size will be changed to hide a message.
I'm getting this error
Uncaught TypeError: Cannot set property 'innerHTML' of null
I've tried moving my script outside the body tag of my index.html but its still not working.
Another problem is I can't add a class to all of the IDs I'm selecting. I can add classes manually like
$("#iconLog").addClass("style"); //this works
but when I try to add a class like this
empTwo = "#" + temp; //where empTwo is a string that equals "#iconLog"
$("empTwo").addClass("style") //this does not work
I'll post my entire script below for reference
$(function() {
var hideMsg = "f";
var n = hideMsg.length;
var i;
var j;
var holder;
var hideHolder;
// on button click - hide msg
$('#btnHide').on('click', function() {
//grab all IDS ON WEBPAGE
var allElements = document.getElementsByTagName("*");
var allIds = [];
for (var i = 0, n = allElements.length; i < n; ++i) {
var el = allElements[i];
if (el.id) {
allIds.push(el.id);
}
}
//ERRORS HAPPENING IN THIS LOOP
for(var i = 0; i < allElements.length; ++i)
{
console.log(allIds[i]);
try{
var temp = document.getElementById(allIds[i]).id;
}
catch(err){
document.getElementById("*").innerHTML = err.message;
}
tempTwo = "#" + temp;
console.log(tempTwo);
//$("#iconLog").addClass("style") //this works
$("tempTwo").addClass("style"); //this does not work
}
for(i = 0; i < n; i++) {
//set var holder to first value of the message to hide
holder = hideMsg.charCodeAt(i);
for(j = 7; -1 < j; j--) {
//set hideHolder to holders value
hideHolder = holder;
//mask hideHolder to grab the first bit to hide
hideHolder = hideHolder & (1<<j);
//grab the first element ID
if(hideHolder === 0) {
// embed the bit
// bitwise &=
} else {
//embed the bit
// bitwise ^=
}
}
}
});
});
To add a class to all elements you don't need a for loop. Try this:
$("*").addClass("style");
Same for setting the inner html of all elements. Try this:
$("*").html("Html here");
Remove the double quotes from empTwo .You don't need quotes when you are passing a varible as a selector. The variable itself contains a string so you don't need the quotes.
empTwo = "#" + temp;
$(empTwo).addClass("style") //this will work
Try this:
$(empTwo).addClass("style")
Note: You used string instead of variable:
well,
try this...
You were passing the varibale in the quotos because of that instead of getting value to empTwo it was searching directly for "empTwo".
$(empTwo).addClass("style");
to get all element try this-
var allElements = = document.body.getElementsByTagName("*");
Hoping this will help you :)
empTwo = "#" + temp; //where empTwo is a string that equals "#iconLog"
$("empTwo").addClass("style") //this does not work
You made mistake in the second Line.
The variable empTwo already is in string format.
So all you need to do is
$(empTwo).addClass("style") //this works because empTwo returns "#iconLog"

getElementsByName: control by last partial name

I can get div elements by id and using only partial name "first"
html
<div id="first.1.end">first.1.end</div>
<div id="first.2.end">first.2.end</div>
<div id="two.3.end">two.3.end</div>
<div id="first.4.end">first.4.end</div>
js
function getElementsByIdStartsWith(selectorTag, prefix) {
var items = [];
var myPosts = document.getElementsByTagName(selectorTag);
for (var i = 0; i < myPosts.length; i++) {
if (myPosts[i].id.lastIndexOf(prefix, 0) === 0) {
items.push(myPosts[i]);
}
}
return items;
}
var postedOnes = getElementsByIdStartsWith("div", "first");
alert(postedOnes.length);
It counts 3 div elements (alert).
But how can I use end-partial name for search? For example using "end"?
From MDN Attribute selectors:
[attr^=value] Represents an element with an attribute name of attr and
whose value is prefixed by "value".
[attr$=value] Represents an element with an attribute name of attr and
whose value is suffixed by "value".
So you can use [id^="first"] to find elements with id start with "first". and use [id$="end"] to find elements end with "end".
Like
// This find all div which id ends with "end".
var divs = document.querySelectorAll('div[id$="end"]');
or use jQuery:
$('div[id$="end"]');
Also, you can combine multiple attribute selectors altogether to find a more specific element:
// As we only use querySelector, it find the first div with id starts with "two" and ends with "end".
var divStartAndEnd = document.querySelector('div[id^="two"][id$="end"]');
See demo on jsfiddle
Here I am allowing user to pass all three parameters.
suppose user doesn't pass midmatch so it will return only match of first and last.
Below is the working code:
It will return 1 count:
function getElementsByIdStartsWith(selectorTag, firstmatch, midmatch, lastmatch) {
var items = [];
var myPosts = document.getElementsByTagName(selectorTag);
for (var i = 0; i < myPosts.length; i++) {
var firstmatchIndex = firstmatch?myPosts[i].id.indexOf(firstmatch)>-1?true : false : true;
var midmatchIndex = midmatch?myPosts[i].id.indexOf(midmatch)>-1?true : false : true;
var lastmatchIndex = lastmatch?myPosts[i].id.indexOf(lastmatch)>-1?true : false : true;
if (firstmatchIndex && midmatchIndex && lastmatchIndex ) {
items.push(myPosts[i]);
}
}
return items;
}
var postedOnes = getElementsByIdStartsWith("div", "first", "2", "end");
alert(postedOnes.length); // now it will show only one in alert.
It will return 3 count:
function getElementsByIdStartsWith(selectorTag, firstmatch, midmatch, lastmatch) {
var items = [];
var myPosts = document.getElementsByTagName(selectorTag);
for (var i = 0; i < myPosts.length; i++) {
var firstmatchIndex = firstmatch?myPosts[i].id.indexOf(firstmatch)>-1?true : false : true;
var midmatchIndex = midmatch?myPosts[i].id.indexOf(midmatch)>-1?true : false : true;
var lastmatchIndex = lastmatch?myPosts[i].id.indexOf(lastmatch)>-1?true : false : true;
if (firstmatchIndex && midmatchIndex && lastmatchIndex ) {
items.push(myPosts[i]);
}
}
return items;
}
var postedOnes = getElementsByIdStartsWith("div", "first", "", "end");
alert(postedOnes.length); // now it will show only three in alert.
if you don't want to consider any parameter just pass empty string( "" ) while calling the function.
Hope this will help you :)
I guess this kind of selection can be possible by using jQuery + regex. Have a look to this
How can I select an element by ID with jQuery using regex?
Might be some what on the line that you want.

Javascript : Select Element in URL with multiple instance of the same element

i need to retrieve a value from an URL in JS, my problem is in this url, the element is repeated at least twice with different value. What i need is the last one.
Example :
http://randomsite.com/index.php?element1=random1&element2=random2&element1=random3
and what i want is "random3" and NOT "random1"
I've tried url.match(/.(\&|\?)element1=(.?)\&/)[2];
But it always gives me the first one :(
I don't have the possibility to change how the url is written as this is for a browser extension.
var ws = "http://randomsite.com/index.php?element1=random1&element2=random2&element1=random3",
input = ws.split("?")[1].split("&"),
dataset = {},
val_to_find = "element1";
for ( var item in input){
var d = input[item].split("=");
if (!dataset[d[0]]){ dataset[d[0]] = new Array(); dataset[d[0]].push(d[1]); }
else{
dataset[d[0]].push(d[1]);
}
}
console.log("item: ", dataset[val_to_find][dataset[val_to_find].length -1]);
return dataset[val_to_find][dataset[val_to_find].length -1];
http://jsfiddle.net/wMuHW/
Take the minimum value (other than -1) from urlString.lastIndexOf("&element1=") and urlString.lastIndexOf("?element1="), then use urlString.substring.
Or alternately, split the string up:
var parts = urlString.split(/[?&]/);
...which will give you:
[
"http://randomsite.com/index.php",
"element1=random1",
"element2=random2",
"element1=random3"
]
...then start looping from the end of the array finding the first entry that starts with element= and grabbing the bit after the = (again with substring).
You could;
for (var result, match, re = /[&?]element1=(.+?)(\&|$)/g; match = re.exec(url);) {
result = match[1];
}
alert(result);
Id try keeping a nested array of duplicate elements
function parseQueryString() {
var elements = {},
query = window.location.search.substring(1),
vars = query.split('&');
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split('='),
key = decodeURIComponent(pair[0]),
value = decodeURIComponent(pair[1]);
if (elements.hasOwnProperty(key)) {
elements[key].push(value);
}
else {
elements[key] = [value];
}
}
}
Used on: www.example.com?element1=hello&element2=test&element1=more
Would give you the object:
{
element1: [
"hello",
"more"
],
element2:[
"test"
]
}

How can I refine this Javascript code to refine it so it only work on links from images (and NOT links from text)

I want to make some refinement to some code from a previous question:
// the new base url
var base = ' https://www.example.co.uk/gp/wine/order?ie=UTF8&asin=';
var links = document.getElementsByTagName('a');
for(var i = 0;i < links.length;i++){
// check each link for the 'asin' value
var result = /asin=([\d\w]+)/.exec(links[i].getAttribute('href'));
if(result){
// make a new url using the 'base' and the 'asin' value
links[i].setAttribute('href', base+result[1]);
}
}
Now, instead of it acting on all links, can I get it to only look at links that are from images?
Here is an HTML snippet to show what I mean:
<img width="125" height="125" border="0" src="http://ecx.images-amazon.com/images/I/01W9a7gwosL.jpg" alt="43453">
That's an image link - I do want it to act on that.
Impossible?
My gut instinct is that this isn't actually possible in code - because document.getElementsByTagName('a') can't see the difference between a text link and an image link.
Use querySelectorAll to pre-select only the right kinds of nodes. EG:
// the new base url
var base = 'https://www.example.co.uk/gp/wine/order?ie=UTF8&asin=';
var linkImgs = document.querySelectorAll ("a > img");
for (var J = linkImgs.length - 1; J >= 0; --J) {
var imgLink = linkImgs[J].parentNode;
//--- Check each link for the 'asin' value
var result = /asin=([\d\w]+)/.exec (imgLink.getAttribute ('href') );
if( result) {
// make a new url using the 'base' and the 'asin' value
imgLink.setAttribute ('href', base+result[1]);
}
}
You could use regex to check for the link inside the HTML of the link:
for(var i = 0;i < links.length;i++) {
// check each link for the 'asin' value
var result = /asin=([\d\w]+)/.exec(links[i].getAttribute('href'));
// check each link for an img tag
var hasimage = /<img [^>]+>/.test(links[i].innerHTML);
if(result && hasimage){
// make a new url using the 'base' and the 'asin' value
links[i].setAttribute('href', base+result[1]);
}
}
Also, using regular expressions to search for HTML probably isn't the best bet, but if you control what's being generated, then this is probably the quickest way without a 3rd party html parser.
You can filter the links based on whether or not they contain an image.
var links = document.getElementsByTagName('a');
links = [].filter.call(links, function(item) {
// test to see if child node is an image
return item.childNodes[0].nodeName === 'IMG';
});
for(var i = 0;i < links.length;i++){
// do what you gotta do
}
You can just test for an IMG child and only process the link if there is one there.
Example on JSFiddle
// the new base url
var base = ' https://www.example.co.uk/gp/wine/order?ie=UTF8&asin=';
var links = document.getElementsByTagName('a');
for(var i = 0;i < links.length;i++){
var linkElement = links[i];
//get the first child of the a element
var firstChild = linkElement.children[0];
//if there is a child and it's an IMG then process this link
if (typeof(firstChild) !== "undefined" && firstChild.tagName=="IMG") {
// check each link for the 'asin' value
var result = /asin=([\d\w]+)/.exec(links[i].getAttribute('href'));
if(result){
// make a new url using the 'base' and the 'asin' value
links[i].setAttribute('href', base+result[1]);
}}
}
// the new base url
var base = ' https://www.example.co.uk/gp/wine/order?ie=UTF8&asin=';
var links = document.getElementsByTagName('img');
var hrefs = links.parent;
for(var i = 0;i < hrefs.length;i++){
// check each link for the 'asin' value
var result = /asin=([\d\w]+)/.exec(hrefs[i].getAttribute('href'));
if(result){
// make a new url using the 'base' and the 'asin' value
hrefs[i].setAttribute('href', base+result[1]);
}
}
There is a links collection, and you can can just check if the link has an image child node:
var link, links = document.links;
var re = /asin=([\d\w]+)/;
for (var i=0, iLen=links.length; i<iLen; i++) {
link = links[i]
if (link.getElementsByTagName('img').length && re.test(link.href)) {
link.href = base + result[1];
}
}
My initial response would be to look into query Select All and then assign a class name to grab on all of the a tags that would be affected by whatever your trying to do. When I get to my laptop I'll edit this with an example.

Categories

Resources