How to scroll to li when is added - javascript

ul.cars(data-ng-show="$ctrl.hasCars")
li.skill("data-ng-repeat="car in $ctrl.cars")
How can I make my window automatically scroll to the last li when is added each time?

As mentioned in the comment you could use Element.scrollIntoView(), you could use :last-child selector to select the last li.
Here is an example of this in action.
var list = document.querySelector('.list');
var button = document.querySelector('.updateList');
function updateList(){
var number = Math.round(Math.random()*100);
var li = document.createElement('li');
li.textContent = number;
list.appendChild(li);
var lastLi = document.querySelector('.list li:last-child');
lastLi.scrollIntoView();
}
button.addEventListener('click', updateList);
.app{
width: 100vw;
height: 100vh;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<button class="updateList">Update List</button>
<div class="app"></div>
<ul class="list">
<li>hello</li>
<li>World</li>
<li>Whats up</li>
</ul>
</body>
</html>
Here is a jsbin of the above code https://jsbin.com/beqovi/edit?html,css,output

Related

Hiding classes by clicking outside

I made a script that when I click on the container it hides a list. However, what I have been trying to do is that the list should hide when clicking outside the container and not inside. I have been looking for answers but nothing really worked for me as I use classes. Does someone know a solution?
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width" />
<title>Hiding the list</title>
</head>
<body>
<h1>Hiding the list</h1>
<div class="list">Hide the list by clicking outside
<li>Text1</li>
<li>Text2</li>
<li>Text3</li>
</div>
<div class="list">Hide the list by clicking outside
<li>Text1</li>
<li>Text2</li>
<li>Text3</li>
</div>
</body>
</html>
<style>
.list {
width: 50%;
height: 100%;
background-color: #f2f2f2;
}
li {
}
</style>
<script>
function hide_list() {
var children = this.children;
for (let i = 0; i < children.length; i++) {
children[i].style.display = "none";
}
}
document.querySelectorAll(".list").forEach(function (elem) {
elem.addEventListener("click", hide_list);
});
</script>

Get the top part of the Window using JavaScript

I'm making a Navbar. Well, it is working correctly (I scroll down and the style changes), but then, when I scroll to the top, the styles stay the same. Is there a way to change styles when I scroll to the top part?
Here's the HTML
<div class="navbar">
<ul>
<li>Home</li>
<li>About us</li>
<li>Contact</li>
</ul>
<span>Visit San Francisco</span>
</div>
Here's the JavaScript:
var body = document.querySelector("body");
var navbar = document.querySelector(".navbar");
var cover = document.querySelector(".cover");
function changeNavbarStyle() {
navbar.classList.add("postConv");
}
function removeNavbarStyle() {
navbar.classList.remove("postConv");
}
body.onscroll = changeNavbarStyle;
Most of modern browsers such as "Firefox", "Opera", "Edge", ... use document.documentElement.scrollTop to detect the position of scroll from top of the page. So maybe if you change your script as follows, it works:
var body = document.querySelector("body");
var navbar = document.querySelector(".navbar");
var cover = document.querySelector(".cover");
function changeNavbarStyle() {
navbar.classList.add("postConv");
if(document.documentElement.scrollTop === 0) {
removeNavbarStyle();
}
}
function removeNavbarStyle() {
navbar.classList.remove("postConv");
}
body.onscroll = changeNavbarStyle;
body {
min-height: 850px;
}
.postConv {
background-color: #c5bdd1;
position: fixed;
top: 0;
left: 0;
width: 100%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>nav-style</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="navbar">
<ul>
<li>Home</li>
<li>About us</li>
<li>Contact</li>
</ul>
<span>Visit San Francisco</span>
</div>
<script src="script.js"></script>
</body>
</html>
You can use HTML DOM onScroll event.
So your HTML code would look like:
<body id="body" onscroll="scroll()">
<div class="navbar">
<ul>
<li>Home</li>
<li>About us</li>
<li>Contact</li>
</ul>
<span>Visit San Francisco</span>
</div>
</body>
And in your JavaScript code you will define your scroll() method like:
function scroll() {
var elmnt = document.getElementById("body");
var y = elmnt.scrollTop;
if(y == 0) {
navbar.classList.remove("postConv");
} else {
navbar.classList.add("postConv");
}
}

How to give a LI item a color on mouseover?

I want to color the LI item on mouseover with javascript.
for the people who think i can use Css. You are right but for this one i need Javascript
This is my code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DOM</title>
</head>
<body>
<p>An unordered list:</p>
<ul id='lijst'>
<li>Coffee</li>
<li>Thea</li>
<li>Milk</li>
</ul>
<p id="demo"></p>
<script>
window.onload = function() {
var list = document.getElementById('lijst');
var y = list.getElementsByTagName('LI');
list.addEventListener('mouseover', function(e) {
});
}
</script>
</body>
</html>
So, when you move with your mouse over coffee or thea or milk. Than they will be orange. But i have no idea how.
you can simply use css for this.
.list li:hover {
color : #FF0000
}
<ul class="list">
<li >Coffee</li>
<li >Thea</li>
<li >Milk</li>
</ul>
you can use javascript like this
function hoverList(list) {
list.style.color = "#FF0000";
}
<ul class="list">
<li onmouseover="hoverList(this)">Coffee</li>
<li onmouseover="hoverList(this)">Thea</li>
<li onmouseover="hoverList(this)">Milk</li>
</ul>
var list
var y
window.onload = function() {
list = document.getElementById('lijst');
y = list.getElementsByTagName('LI');
for(var i = 0; i<y.length; i++){
y[i].addEventListener('mouseover', function(e) {
this.style.color = 'blue'
});
y[i].addEventListener('mouseleave', function(e) {
this.style.color = 'black'
});
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DOM</title>
</head>
<body>
<p>An unordered list:</p>
<ul id='lijst'>
<li>Coffee</li>
<li>Thea</li>
<li>Milk</li>
</ul>
<p id="demo"></p>
</body>
</html>
You don't need JS for this. This can be easily achieved by CSS
Have an error
var list = document.getElementById('lijst');
var y = x.getElementsByTagName('LI');
don't have x var, change to
var list = document.getElementById('lijst');
var y = list.getElementsByTagName('LI');
The preferred way to handle this task is to use the hover property of CSS. The code for that is
<style>
li:hover{
color: orange
}
</style>
However, if you insist to use the mouseover property, you can by using the following way
<script>
var li = document.getElementsByClassName("item-list");
li[0].addEventListener('mousedown', function(){
this.style.color = "orange";
});
li[1].addEventListener('mouseover', function(){
this.style.color = "orange";
});
li[2].addEventListener('mouseover', function(){
this.style.color = "orange";
});
</script>

Trouble adding active class to buttons on website

I am trying to add an active class to my buttons so that when you click on them the hover animation would stay on the active button. It seems like something in my javascript does not follow through with my call to add the active class to whatever element I put it on. pls help thnx ^_^
https://jsfiddle.net/purpkev/pf1vzx2t/7/
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Ukiyo Sushi ツ</title>
<link href = "/style.css" type = "text/css" rel = "stylesheet">
<link href="https://fonts.googleapis.com/css?family=Fira+Sans&display=swap" rel="stylesheet">
<script src = "/script.js"></script>
</head>
<body>
<!--<div class = "hero active">
<div class = "hero1">
<div class = "hero2">-->
<header id = "bg">
<nav class = "navbar">
Ukiyo Sushi ツ
<ul>
<li>About us</li>
<li>Menu</li>
<li>Services</li>
<li>Contact</li>
</ul>
</nav>
<div class = "sushiPlatter">
<h2 id = "caption">Chef's Special Sushi Platter</h2>
<div class = "dots">
<button class = "dot" onclick = "imgslider(1)"></button>
<button class = "dot" onclick = "imgslider(2)"></button>
<button class = "dot" onclick = "imgslider(3)"></button>
</div>
View Menu
</div>
</header>
<!--</div>
</div>
</div>-->
<section class = "idkYet">
<div>
<span>hello I am filler content</span>
</div>
</section>
</body>
</html>
CSS:
.dots{
display: flex;
flex-direction: column;
align-self: flex-end;
margin: 0 1em;
}
.dot{
display: inline-block;
cursor: pointer;
height: 15px;
width: 15px;
background-color: transparent;
border: solid 2px white;
border-radius: 50%;
margin: .2em;
transform: scale(.75);
outline-color: white;
}
.active{
transform: scale(1);
opacity: .25;
}
.dot:hover, .dot:hover, .dot:hover{
transform: scale(1);
opacity: .25;
transition: transform 1s ease-in;
transition: opacity .5s;
}
Javascript:
function buttonClick(){
var button = document.getElementsByClassName("dots");
var dot = button.children;
dot[0].classList.add("active");
for(var i = 0; i < dot.length; i++){
dot[i].addEventListener("click", function(){
var active = document.getElementsByClassName("active");
active[0].className = active[0].className.replace("active", "");
this.className += "active";
});
}
}
edit:
I have tried suggestions in the comments but the active class still does not get added to the active button, here is what my code looks like:
function buttonClick(){
var button = document.getElementsByClassName("dots");
var dot = button[0].children;
dot[0].classList.add("active");
for(var i = 0; i < dot.length; i++){
dot[i].addEventListener("click", function(){
var active = document.getElementsByClassName("active");
active[0].className = active[0].className.replace("active", "");
this.className += "active";
});
}
}
document.getElementsByClassName returns array.
Use button[0].children or button = document.getElementsByClassName("dots")[0]
I am not very good at vanilla javascript. I will do the equivalent of jQuery as follows
$('.dots').on('click', '.dot', function(e) {
el = $(this);
el.parents('.dots').find('dot').removeClass('active');
el.addClass('active');
});
Looks like you're adding eventListeners again and again.
Maybe try this approach, where you send the button element to the function using the "this" keyword....
(see fiddle: https://jsfiddle.net/sre1dua9/1/ )
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Ukiyo Sushi ツ</title>
<link href = "/style.css" type = "text/css" rel = "stylesheet">
<link href="https://fonts.googleapis.com/css?family=Fira+Sans&display=swap" rel="stylesheet">
<script src = "/script.js"></script>
</head>
<body>
<!--<div class = "hero active">
<div class = "hero1">
<div class = "hero2">-->
<header id = "bg">
<nav class = "navbar">
Ukiyo Sushi ツ
<ul>
<li>About us</li>
<li>Menu</li>
<li>Services</li>
<li>Contact</li>
</ul>
</nav>
<div class = "sushiPlatter">
<h2 id = "caption">Chef's Special Sushi Platter</h2>
<div class = "dots">
<button class = "dot" onclick="window.imgslider(this, 1)"></button>
<button class = "dot" onclick="window.imgslider(this, 2)"></button>
<button class = "dot" onclick="window.imgslider(this, 3)"></button>
</div>
View Menu
</div>
</header>
<!--</div>
</div>
</div>-->
<section class = "idkYet">
<div>
<span>hello I am filler content</span>
</div>
</section>
</body>
</html>
Then just track the last button clicked:
var lastDot = null;
window.imgslider = function(elem, x)
{
var bg = document.getElementById("bg");
var dot = document.getElementsByClassName("dot");
var caption = document.getElementById("caption");
switch(x){
case 1:
bg.style.backgroundImage = "-webkit-linear-gradient(rgba(0,0,0,.375), rgba(0,0,0,.375)),url(/img/header.jpg)";
caption.style.marginLeft = "0em";
caption.innerHTML = "Chef's Special Sushi Platter";
break;
case 2:
bg.style.backgroundImage = "-webkit-linear-gradient(rgba(0,0,0,.375), rgba(0,0,0,.375)),url(/img/pokebowl.jpg)";
caption.style.marginLeft = "2em";
caption.innerHTML = "Spring Poke Bowl";
break;
case 3:
bg.style.backgroundImage = "-webkit-linear-gradient(rgba(0,0,0,.375), rgba(0,0,0,.375)),url(/img/ramen.jpg)";
caption.style.marginLeft = "3.75em";
caption.innerHTML = "Miso Ramen";
}
// do dots
if(lastDot){
lastDot.classList.remove("active");
}
elem.classList.add("active");
// store last dot for next click
lastDot = elem;
}

Understanding 'parentNode' of undefined error

I'm practicing basic JS skills by setting up little exercises for myself. In this one, I have a list of <a>s inside a div. The aim of the exercise is to wrap each <a> in a div. I'm using replaceChild in this instance.
Oddly (to me at least) the script works for the first three links, but after that throws an error:
Uncaught TypeError: Cannot read property 'parentNode' of undefined
I can't tell why the script partly works. Can anyone see what I'm doing wrong here? Here's the code I'm using:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style media="all">
div div {padding: 10px; background: #e7e7e7; margin: 5px;}
</style>
</head>
<body>
<div>
link
link
link
link
link
link
</div>
<script>
var links = document.getElementsByTagName("a");
for (var i=0, ii=links.length; i<ii; i++)
{
var container = document.createElement("div");
links[i].parentNode.replaceChild(container, links[i]);
container.appendChild(links[i]);
}
</script>
</body>
</html>
and here's an online version: http://codepen.io/anon/pen/Lpuky
I've tried the few debugging techniques that I know of and read about this error message, but haven't worked out what's wrong here. Seems funny to me that it works for 3 of the 6 links.
The collection links is NodeList and is live.
Since you are replacing them, they are disappearing from the collection and our index into them is no longer pointing to anything.
You're modifying the nodelist as you iterate over it. Use the Array slice method to make a copy of the list:
var linksCopy = Array.prototype.slice.call(links);
for (var i=0; i<linksCopy.length; i++)
{
var container = document.createElement("div");
linksCopy[i].parentNode.replaceChild(container, linksCopy[i]);
container.appendChild(linksCopy[i]);
}
Regarding your own follow-up answer: if your objective was simply to find the easiest way to wrap the <a>s in <div>s, rather than to practice with createElement, replaceChild or appendChild or any of the other methods, this would be it:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo</title>
<style>
div div {
padding: 10px;
background: #e7e7e7;
margin: 5px;
}
</style>
</head>
<body>
<div>
link
link
link
link
link
link
</div>
<script>
var links = document.querySelectorAll("a");
for (var i=0; i<links.length; i++) {
links[i].outerHTML = '<div>'+links[i].outerHTML+'</div>';
}
</script>
</body>
</html>
.
Live demo here: http://jsbin.com/jasoho/1/edit?html,output. Another advantage of the outerHTML method is that it doesn't change the nodeList. So you can also use getElementsByTagName in stead of querySelectorAll.
As a follow up to this, I often hear that querySelectorAll() is different in that it returns a static Nodelist rather than an array, so I thought that might come in handy here, and indeed it does:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style media="all">
div div {padding: 10px; background: #e7e7e7; margin: 5px;}
</style>
</head>
<body>
<div>
link
link
link
link
link
link
</div>
<script>
var links = document.querySelectorAll("a");
for (var i=0, ii=links.length; i<ii; i++)
{
var container = document.createElement("div");
links[i].parentNode.replaceChild(container, links[i]);
container.appendChild(links[i]);
}
</script>
</body>
</html>
Also, an alternative to Array.prototype.slice.call(links) is [].slice.call(links):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style media="all">
div div {padding: 10px; background: #e7e7e7; margin: 5px;}
</style>
</head>
<body>
<div>
link
link
link
link
link
link
</div>
<script>
var links = document.getElementsByTagName("a");
var linksCopy = [].slice.call(links);
for (var i=0; i<linksCopy.length; i++)
{
var container = document.createElement("div");
linksCopy[i].parentNode.replaceChild(container, linksCopy[i]);
container.appendChild(linksCopy[i]);
}
</script>
</body>
</html>
And another option again is to use [].forEach.call():
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style media="all">
div div {padding: 10px; background: #e7e7e7; margin: 5px;}
</style>
</head>
<body>
<div>
link
link
link
link
link
link
</div>
<script>
[].forEach.call(document.querySelectorAll('a'), function(el) {
var container = document.createElement("div");
el.parentNode.replaceChild(container, el);
container.appendChild(el);
});
</script>
</body>
</html>
Yet another option, using Array.from():
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style media="all">
div div {padding: 10px; background: #e7e7e7; margin: 5px;}
</style>
</head>
<body>
<div>
link
link
link
link
link
link
</div>
<script>
var links = document.getElementsByTagName("a");
var linksCopy = Array.from(links);
for (var i=0; i<linksCopy.length; i++)
{
var container = document.createElement("div");
linksCopy[i].parentNode.replaceChild(container, linksCopy[i]);
container.appendChild(linksCopy[i]);
}
</script>
</body>
</html>

Categories

Resources