Using 'vanilla' JS to set CSS property on selected elements - javascript

JavaScript Newbie so the following question maybe 'dumb'.
For my work I do a little GreaseMonkey scripting to make our eCommerce store back end a little more friendly to our customer service team. Normally I'd make a new or better UI for them setup a special role or something, but with this current system, this is literally not an option.
Specifically I make a selection of links visibility: hidden, as they trigger some reporting functions which can lock up the backend till the reports are completed.
Up to this point I have had the script load jQuery, which is fine but not ideal. Then I dug in and saw that the interface was built using YUI, while this is already loaded, the syntax is weird to me, and I don't like it much, plus it is now not supported.
Recently I found the Plain JS site, which describes how to use 'vanilla' JS to do jQuery like things. Splendid! I thought, Now I can just write simple JS without extra dependencies or libs! But this is not quite the case.
I have tried the following:
var links = Array.from(document.querySelectorAll("a")); // creates an actual array from the node list returned by document.query
var links_to_hide = links.slice(14, 22); // gets just the bits we want to affect from the array, and is still an array
// ok so 'links_to_hide' is an array, and it is an array of 'a' anchor tags.
// if I go into the inspector and set the visibility property it affects the tag but doing it via scripting seems to not work.
// so if links_to_hide is an array it should be possible to
for(var i = links_to_hide.length; i <= links_to_hide.length; i++){
links_to_hide.style['visibility'] = 'hidden';
}
// this for loop doesn't seem to actually affect anything
What am I missing. Near as I can tell this should work.

Change this:
for(var i = links_to_hide.length; i <= links_to_hide.length; i++){
links_to_hide.style['visibility'] = 'hidden';
}
To this
for(var i = 0; i < links_to_hide.length; i++){
links_to_hide[i].style['visibility'] = 'hidden';
}

You aren't using i
links_to_hide[i].style.visibility = 'hidden';

Your for loop should be like below:
for(var i = 0; i < links_to_hide.length; i++){
links_to_hide[i].style.visibility = 'hidden';
}

Related

What is a safe alternative to .innerHTML and Jquery .append?

Firefox addon got removed because of unsafe assignment to innerHTML. Replaced it with the Jquery append(), but it is also unsafe. What can I use instead?
I need to add content dynamically to the extension's DOM. Mozilla gave me this link when they took down the addon: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Safely_inserting_external_content_into_a_page
But I can not figure out from the link how to add nodes to an existing node in a safe way.
This is an example of what i'm doing now. I have several places where I append a node to another node. In this case I need to make a div for every category and add it to the node "folders"
var folders = $("#folders");
for (var i = 0; i < categories.length; i++) {
var s = categories[i];
var categoryFolder = $("<div>");
categoryFolder.addClass("folder");
categoryFolder.attr("id",s);
categoryFolder.text(s);
folders.append(categoryFolder);
}

How to change CSS file using JavaScript?

I would ask how to change src of CSS using pure Javascript. I saw on internet that one guy used cookies for this, by i tried sth like this:
window.onload = function onload() {
setTimeout(function(){
document.styleSheets[1].href = "file:///C:/Users/Ma%C5%9Blan/Desktop/Site/bootstrap-3.3.6-dist/project1a.css";
}, 3000);
};
And it didn't work (i want to change CSS after 3 s, i know that actual localization is local, on my PC. Just trying :) ). I want to swap whole file.
Any ideas? If it's impossible in pure JS, show me jQuery way then.
Thanks!
document.styleSheets is a READ-ONLY property, so you won't be able to change the properties of that array.
What you want to do instead is get a list of all the <link> elements in the head, then either use a regex or conditional statement to get the element you are looking to replace, and use .href on that element.
E.G.
// get all links in the head (including CSS)
var allLinks = document.head.getElementsByTagName('link');
// find and replace the element
for (var i = 0; i < allLinks.length; i++) {
if ( allLinks[i].href = "old/url/to/css/file.css") {
allLinks[i].href = "file:///C:/Users/Ma%C5%9Blan/Desktop/Site/bootstrap-3.3.6-dist/project1a.css";
}
}

Issue with my function using associative array (dom objects) and for loop

Knowledge: First week Javascript
I am trying to learn real javascript and avoid jquery at all cost. Now I am I recently learned that id's can be style easily but not classes. In order to style a class I need to loop through the dom for the class. My original code works, however my new one does not. Best practices aside for a moment, I am trying to learn how this works regardless if it is a perfect solution or not.
Problem specifics: In my new code I stored the two get functions in keys within an associative array. So I have objects which I would like my for loop to understand. I am trying to make it work like my first code.
What I tried: Honestly, I read something about squared bracket notation and how it can be useful. I felt a bit overwhelmed to be honest. What I tried was:
source[_class][i]
Maybe _class is undefined even though I defined it. I specified what class contains. Honestly im lost and would appreciate some help and of course I welcome best practice advice as well.
I want to be a better programmer and I would appreciate some insight. I dont want to start with jquery.
My experiment:
setTimeout(function() {
var source = {_id: document.getElementById('box'),
_class: document.getElementsByClassName('hint')};
for (var i = 0; i < source[_class].length; i++) {
source[_class + i].style.opacity = '0';
console.log(i);
}
}, 1000);
My original working code:
// setTimeout(function() {
// var divs = document.getElementsByClassName('hint');
// for (var i = 0; i < divs.length; i++) {
// divs[i].style.opacity = '0';
// console.log(i);
// }
// }, 1000);
Use source._class.length instead of source[_class].length and source._class[i] instead of source[_class + i]:
for (var i = 0; i < source._class.length; i++) {
source._class[i].style.opacity = '0';
console.log(i);
}
source is an object and has a property _class. You can access properties either as source._class or as source['_class'].
The property source._class is an collection of DOM nodes itself so it can be accessed like an array. You can access array elements like this: array[index].
So you have both an object with properties and an array with elements. You need to access their contents appropriately.
Styling should be done with css, not loops, because using css is an order of magnitude faster.
Create css class definitions for your set of styles and then simply change the name of the class on your elements to change their style.
Also, look into using css selectors to query the DOM. This is done with querySelector for a single element, or querySelectorAll for a set of elements. Note that jQuery wraps this functionality and that is where the name is derived.
For your specific example, the problem was with accessing the array, instead of adding the i index, you need to reference the array, and you also need to make sure you are using a string index or a dot notation (such as source._class) in order to reference that object's property
for (var i = 0; i < source['_class'].length; i++) {
source['_class'][i].style.opacity = '0';
console.log(i);
}
You missed a square bracket and it's text not a variable:
source[_class + i].style.opacity = '0';
should be
source["_class"][i].style.opacity = '0';

Giving a different id to each child of an element

First question ever, new to programming. I'll try to be as concise as possible.
What I want to do is to create a bunch of children inside a selected div and give each of them specific html content (from a predefined array) and a different id to each child.
I created this loop for the effect:
Game.showOptions = function() {
var i = 0;
Game.choiceElement.html("");
for (i=0; i<Game.event[Game.state].options.length; i++) {
Game.choiceElement.append(Game.event[Game.state].options[i].response);
Game.choiceElement.children()[i].attr("id","choice1");
}
};
Using the predefined values of an array:
Game.event[0] = { text: "Hello, welcome.",
options: [{response: "<a><p>1. Um, hello...</p></a>"},
{response: "<a><p>2. How are you?</p></a>"}]
};
This method does not seem to be working, because the loop stops running after only one iteration. I sincerely have no idea why. If there is a completely different way of getting what I need, I'm all ears.
If I define the id attribute of each individual p inside the array, it works, but I want to avoid that.
The idea is creating a fully functional algorithm for dialogue choices (text-based rpg style) that would work with a predefined array.
Thanks in advance.
The problem with your loop as I see it could be in a couple different places. Here are three things you should check for, and that I am assuming you have but just didn't show us...
Is Game defined as an object?
var Game = {};
Is event defined as an array?
Game.event = new Array();
Is Game.state returning a number, and the appropriate number at that? I imagine this would be a little more dynamic then I have written here, but hopefully you'll get the idea.
Game.state = 0;
Now assuming all of the above is working properly...
Use eq(i) instead of [i].
for (var i = 0; i<Game.event[Game.state].options.length; i++) {
Game.choiceElement.append(Game.event[Game.state].options[i].response);
Game.choiceElement.children().eq(i).attr("id","choice" + (i + 1));
}
Here is the JSFiddle.

javascript/jquery - dynamically add data by id to an array

Attempting to build a resume creator as a project for codeacademy.
I'm using a button to "save" the user's input to an array so it can later be appended into the resume.
However, I'm failing at getting the data to "save" to the array. I've looked at similar questions here on stackoverflow and I cannot for the life of me figure out what I am doing wrong.
here's my fiddle
specific code block I'm having trouble with:
$('#experiencesave').click(function(){
for (var i = 0; i < jobs; i++){
jobtitle.push = $('#jobtitle'+i).val();
}
$('#morejobs').append(jobtitle);
});
Well, .push [MDN] is a function which has to be called:
jobtitle.push($('#jobtitle'+i).val());
As an alternative solution, instead of using a for loop, you might want to use .map to collect the values:
var jobtitle = $('input[id^=jobtitle]').map(function() {
return this.value;
}).get();
I don't see a reason to give each of those input elements an ID though. Just give them a class. That makes it a bit easier to bulk-process them later. E.g. the selector could then just be $('input.jobtitle').

Categories

Resources