Issue with altering transparency using a JavaScript while loop

I'm attempting to create a blinking effect for an image by continuously fading it in and out. I've implemented two while loops to adjust the opacity attribute of the element - each loop changing the opacity by 10% and pausing for 10ms. Although the first loop runs smoothly, iterating 10 times before moving on, the second loop only adjusts the opacity once and then goes into an infinite loop without affecting the opacity further. Does anyone have insights on what might be causing this issue and how it can be resolved?

async function blink(){
    var arrow = document.getElementById('downArrow');
    arrow.style.opacity = 1;
    while(window.getComputedStyle(arrow).opacity > 0){
        arrow.style.opacity -= 0.1;
        await sleep(10);
        console.log('first loop');
    }
    while(window.getComputedStyle(arrow).opacity <= 1){
        arrow.style.opacity += 0.1;
        await sleep(10);
        console.log('second loop');

    }
    blink();
}


function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

Answer №1

You've encountered the quirky side of JavaScript ;)

arrow.style.opacity actually returns a string.

When you subtract a number from a string in JS, both operands are converted to numbers. For example, "1" - 0.1 will give you 0.9:

console.log("1" - 0.1);

However, when you try to add something to a string, both operands in JS are converted to strings. So, for instance, "0.1" + 0.1 will result in "0.10.1". This is what's happening in your code.

console.log("0.1" + 0.1);


To resolve this issue, you must convert the opacity to a number before adding another number to it.

Additionally, there's an incorrect condition in the second loop; it should be < 1, not <= 1.

Take a look at this:

async function blink(){
    var arrow = document.getElementById('downArrow');
    arrow.style.opacity = 1;
    while(window.getComputedStyle(arrow).opacity > 0){
        arrow.style.opacity -= 0.1;
        await sleep(10);
        console.log('first loop', arrow.style.opacity);
    }
    
    while(window.getComputedStyle(arrow).opacity < 1){ // Corrected to `< 1`
        arrow.style.opacity = +arrow.style.opacity + 0.1; // The addition converts it to a number
        await sleep(10);
        console.log('second loop', arrow.style.opacity);

    }
    blink();
}


function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

blink();
<div id="downArrow" style="width: 100px; height: 100px; background: red;"></div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I can't see the presence of spin.js on my website

I am completely new to Javascript and I'm trying to implement a loading spinner on my website. Whenever users tap the screen, it takes some time to navigate to the desired URL, so we need a spinner to prevent them from tapping repeatedly. I decided t ...

Service Worker unable to register due to an unsupported MIME type ('text/html') declared

Working on a project using create-react-app along with an express server. The pre-configured ServiceWorker in create-react-app is set up to cache local assets (https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README ...

I'm looking to provide the average rating of a restaurant along with the name of the owner

Currently, I am utilizing knex to craft queries for my express server. Within my database, I have two tables structured as follows: My objective is to establish a join between the two tables using the "owner_id" foreign key. Subsequently, I aim to retriev ...

Tips for identifying when the back button is pressed on an Android or iOS device using React.js

I recently completed a responsive website project utilizing React js and now I am looking to implement a confirmation popup when users press the Back button on their Android/iOS mobile devices. Can anyone provide guidance on detecting the back button pre ...

Using Vue's v-if statement to determine if a variable is either empty or null

Using a v-if statement to display certain HTML only if the archiveNote variable is not empty or null. <div v-if="archiveNote === null || archiveNote ===''" class="form-check ml-3" id="include-note-div"> Here is how it's implemented ...

struggling to correctly display json api data in javascript onto html

I am receiving a json API response from my JavaScript request. I can successfully print the output to the console and it appears properly formatted like this: { "id": "1", "name": "John" } However, when I try to display it on an HTML page, it looks l ...

Converting coordinates to pixel-based fixed positioning in CSS

After creating an animated square pie chart using basic CSS to display it in a grid format, I am now looking to transform the larger squares into a state map grid. Any ideas on how to achieve this? In my JavaScript code snippet below, I believe there is a ...

Retrieving the background image URL from inline CSS using jQuery

I'm looking for a link similar to url(img/bg/06.jpg), but when using jQuery, I get a longer link like url("file:///D:/WORKING%20FILE/One%20Landing%20Page/version/img/bg/06.jpg") https://i.stack.imgur.com/8WKgv.png Below is the code snippet in questi ...

Whenever I navigate to a new page in my NEXTJS project, it loads an excessive number of modules

I am currently working on a small Next.js project and facing an issue where the initial load time is excessively long. Whenever I click on a link to navigate to a page like home/product/[slug], it takes around 12 seconds to load due to compiling over 2000 ...

Validating dynamic textboxes in Angular with custom rules

Creating dynamic textboxes with *ngFor in Angular <tr *ngFor="let computer in _Computers; let i = index;"> <td>{{computer.Name}}</td><td>{{computer.Optional}}</td> <td> <input matInput [formControl] = " ...

Adjusting column styles on mobile or desktop devices

My row has two columns <div class="row"> <div class="col-9"> hello </div> <div class="col-3"> world </div> </div> But I want to change the column classes for small screens, so they would be ...

Pattern matching using regex can also be used to restrict the number of characters allowed

Having some trouble with regex to match a specific pattern and also limit the number of characters: Let's say I have allowed number prefixes: 2, 31, 32, 35, 37, 38, 39, 41, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60 I only want numb ...

The Challenge of Refreshing Static Site Generation in NextJS Version 13

I've encountered a problem with updating data on a basic data page. The situation is simple: there's a page that shows category data and another page that allows editing of the same data. After making edits and returning to the list page, I expec ...

Is it possible to share a Vue.js component by "transferring" it rather than duplicating it?

In my comment system project using Vue.js, I have over 300 comments to manage. Each comment has an admin section that appears when the cursor hovers over it. Duplicating the admin section component for each comment is not ideal as it creates unnecessary l ...

Encountering an Error during the Installation of MapBox SDK in React Native

After creating a React Native project with Expo using expo init MapTry, I encountered an issue while trying to install the MapBox library. Despite following the installation guide at https://github.com/rnmapbox/maps#Installation, I faced an error message w ...

AngularJS: Initiate a Bootstrap modal upon webpage loading

As I work on designing a web application using AngularJS, I aim to implement the launching of a bootstrap modal upon page load through AngularJS. Here is the structure of my modal: <div class="modal hide fade" id="myModal"> <div class="moda ...

Adjust an SVG text to fit perfectly within an SVG background rectangle

Inside this box are two SVGs: one for the text and one for the background rectangle. My goal is to make sure the text fits perfectly within the background rectangle without any stretching or overflowing. I don't want to break the text into multiple l ...

The keyboard automatically disappeared upon clicking the select2 input

Whenever I select the select2 input, the keyboard automatically closes $('select').on('select2:open', function(e) { $('.select2-search input').prop('focus',false); }); Feel free to watch this video for more i ...

What is the procedure for incorporating JavaScript into my tic-tac-toe game's HTML and CSS?

I have created a simple Tic Tac Toe game using HTML and CSS. Although there is no embedded Javascript, I do reference a Javascript file for functionality. Can anyone provide me with the most straightforward Javascript code that will display an 'X&apos ...

Using the CSS property `absolute` can result in the input element shifting when entering text in Chrome

My grid layout is causing some issues with the search box placement. Whenever a user starts typing in the input box, it jumps to the other side of the page. After investigating, I realized that the culprit is the position: absolute property. Oddly enough, ...