Replacing <li> image using javascript function - javascript

I am trying to replace the 3rd star in this list with an empty star based on a function. If the user has over 10 moves, the 3rd star should be replaced. After 14 moves, the 2nd star should also be replaced. I've tried the replaceChild Node but I can't get it working at all. Below is the UL list and as well as the function that I'm trying to associate it with. Is the replaceChild node the best method?
<div id="starRating">
<ul id="stars" class="starlist" style="list-style-type:none">
<li><img src="/images/filledstar.png" id="star1"> </li>
<li><img src="/images/filledstar.png" id="star2"> </li>
<li><img src="/images/filledstar.png" id="star3"> </li>
<li><img src="/images/emptystar.png" id="star4"> </li>
</ul>
</div>
function playerRating(moves) { //determines rating based on how many moves the player takes
var rating = 3;
if (moves > 10 && moves <= 13) {
rating = 2;
} else if (moves >= 14) {
rating = 1;
} else {
rating = 3;
} return rating;
document.getElementById("rating").innerHTML = "Rating: "+ rating;
}

You didn't explain what triggers the function, but it would work something like this:
// Get star references for empty and filled in
var filledStar1 = document.getElementById("filled1");
var filledStar2 = document.getElementById("filled2");
var filledStar3 = document.getElementById("filled3");
var emptyStar = document.getElementById("empty");
function playerRating(moves) {
var rating = 3;
if (moves > 10 && moves <= 13) {
filledStar3.src = emptyStar.src;
rating = 2;
} else if (moves >= 14) {
filledStar2.src = emptyStar.src;
filledStar3.src = emptyStar.src;
rating = 1;
}
return rating;
document.getElementById("rating").textContent = "Rating: " + rating;
}
// Try these one at a time and you will see the ratings work
playerRating(9);
playerRating(11);
playerRating(14);
img {width:50px;}
<div id="starRating">
<ul id="stars" class="starlist" style="list-style-type:none">
<li><img src="http://www.bombmanual.com/manual/1/html/img/symbols/2-filledstar.png" id="filled1"> </li>
<li><img src="http://www.bombmanual.com/manual/1/html/img/symbols/2-filledstar.png" id="filled2"> </li>
<li><img src="http://www.bombmanual.com/manual/1/html/img/symbols/2-filledstar.png" id="filled3"> </li>
<li><img src="https://cdn2.iconfinder.com/data/icons/snipicons/500/star-empty-m-128.png" id="empty"> </li>
</ul>
</div>
<p id="rating"></p>

Related

[Plain javascript]My mouseover effect is buggy

I'm trying to achieve a mouse hover effect using Js on three <li>s.
The effect doesn't work on the first try, I have to keep hovering my mouse again and again to go back to its original string.
note: i linked the script at the right before </body>
HTML code:
<ul>
<li data-value="// ABOUT" ><a href="#" >// ABOUT </a></li>
<li data-value="// PROJECTS" ><a href='#' >// PROJECTS </a></li>
<li data-value="// CONTACT" ><a href="#" >// CONTACT </a></li>
</ul>
Javascript code:
const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let interval = null;
document.querySelectorAll("li").forEach(li => {
li.onmouseover = event => {
let iteration = 0;
clearInterval(interval);
interval = setInterval(() => {
event.target.innerText = event.target.innerText
.split("")
.map((letter, index) => {
if (index < iteration) {
return event.target.dataset.value[index];
}
return letters[Math.floor(Math.random() * 26)];
})
.join("");
if (iteration >= event.target.dataset.value.length) {
clearInterval(interval);
}
iteration += 1 / 3;
}, 30);
};
});
1- you don't need to use event.target because you only use arrow function.
2- the interval variable should be local to avoid conflicts in your multiples setInterval
3- your code remove all links -> ex <li><a href="#" >// ABOUT </a><li> by <li>// ABOUT <li>....
so, here it is... ( with some improvemnts )
const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
document.querySelectorAll('li').forEach( li_Elm =>
{
let interval = null
, li_aLink = li_Elm.querySelector('a')
, textInit = li_aLink.textContent
, length = textInit.length
;
li_Elm.onmouseover =_=>
{
let iteration = 0;
clearInterval(interval);
interval = setInterval(() =>
{
li_aLink.textContent = Array
.from( ({length}), (letter,index) =>
( index < iteration)
? textInit[index]
: letters[Math.floor(Math.random() * 26)]
).join('');
if (iteration >= length)
clearInterval(interval);
iteration += 1 / 3;
}
, 30);
};
});
<ul>
<li><a href="#" >// ABOUT </a></li>
<li><a href='#' >// PROJECTS </a></li>
<li><a href="#" >// CONTACT </a></li>
</ul>

Javascript how to check if a condition is already met and not apply it again?

Trying not set the background color every time the count is 7 or less, if its already red it shouldnt set it again.
<div class="parent">
<ul class="list">
<li class="item">Item 1</li>
<li class="item">Item 2</li>
<li class="item">Item 3</li>
<li class="item">Item 4</li>
<li class="item">Item 5</li>
<li class="item">Item 6</li>
<li class="item">Item 7</li>
</ul>
</div>
How can I stop setting the color over and over once the count is less than 7?
var parent = document.querySelector('.parent');
parent.addEventListener('click', changeColor, false);
function changeColor( e ) {
var element = e.target;
var item = document.querySelectorAll('.item');
element.parentNode.removeChild(element);
if( item.length <= 7 ) {
parent.style.background = "red";
console.log(
item.length + " set backgroud color"
)
}
}
DEMO http://jsfiddle.net/Grundizer/awc6rymn/
If I understand your question correctly, this should do the trick:
var parent = document.querySelector('.parent');
var background = 'false';
parent.addEventListener('click', changeColor, false);
function changeColor( e ) {
var element = e.target;
var item = document.querySelectorAll('.item');
element.parentNode.removeChild(element);
if( item.length <= 7 && parent.style.background != 'red') {
parent.style.background = "red";
console.log(
item.length + " set backgroud color"
)
}
You could remove event listener if count is under 7. That way, not only you're not changing color again, you're not running anything on click anymore.
if( item.length <= 7 ) {
parent.style.background = "red";
parent.removeEventListener('click', changeColor, false);
}
And if somewhere you have a function adding element, simply start listening again.

Drop down menu that runs functions not working

I am trying to make a store locator and I am having problems with the drop down menu, I wanted a drop down menu for the distance from the user to the shops so for example 1 mile 3 miles 10 miles and so on but I can't get a drop down menu to run a function that will show these locations I have tried a couple example I have seen on here for example
Calling javascript functions from drop down
But I can't get it to work for my code the code I am trying to run is:
function list() {
document.getElementById("myList").onchange = function() {
var sheet=document.getElementById("myList").value;
if(sheet == "one"){
showPosition();
}
else if(sheet == "two"){
showPosition2();
}
else if(sheet = "three"){
}
else{
}
return false
};
}
window.onload = list;
The function that I want it to run when I choose the first option in the menu is:
function showPosition(position) {
var locations = [
['store1', -2.063150, 52.516503, 4],
['store2', -2.064824, 52.518436, 5],
['store3', -2.068214, 52.519898, 3],
['store4', -2.068558, 52.512769, 2],
['store5', -2.070875, 52.510758, 1]
];
var lon1 = position.coords.longitude* 0.0174532925;
var lat1 = position.coords.latitude * 0.0174532925;
var i = 0;
while (i < locations.length)
{
x.innerHTML+= "<br>Distance " + calcDist(lon1, lat1, locations[i][1]*0.0174532925, locations[i][2]* 0.0174532925);
i++;
}
}
function calcDist(lon1, lat1, lon2, lat2)
{
return Math.acos(Math.sin(lat1)*Math.sin(lat2) +
Math.cos(lat1)*Math.cos(lat2) *
Math.cos(lon2-lon1)) * 3958;
}
And the menu that I'm using is:
<ul id="dropdown">
<li> Choose theme
<ul>
<li id="stylesheet1" > Default </li>
<li id="stylesheet2" > Theme 1 </li>
<li id="stylesheet3" > Theme 2 </li>
<li id="stylesheet4" > Theme 3 </li>
</ul>
</li>
</ul>
By looking at the code, I see one major error.
Change window.onload = list; to window.onload = list();
Demo - shows the passing of params
var testPosition = {
coords: {
longitude: 1,
latitude: 1
}
}
showPosition(testPosition);

Are you able to solve it? JavaScript carousel implementation using an array

I cannot solve this problem, are you able to solve it? I would need your expert advice on how to do it in JS vanilla or jQuery (optional).
A sample of code on jsfiddle would be high appreciated.
I have to display an array of 5 elements in a list with a limit of 3 at one time
var range = [0,1,2,3,4];
<ul>
<li>0</li>
<li>1</li>
<li>2</li>
</ul>
<div id="prev">prev</div>
<div id="next">next</div>
When user click on "next", I need to add a class "focus" on the first "li".
<ul>
<li class="focus">0</li>
<li>1</li>
<li>2</li>
</ul>
Second click on "next"
<ul>
<li>0</li>
<li class="focus">1</li>
<li>2</li>
</ul>
click on "next" ...
<ul>
<li>0</li>
<li>1</li>
<li class="focus">2</li>
</ul>
click on "next" ... note array shift
<ul>
<li>1</li>
<li>2</li>
<li class="focus">3</li>
</ul>
click on "next" ... array shift
<ul>
<li>2</li>
<li>3</li>
<li class="focus">4</li>
</ul>
click on "next" ... but I cannot go any further as there is not element in the array to be displayed, so if I clicking "prev" I would like have the reverse
click on "prev" …
<ul>
<li>2</li>
<li class="focus">3</li>
<li>4</li>
</ul>
click on "prev" …
<ul>
<li class="focus">2</li>
<li>3</li>
<li>4</li>
</ul>
click on "prev" … note array shift
<ul>
<li class="focus">1</li>
<li>2</li>
<li>3</li>
</ul>
click on "prev" … note array shift
<ul>
<li class="focus">0</li>
<li>1</li>
<li>2</li>
</ul>
click on "prev" … nothing happen it has we reach the beginning go the array
<ul>
<li class="focus">0</li>
<li>1</li>
<li>2</li>
</ul>
Any idea? Thanks in advance
Revised solutions as suggested in answers
http://jsfiddle.net/QwATR/
// Initalize everything
var curPos = 0;
var minIndex = 0;
var maxIndex = 2;
var clicks = 0;
var range = ['0','1','2','3','4','5','6','7','8','9','10'];
if($('li.focus').length === 0)
{
$('ul > li:eq(0)').addClass('focus');
$('ul > li').each(function(index){
$(this).text(range[index+curPos]);
});
}
// Next click handler
$('#next').click(function(){
if($('ul li').index($('li.focus')) < 2)
{
$('li.focus').removeClass('focus');
if(curPos < 2)
curPos++;
else
{
clicks++;
}
$('ul > li:eq('+curPos+')').addClass('focus');
} else {
if(clicks < range.length -3)
clicks++;
}
$('ul > li').each(function(index){
$(this).text(range[index+clicks]);
});
});
// Previous click handler
$('#prev').click(function(){
if($('ul li').index($('li.focus')) > 0)
{
$('li.focus').removeClass('focus');
if(curPos > 0)
curPos--;
else
{
clicks--;
}
$('ul > li:eq('+curPos+')').addClass('focus');
} else {
if(clicks > 0)
clicks--;
}
$('ul > li').each(function(index){
$(this).text(range[index+clicks]);
});
console.log('clicks after prev:' + clicks);
});
http://jsfiddle.net/QAsQj/2/
$(function(){
$("#next").click(function(){
if($(".focus").length == 0){
$("ul li:first-child").addClass("focus");
}
else{
if($(".focus").is(":last-child")){
$("ul li").each(function(){
var content = $(this).next("li").html();
$(this).empty().html(content);
}
$(".focus").html(/**WHATEVER YOUR NEXT CONTENT IS**/);
}
else{
var active = $(".focus");
$("ul li").removeClass("focus");
active.next("li").addClass("focus");
}
}
}
);
$("#prev").click(function(){
if($(".focus").length == 0){
break;
}
else{
if($(".focus").is(":first-child")){
$("ul li").each(function(){
var content = $(this).prev("li").html();
$(this).empty().html(content);
}
$(".focus").html(/**WHATEVER YOUR PREV CONTENT IS**/);
}
else{
var active = $(".focus");
$("ul li").removeClass("focus");
active.prev("li").addClass("focus");
}
}
}
);
}
);
This is quite straightforward in vanilla javascript (jsfiddle)
var range = [0, 1, 2, 3, 4],
lis = document.getElementsByTagName('li'),
foc, offset = 0;
function next() {
if (foc === undefined) {
foc = 0;
} else if (foc < lis.length - 1) {
foc++;
} else if (offset + foc < range.length - 1) {
offset++;
}
rewriteList();
}
function previous() {
if (foc === undefined) {
foc = 0;
} else if (foc > 0) {
foc--;
} else if (offset > 0) {
offset--;
}
rewriteList();
}
function rewriteList() {
for (var i = 0; i < lis.length; i++) {
lis[i].innerHTML = range[i + offset];
lis[i].className = i == foc ? 'focus' : '';
}
}
document.getElementById('prev').onclick = previous;
document.getElementById('next').onclick = next;
Alternatively you could set up the carousels with a constructor function (jsfiddle)

Array of numbers, check to see which 2 numbers the current value is between

I have an array of numbers. 0,136,1084,3521,3961,5631,6510,7901,8204 (which are the current scrollTops of all of the sections on one page.) I'm trying to find a way to take the current window scrollTop and find out which of these values it's currently between so that when the page is being scrolled, the active navigation item switches.
Currently, while scrolling, 'current page' skips 0 and goes straight to 1 in the array, and as a result, is unable to catch the last page.
currentPage = 0;
divOffset = new Array();
function setCurrentPage() {
divOffset = []; //this ends up as 0,136,1084,3521,3961,5631,6510,7901,8204
//get offset and ID of each section and add to array.
$(".section").each(function() {
sectionOffset = $(this).offset();
divOffset.push(Math.round(sectionOffset.top));
});
bodyOffset = $(window).scrollTop();
for(i=0; i < divOffset.length; i++) {
if( divOffset[i] >= bodyOffset ) {
currentPage = i;
$('#mainNav li').removeClass("active");
$("#mainNav li #a-" + currentPage).parent().addClass("active");
return false;
}
}
}
My navigation looks something like this:
<ul id="mainNav">
<li class="active">home</li>
<li class="menuLI"><a>works</a>
<ul>
<li><a href='#a-1' class='navA' id='a-1'>Websites</a></li>
<li><a href='#a-2' class='navA' id='a-2'>Illustrations</a></li>
<li><a href='#a-3' class='navA' id='a-3'>Photomanipulations</a></li>
<li><a href='#a-4' class='navA' id='a-4'>Glam Guitars</a></li>
<li><a href='#a-5' class='navA' id='a-5'>Logos</a></li>
<li><a href='#a-6' class='navA' id='a-6'>Photography</a></li>
</ul>
</li>
<li>about</li>
<li>contact</li>
</ul>
You can look at it here: http://glowtagdesign.com/index2.php#a-0
Assuming the array is sorted, try this:
var i;
for (i = 0; i < arr.length && pos < arr[i]; i++)
{
}
// i is now the number of items in the array less than pos
// pos is less than the first item -> 0
// pos is greater than the last item -> arr.length

Categories