Extract the target from the loop in JavaScript and process it externally

I am looking to extract the values from a loop and manipulate them outside of it.

Specifically, I want to target all elements with the class "testY" and only apply changes to the last one.

let classes = Array.from(document.getElementsByClassName("testY"));
classes.forEach(function (looped, i) {
        loopclass = looped;
        loopclass.style.color = "blue";
        return loopclass;
});
loopclass.style.color = "orange";

However, only the last element is turning orange. How can I recycle these elements without being confined within the loop?


---- EDIT 1

Building on the previous code, I want to retrieve the classes and manipulate them outside of the loop.

Here is another example based on the suggestions:

let classeslist = Array.from(document.getElementsByClassName("testY"));
let classes = classeslist.map( (el) => {
        loopedclass = el;
        return loopedclass
});
loopedclass.style.color = "orange";

Even with this approach, only the last class is affected.


---- EDIT 2.B

We're getting there.

The concept works but chaining remains an issue.

I tried to incorporate the FrankerZ constructor into the code, but got stuck.

Now, the question revolves around libraries... How do you concatenate the results of functions?

LIBS:

actions = {

    showError: (elem) => {
        elem.style.color = 'red';
    },
    highlight: (elem) => {
        elem.style.color = 'orange';
        elem.style.fontSize = '1.2em;';
    }
}

class Core {

    find(subject) //works
    {
        let name;

        if (subject.startsWith("#")) {
           ...
        }
        if (subject.startsWith(".")) {
            name = subject.split(".")[1];
            find = [...document.getElementsByClassName(name)];
        }
        if (subject.startsWith("[")) {
           ...
        }
        return find;
    }

    actionfor(target, todo) //works
    {
        target.forEach(actions[todo]);
    }

    loop(todo)
    {
        alert("direct todo");
        ???.forEach(actions[todo]);
    }
}
const core = new Core();

SCRIPT:

(function () {

       //indirect action // works!
       var X = core.find(".test_X");
       core.actionfor(X, "showError");

       //direct action //issue!
       core.find(".test_Y").loop("highlight");
})();

HTML:

<div class="test_X">SIMPLE TEST CLASS</div>
<div class="test_X">SIMPLE TEST CLASS</div>
<div class="test_X">SIMPLE TEST CLASS</div>
<div class="test_Y">SIMPLE TEST CLASS</div>
<div class="test_Y">SIMPLE TEST CLASS</div>
<div class="test_Y">SIMPLE TEST CLASS</div>

Answer №1

classes is an array, so if you wish to retrieve the last element, simply access it using indexes:

let classes = Array.from(document.getElementsByClassName("testY"));

classes[classes.length - 1].style.color = 'orange';
<span class="testY">Testing 1</span>
<span class="testY">Testing 2</span>
<span class="testY">Testing 3</span>

To address your other inquiry, as mentioned earlier, .forEach is not the appropriate method here. Instead, utilize .map() to map the elements to an array (in this scenario, the style of each element). Here, I'm setting all styles to blue initially, and then modifying the last element's color to orange:

let classes = Array.from(document.getElementsByClassName("testY"));

let styles = classes.map((el) => {
  el.style.color = 'blue';
  
  return el.style;
});

styles[styles.length - 1].color = 'orange';
<span class="testY">Testing 1</span>
<span class="testY">Testing 2</span>
<span class="testY">Testing 3</span>

Below is an example demonstrating how you can perform a function called .doSomething():

class LibElementHelper {
  constructor(elements) {
    this.elements = elements;
  }
  
  doSomething() {
    this.elements.forEach((el) => el.style.color = 'blue');
  }
}

class MyLib {
  getClass(className) {
    let classes = Array.from(document.getElementsByClassName(className));
    
    return new LibElementHelper(classes);
    
    //Alternatively:
    return {
      doSomething: () => classes.forEach((el) => el.style.color = 'blue')
    };
  }
}

var lib = new MyLib();

lib.getClass("testY").doSomething();
<span class="testY">Testing 1</span>
<span class="testY">Testing 2</span>
<span class="testY">Testing 3</span>

Answer №2

Your code below:

let classeslist = Array.from(document.getElementsByClassName("testY"));
let classes = classeslist.map( (el) => {
        loopedclass = el;
        return loopedclass
});
loopedclass.style.color = "orange";

even here, only the last class is collected and returned.

No, All the classes are returned(elements not classes to be precise). You don't need that map function at all since it does absolutely nothing. It returns the same element that it received as a parameter of map funciton. ( It does nothing ). Map function is supposed to take values from an array and change them( map them ) into something else.

One way of achieving your objective may be this:

// list of shared actions that can be used everywhere
Actions = {
  showError: (elem) => {
    elem.style.color = 'red';
  },
  clearError: (elem) => {
    elem.style.color = 'black';
  },
  hide: (elem) => {
    elem.style.display = 'none';
  },
  reveal: (elem) => {
    elem.style.display = 'block';
  },
  highlight: (elem) => {
    elem.style.color = 'orange';
    elem.style.fontSize = '1.2em;';
  } ,
  underline: (elem) => {
    elem.style.textDecoration = 'underline';
  }
}
// connect actions to classes
class ClassActions {
    action(className, action) {
      [...document.getElementsByClassName(className)].forEach(Actions[action]);
      return this;
    }
}
const classActions = new ClassActions();
// Use the class actions when buttons are clicked
function commentError() {
  classActions.action('comment', 'showError');
}
function commentHide() {
  classActions.action('comment', 'hide');
}
function commentReveal() {
  classActions.action('comment', 'reveal');
}
function commentHighlight() {
  classActions.action('comment', 'highlight');
}
function postHighlightAndUnderlineAndRemoveComments() {
  classActions
  .action('post', 'highlight')
  .action('post', 'underline')
  .action('comment', 'hide');
}
.post {
  padding: 2em;
}
.comment {
  color: gray;
  margin: 1em;
}
<div class='post'>Post 1</div>
<div class='comment'>Comment 1</div>
<div class='comment'>Comment 2</div>
<div class='comment'>Comment 3</div>

<div class='post'>Post 2</div>
<div class='comment'>Comment 1</div>
<div class='comment'>Comment 2</div>
<div class='comment'>Comment 3</div>

<button onclick="commentError()">comment error</button>
<button onclick="commentHide()">comment hide</button>
<button onclick="commentReveal()">comment reveal</button>
<button onclick="commentHighlight()">comment highlight</button>
<button onclick="postHighlight()">post highlight</button>

<button onclick="postHighlightAndUnderlineAndRemoveComments()">Highlight and underline and...</button>

Using functions to change styles may not always be necessary. First - try to utilize CSS for basic styling purposes. If needed, then move on to javascript for more complex solutions.

For instance, instead of using JS functions to change style properties, consider adding or removing classes in CSS for desired effects.

In CSS, styles have cascading behavior. So, to apply specific styles to elements based on some action, you can modify classes dynamically like this:

// CSS
.comment {color: black;}
.comment.error { opacity: 0.8; color: red; }

// JS
[...document.getElementsByClassName("comments")].forEach((e) => {
    e.classList.add('error');
});

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

Refresh outfit designs or retrieve information from fragment shader post-processing

While working on image processing in the fragment shader (specifically thresholding), I find myself wanting to access the processed result from JavaScript so that I can save the modified image using standard JavaScript methods. I send the original texture ...

What are the possible scenarios for utilizing the declaration int (*q)[3]; and what factors would prompt someone

I recently came across a question on stackoverflow that discussed the topic of C pointer to array/array of pointers disambiguation. The post delved into the declaration int (*q)[3]; // q is a pointer to array of size of 3 integers, shedding light on comple ...

Error encountered in Next.JS when calling getInitialProps(ctx) due to undefined ctx variable

This is my code import NavLayout from "../../components/Navigation/Navigation"; export default function WorldOfWarcraft({ game }) { return (<NavLayout> {game.link} </NavLayout>) } WorldOfWarcraft.getInitialProps = as ...

The value of the $scope variable remains constant within the function

I am facing an issue with a scope variable that I passed to a function. Even though the variable is accessible inside the function, its value does not change when I try to modify it. Below is my HTML code: <div class="console_item" ng-class="dropdwns.a ...

In what ways can I apply the outcome of this commitment?

I need help refining the buildQuery function for my social post feed: const buildQuery = (criteria) => { const { userId, interest } = criteria; const query = {}; if (interest !== 'everything') { if (interest === 'myInterests&a ...

Tips for utilizing the onClick function in jQuery on an element nested within a div that was dynamically added using jQuery beforehand

I have added some elements inside a div with the class .display_noti like this: $(document).ready(function(){ setTimeout(done,200); }); function done() { setTimeout(updates, 200); // Call updates in 200ms } function updates(){ $.getJSON("notificatio ...

How can I add labels to dataPoints chart in JavaScript?

I have data from a database that I want to use to create a chart with labels and values. I have already converted the data to a JSON object. Here is the basic script for setting the labels: <script> window.onload = function () { var arrc ...

Utilizing Asynchronous Values in a Different JavaScript Function

Currently delving into the world of destructuring arrays in Javascript, I find myself faced with the challenge of accessing these variables in other functions. I attempted to retrieve the array by calling a function and then using console.log(thermostatAr ...

Obtaining Distinct Values in AngularJS Using ng-option

My table contains the following data: info = [ {id: 1, name: 'Manchester United', type: 'Soccer', featured: true, country: 'England'}, {id: 2, name: 'Manchester City', type: 'Soccer', featured: false, ...

Issue with Angular FormControl Pattern Validator failing to validate against regex pattern

My goal is to restrict a text input field to specific characters only. I am looking to allow: alphanumeric characters (a-z A-Z 0-9) 3 special characters (comma, dash, single quotation mark) : , - ' A few accented characters: à â ç è é ê î ô ...

Is it possible to designate touch as the top finger and always have touch 2 be the bottom finger on the screen?

Is there a way to specify touch1 as the upper finger on the screen and always have touch2 as the lower finger, even if the lower touch is detected first? var touch1 = e.originalEvent.touches["0"]; var touch2 = e.originalEvent.touches["1"]; Can these ...

Modify KeyboardDatePicker to display the full name of the day and month

Date Selector Hey there, I'm looking to modify the date format from Wed, Apr 7 to Wednesday, April 7. Is there a way to display the full name of the day and month instead of the short abbreviation? ...

Retrieving a matching value in a JSON object using AngularJS

Utilizing AngularJS, I have a JSON object presented below; info = [ { "name": "Tom", "id": "111" }, { "name": "Sam", "id": "222" }, { "name": "James", "id": "333" } ] I aim to create a function that triggers a specific action when ...

Vue component encounters undefined error when passing prop array through component

My challenge is passing an array of dates to my component, but I keep encountering this error: [Vue warn]: Property or method "dates" is not defined on the instance but referenced during render I'm puzzled by this issue because I am receiving the ...

What is the best way to collapse an array within an object?

I'm looking for a way to flatten an array within an object using JavaScript, preferably ES6. I'm not sure if "flattening" is the correct term here, but I just want a solution to achieve this transformation. Currently, I have this structure: { ...

Error: Unable to Locate the jqueryFileTree Connector Script

I am currently working on a project to build a webpage that showcases a file tree. The jqueryFileTree plugin from the following site has been selected for this purpose: My plan is to eventually connect this tree to a server. But for now, my focus is on ge ...

Vue's animation happens without any delay or duration

I followed the Vue animation instructions from the documentation carefully: The transition component has a name="fade" attribute. v-if is placed in the child of the transition element. The styles were directly copied from the documentation provi ...

Is the performance impacted by using try / catch instead of the `.catch` observable operator when handling XHR requests?

Recently, I encountered an interesting scenario. While evaluating a new project and reviewing the codebase, I noticed that all HTTP requests within the service files were enclosed in a JavaScript try / catch block instead of utilizing the .catch observable ...

What is the process for moving entered data from one text box to another text box when a checkbox is selected?

I need help with a function that reflects data entered in one text box to another text box when a checkbox is ticked. The checkbox is initially checked and the values should change when it is unchecked and then checked again. Currently, the code is only ou ...

I am looking to implement a dropdown menu that appears after clicking on an image. Any suggestions on how to achieve this using

I've been experimenting with adding a dropdown class, but I'm feeling a bit lost on where to start. Here's a snippet of code that shows what I'd like to do to add a dropdown menu: <span id="dropdown-info" ng-init= "myVar='i ...