How to set active class in Chrome Extension - javascript

I am making a chrome extension and have this in my popup.html:
<nav id="secondary-nav">
<ul>
<li class="active">Prerender</li>
<li>Prefetch</li>
<li>Preconnect</li>
</ul>
</nav>
What I want to do is to change the active link onclick in pure JS. How and where can I do that?
Should I make it in the background.js?
Thank you.

According to the Google Developper documentation you can link any other JS file to your main html file.
<!DOCTYPE html>
<html>
...
<body>
<script src="popup.js"></script>
</body>
</html>
And if you want to set the <li> active when you click on it, you should use something like this :
var menu = document.getElementById("menu");
var menu_items = menu.children;
for (var i = 0; i < menu_items.length; i++) {
menu_items[i].onclick = function() {
this.classList.add("active");
// don't forget to reset the class of others
for (var j = 0; j < menu_items.length; j++) {
if (menu_items[j] != this) menu_items[j].classList.remove("active");
}
}
}
li.active {
color: green;
}
<ul id="menu">
<li class="active">link1</li>
<li>link2</li>
<li>link3</li>
<li>link4</li>
</ul>

Related

I'm trying to get the parent of the parent (div) of the li-element which I click

I'm trying to get the parent of the parent (div) of the li-element which I click and change/remove it's class but I don't know how to tell JS that it should get the specific li class that I click. Sorry for this simple question I'm fairly new to JS.
<!DOCTYPE html>
<html>
<body>
<p>List:</p>
<div class="div">
<ul>
<li class="lis">Coffee</li>
<li class="lis">Tea</li>
<li class="lis">Water</li>
</ul>
</div>
<script>
let li = document.getElementsByClassName("lis")
li.click() = function() {
var x = li.parentElement.parentElement.classList.value
if(x.classList.contains("div")) {
x.remove.classList("div")
}
}
</script>
</body>
</html>
<script>
var elements = document.getElementsByClassName("lis");
var myFunction = function(e) {
x = e.target.innerHTML;
e.target.parentElement.parentElement.innerHTML=x
};
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', myFunction, false);
}
</script>
You can use .closest() to select the closest div and after that, you can remove the class from that element.
Try below working code -
var elements = document.getElementsByClassName("lis");
var myFunction = function() {
var x = this.closest('.div')
if (x) {
this.closest('.div').classList.remove("div")
console.log('Div Element Class Removed!');
}
};
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', myFunction, false);
}
<!DOCTYPE html>
<html>
<body>
<p>List:</p>
<div class="div">
<ul>
<li class="lis">Coffee</li>
<li class="lis">Tea</li>
<li class="lis">Water</li>
</ul>
</div>
</body>
</html>
I recommend to delegate to the nearest static container
Also you had remove.classList - that should be classList.remove
Here I give an ID to the UL and test if the LI clicked has the lis class
document.getElementById("ul").addEventListener("click",function(e) {
const tgt = e.target.closest("li")
if (tgt.classList.contains("lis")) {
tgt.closest("div").classList.remove("div")
}
})
.div { background-color:red }
<p>List:</p>
<div class="div">
<ul id="ul">
<li class="lis">Coffee</li>
<li class="lis">Tea</li>
<li class="lis">Water</li>
</ul>
</div>
I came up with another good solution that let's me add and remove the div class, the parent of specified li elements. I added an extra div to make sure it always gets the certain parent that I've specified with .closest(body > div) and used a for loop to make the array that it creates select one certain li element, the one I currently click on.
<!DOCTYPE html>
<html>
<body>
<p>List:</p>
<div class="div">
<ul>
<li class="lis">Coffee</li>
<li class="lis">Tea</li>
<li class="lis">Water</li>
</ul>
</div>
<div>
<ul>
<li class="l">Coffee</li>
<li class="l">Tea</li>
<li class="l">Water</li>
</ul>
</div>
<script>
let lists = document.getElementsByClassName("lis");
let divs = document.getElementsByTagName("div");
for (let list of lists) {
list.addEventListener("click", () => {
list.closest("body > div")
for (let div of divs) {
div.addEventListener("click", () => {
if (div.classList.contains("div")) {
div.classList.remove("div")
} else {
div.classList.add("div")
}
})
}
})
}
</script>
<style>
.div {
color: brown;
font-size: larger;
}
</style>
</body>
</html>
var li = document.getElementsByClassName("lis");
for (var i=0; i<li.length; i++) {
li[i].onclick = function() {
var el = this.parentElement.parentElement;
if (el.className == "div") {
el.className = "";
}
}
}

How to go to from my initial page to a new html page with HTML [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I want to create on my website everytime someone press on of those item 1 ,2,3,4,5, or 6 then will seemed a message "You choose me!!!" and then (with a button maybe - I don't know ) will linked to a new html page.Example if item 1 as we name it HOME . If someone goes to HOME then a message will seemed(You choose me) and then will go to a new html page named HOME.I tryed to do that but I stucked. Until the code it worked is this.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-7">
<title>Untitled Document</title>
<script>
function MyFun(event){
t = event.target ;
if(t.tagName=='LI'){
t.innerHTML="You choose me!!!"
}
}
</script>
</head>
<body>
<ul onclick="MyFun(event)">
<li> item 1</li>
<li> item 2</li>
<li> item 3</li>
<li> item 4</li>
<li> item 5</li>
<li> item 6</li>
</ul>
</body>
</html>
var items = document.querySelectorAll("li"),
len = items.length,
alreadyAdded = [],
prevAdded = -1;
for (let i = 0; i < len; i++) {
items[i].addEventListener("click", function(e) {
if (e.target.tagName == "LI" && alreadyAdded[i] !== 1) {
var a = document.createElement("a");
a.href = "#your-path-" + (i + 1);
a.innerHTML = "You choose me! I'm the " + (i + 1) + " link";
this.appendChild(a);
if (prevAdded !== -1) {
items[prevAdded].removeChild(items[prevAdded].lastChild);
alreadyAdded[prevAdded] = -1;
}
alreadyAdded[i] = 1;
prevAdded = i;
}
});
}
li {
cursor: pointer;
margin: 12px;
}
a {
background: #eee;
padding: 0 0.25rem;
text-decoration: none;
border: 1px solid #aaa;
margin: 0 0.25rem;
border-radius:3px;
}
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-7">
<title>Untitled Document</title>
</head>
<body>
<ul id="items">
<li> item 1</li>
<li> item 2</li>
<li> item 3</li>
<li> item 4</li>
<li> item 5</li>
<li> item 6</li>
</ul>
</body>
</html>
The simplest answer to your question, is to set the variable location.href to your desired HTML file. If you want to display your message ("You chose me"), then wait 1 second before redirecting, use setTimeout().
function MyFun(event){
t = event.target ;
if(t.tagName=='LI'){
t.innerHTML="You choose me!!!"
setTimeout(()=>{
location.href = //the HTML path.
}, 1000);
}
}
Remember, you have to store your HTML path somewhere, and you may want to store it in a data-XXX attribute in each <li>, then getting it in your onclick function handler. See custom attributes.
This is very simplistic, however, and you may want to eventually consider using a framework with routing!

JS Dropdown Menu Behavior

I have a dropdown menu working but I can't figure out how to close the previous menu onclick. All the menues stay open so I need them to close when a different menu is open.
Please see my jsfiddle
https://jsfiddle.net/yvhnphp4/
$(document).ready(function(){
// Dropdown menu
var findDropdowns = document.querySelectorAll(".has-dropdown");
for(var i = 0; i < findDropdowns.length; i++) {
if(i == 0) {
var dropdownId = "has-dropdown-1";
findDropdowns[i].setAttribute("id", dropdownId);
}else {
var addOneToIndex = i + 1;
dropdownId = "has-dropdown-" + addOneToIndex;
findDropdowns[i].setAttribute("id", dropdownId);
}
var targetDropdown = document.getElementById(dropdownId);
targetDropdown.onclick = dropdownTrigger;
}
function dropdownTrigger(e) {
e.preventDefault();
var showHideDropdown = e.target.nextElementSibling;
showHideDropdown.setAttribute("class", "show");
}
});
<ul class="nav">
<li><a class="has-dropdown" href="">Link</a>
<ul>
<li>Sub-Link</li>
<li>Sub-Link</li>
<li>Sub-Link</li>
</ul>
</li>
<li><a class="has-dropdown" href="">Link</a>
<ul>
<li>Sub-Link</li>
<li>Sub-Link</li>
<li>Sub-Link</li>
</ul>
</li>
</ul>
.nav ul {display:none;}
.nav ul.show{display:block;}
You can simply remove the .show class from all ul tags in .nav that still have it, before opening a new dropdown:
function dropdownTrigger(e) {
var opened = document.querySelectorAll(".nav ul.show");
for(var i = 0; i < opened.length; i++) {
opened[i].removeAttribute("class");
}
...
}
Note that since you're using jQuery anyway ($(document).ready) there is probably a much better way to do this.
Also, use href="#" instead of href="".

Javascript hide/unhide text

I am having trouble figuring this out. After a user clicks Link1 I would like it to close when Link2 has been clicked using Javascript. I have seen an example or two with this working in jquery, but I already have a tone of code written using this method, so I would prefer to to have to start all over.Thanks everyone!
HTML...
<style>
.hidden { display: none; }
.visible { display: block; }
</style>
</head>
<body>
<div id="col2">
Link 1
<div id="contentONE" class="hidden">
<h3>contentONE</h3>
<ul>
<li>Content1.1</li>
<li>Content1.2</li>
</ul>
</div>
</div>
<div id="col2">
Link 2
<div id="contentTWO" class="hidden">
<h3>contentTWO</h3>
<ul>
<li>Content2.1</li>
<li>Content2.2</li>
</ul>
</div>
</div>
<script type="text/javascript">
function unhide(divID) {
var item = document.getElementById(divID);
if (item) {
item.className=(item.className=='hidden')?'unhidden':'hidden';
}
}
</script>
</body>
Try something like this:
var collapsables = document.getElementsByClassName('collapsable');
function unhide(divID) {
// Hide previous
for (var i = 0; i < collapsables.length; i++) {
collapsables[i].className = 'collapsable hidden';
}
// Show new
var item = document.getElementById(divID);
if (item) {
item.className = 'collapsable';
}
}
Demo: http://jsfiddle.net/MLmXa/

Javascript to hide every element in div if it's height is 0

I'm looking for a way to hide every element (set to display:none) in a div (marked with a class or an id) if the height of the element is 0.
Example. Hide elem1 and elem4
<div class="container">
<ul id="elem1" style="height:0"> ... </ul>
<ul id="elem2" style="height:50"> ... </ul>
<ul id="elem3" style="height:40"> ... </ul>
<ul id="elem4" style="height:0"> ... </ul>
<ul id="elem5" style="height:60"> ... </ul>
</div>
Please help
Try this one for size:
.container ul[style="height:0"] {
display: none;
}
Demo: http://jsfiddle.net/qwertynl/yBJEe/
The following will work no matter if there is a space after the : or not:
.container ul[style~="0"], .container ul[style="height:0"] {
display: none;
}
Demo: http://jsfiddle.net/qwertynl/yBJEe/3/
Pure JS sample. Mark your elements with a class. This will work:
<div class="container">
<ul class='yourClass' id="elem1" style="height:0">.1..</ul>
<ul class='yourClass' id="elem2" style="height:50">.2..</ul>
<ul class='yourClass' id="elem3" style="height:40">.3..</ul>
<ul class='yourClass' id="elem4" style="height:0">.4..</ul>
<ul class='yourClass' id="elem5" style="height:60">.5..</ul>
</div>
JS script:
(function hideElements() {
var the_elements = document.getElementsByClassName('yourClass');
for (var i = 0; i < the_elements.length; ++i) {
var item = the_elements[i];
if (item.style.height === '0px') {
item.style.display = 'none';
}
}
})();
Note that the value retrieved is '0px'.
JSFiddle working sample: http://jsfiddle.net/amontellano/EgHLt/5/
This CSS block would help
.container ul {
overflow: hidden;
}
You can do it like this, using querySelectorAll()
var x = document.querySelectorAll("ul[id*='elem']"); //select all elements with an ID containing 'elem'
for (var i=0; i<x.length; i++) { //loop the element array and check if height == 0
if (x[i].style.height == 0) x[i].style.display = "none"; //set display to none
}

Categories