Styling elements using the nth-child selector in JavaScript

I am trying to apply a CSS class based on the combined height of the 2nd and 3rd child elements. For example, if the height of the 2nd child plus the height of the 3rd child equals a certain value, I want to add a specific class.

Here is my JavaScript code to perform this calculation -

$(function() {
var fl = $('ul img:nth-child(3n+3)').height();
var fr = $('ul img:nth-child(3n+4)').height();
var result = fl + fr;
if (result == 1092) {
    $('ul img:nth-child(3n+3)').addClass('style1a');
    $('ul img:nth-child(3n+4)').addClass('style1b');
}
else if (result == 2460) {
    $('ul img:nth-child(3n+3)').addClass('style2a');
    $('ul img:nth-child(3n+4)').addClass('style2b');
}
else if (result == 1776) {
    $('ul img:nth-child(3n+3)').addClass('style3a');
    $('ul img:nth-child(3n+4)').addClass('style3b');
}
});

The current script works by calculating the height of the first iteration of 3n+3 and 3n+4, then applies the style to all instances of 3n+3.

However, I need to modify the JavaScript to calculate the height of every iteration of 3n+3 and 3n+4, rather than just the initial one, and then apply the CSS style accordingly.

If the sum of li(3)+li(4) equals a certain value, add a style. If the sum of li(6)+li(7) equals another value, add a different style.

Thank you in advance for any assistance!

Answer №1

When dealing with pairs of elements individually, it is necessary to iterate over the collection. Here is an example:

http://jsfiddle.net/b187z18q/

var $threes = $('ul img:nth-child(3n+3)');  // get collection of all elements matching 3n+3
var $fours = $('ul img:nth-child(3n+4)');   // get collection of all elements matching 3n+4

for(var i = 0; i < $fours.length; i++){
    var $three = $threes.eq(i);  // get individual element
    var $four = $fours.eq(i);    // get individual element

    var result = $three.height() + $four.height();

    if (result == 109) {
        $three.addClass('style1a');
        $four.addClass('style1b');
    } else if (result == 246) {
        $three.addClass('style2a');
        $four.addClass('style2b');
    } else if (result == 177) {
        $three.addClass('style3a');
        $four.addClass('style3b');
    }
}

$(function() {
  var $threes = $('ul img:nth-child(3n+3)');
  var $fours = $('ul img:nth-child(3n+4)');

  for (var i = 0; i < $fours.length; i++) {
    var $three = $threes.eq(i);
    var $four = $fours.eq(i);

    var result = $three.height() + $four.height();
    console.log(result);
    if (result == 109) {
      $three.addClass('style1a');
      $four.addClass('style1b');
    } else if (result == 246) {
      $three.addClass('style2a');
      $four.addClass('style2b');
    } else if (result == 177) {
      $three.addClass('style3a');
      $four.addClass('style3b');
    }
  }




});
.style1a,
.style1b {
  border: 1px solid blue;
}
.style2a,
.style2b {
  border: 1px solid red;
}
.style3a,
.style3b {
  border: 1px solid green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
  <li>
    <img src="http://placehold.it/35x50" />
    <img src="http://placehold.it/35x50" />

    <img src="http://placehold.it/35x59" />
    <img src="http://placehold.it/35x50" />

    <img src="http://placehold.it/35x50" />

    <img src="http://placehold.it/35x50" />
    <img src="http://placehold.it/35x50" />

    <img src="http://placehold.it/35x50" />

    <img src="http://placehold.it/35x100" />
    <img src="http://placehold.it/35x77" />

    <img src="http://placehold.it/35x50" />

    <img src="http://placehold.it/35x146" />
    <img src="http://placehold.it/35x100" />

    <img src="http://placehold.it/35x50" />
  </li>
</ul>

Answer №2

This method may not be the most efficient way to solve this issue. Relying on exact heights can lead to bugs, as even a one pixel change could disrupt your code. It might be better to use less than/greater than comparisons rather than equals or assigning classes to elements. Additionally, it's recommended to declare your jQuery variables only once. Here is a suggested refactored version:

$(function() {
var foo = $('ul img:nth-child(3n+3)');
var bar = $('ul img:nth-child(3n+4)');

switch(foo.height() + bar.height()) {
  case == 1092: 
    // Avoid basing logic on precise heights
    // Consider alternative methods to determine styling
    foo.addClass('style1a');
    bar.addClass('style1b');
    break;
  case == 2460:
    foo.addClass('style2a');
    bar.addClass('style2b');
    break;
  case == 1776:
    foo.addClass('style2a');
    bar.addClass('style3b');
    break;
}

Answer №3

When using the $ function in jQuery to select elements, it always returns a collection even if there is only one matching element. This means that jQuery will look for properties and methods of the first member of the collection by default. To avoid this behavior, you should use jQuery.each() instead.

If you want to calculate the height of specific images within a ul list, your function body should start with the following lines:

var totalHeight;
$('ul img:nth-child(3n+3)').each(function(index, element) {
    totalHeight += element.height;
}
$('ul img:nth-child(3n+4)').each(function(index, element) {
    totalHeight += element.height;
}

The usage of = and += on the same line can be confusing, but the provided code snippet takes care of that for you.

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

Using external scripts that require access to the DOM and window object within a Javascript/Node.js Azure Function: Best practices

I am attempting to integrate external JavaScript into an Azure Function that uses the JavaScript/Node.js flavor. The external JavaScript library I need to use, Kendo, relies on a DOM and a window. To achieve this, I initially experimented with JSDOM, but I ...

Updating website content dynamically using AJAX and URL manipulation without refreshing the page (Node.js)

How can I update the inventory without refreshing the page using both button events and URLs? I want to be able to update to a specific page based on the URL parameter (like /inventory/2) when it is passed to the route. Currently, my AJAX request works but ...

"Is there a virtual keyboard available that supports multiple inputs and automatically switches to the next input when the maximum length

Looking to build a virtual keyboard with multiple inputs that automatically switch to the next input field after reaching the maximum length. Currently having an issue where I can only fill the first input and not the second one. Any assistance in resolvin ...

The functionality of Javascript is being compromised when utilizing ng-repeat

Just recently diving into the world of AngularJs while developing a website. I've successfully retrieved data from Rest services on a page, and used ng-repeat to display it. The issue arises when I have a regular javascript element on the page that i ...

Utilizing the map function to display elements from a sub array

I'm struggling to print out the comments using the map function in this code: class Postcomment2 extends React.Component { uploadcomment = () => { return this.props.post.comments.map((comment) => { return <div>{comment["comment"]}< ...

Display: Show view once forEach loop finishes execution

I'm facing an issue with my update query execution within a loop. Is there a way to trigger the rendering of a view once the forEach loop completes all its iterations? Here's the snippet of code: conn.query(`SELECT Id, ${sfColumn} from Lead`, ...

Dynamic Menu Navigation (No Bootstrap Required)

My Navbar is working perfectly in the original mode but when the screen width is less than 950px, it displays the buttons stacked vertically. However, the dropdown button opens the dropdown content on the wrong side. I want the dropdown content to appear u ...

An example of using quotes within quotes is an HTML tag embedded within JavaScript code

Currently, I'm working on a JavaScript code where clicking assigns the function getImage the source of an image to be displayed later on the page. The issue I'm facing revolves around dealing with quotation marks. <img src="bill.jpg" class=" ...

Attempting to transmit a dynamic array of promises from Angular to an Express server

Currently, I am attempting to send an array of promises to an express app in order to retrieve data from a mongo database. The behavior seems to be working fine on the front end. In this scenario, both objects are sent to the server and resolved using $q ...

Strings that automatically adjust to fit the content from a JSON object

I have a JSON object with a long string that I want to display. The string looks like this: "String":"<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever si ...

Utilizing JavaScript AJAX to upload a dynamically generated PDF file to a specific directory on the server

Looking for a solution to save a complex table generated via JavaScript as a PDF on the server. Existing pdf generation libraries have limitations with style and fonts, making it difficult for 'complex' tables. The table can currently be download ...

Prevent a sliding panel from responding if there is no input text by incorporating jQuery

I have a straightforward example of user input and a button that reveals "Hello World" when clicked: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1 ...

Error message encountered in Rails Webpacker: "Uncaught TypeError: $(...).tooltip is not recognized as a function

I am working on a Rails 6 application where I compile assets using Webpack 4.39.1 with the help of the Webpacker gem. In my webpack configuration file (config/webpack/environment.js), I have included JQuery 3.4.1 and Popper.js as part of the ProvidePlugin ...

Once the PostgreSQL container is stopped with docker-compose down, the previously used port becomes unavailable for use again

Currently, I am involved in a project which utilizes express as the server and postgres as the database to delve into dockerization. The server relies on the database being operational. Initially, when running docker-compose up everything functions correct ...

What is the best way to expand the header, content, and footer colors to cover the entire width of a page while keeping everything centered within a fixed width

I managed to get the header and main content area to stretch across the full page, while keeping the content centered. But now I am facing an issue with the footer not stretching like the header. How can I make the footer stretch as well? HTML: <body ...

"Simultaneously creating a Firebase user account and populating the database with user

My goal is to store new user information in my database using their unique user UID when they sign up through Firebase. Currently, my code is functioning properly, however, I am facing an issue where the name (which should be the created user UID) appears ...

Using AJAX along with the append method to dynamically add identical HTML content multiple times to a single element

Although I have successfully implemented most of the desired functionality with this JavaScript code, there is a persistent bug that is causing unnecessary duplicates to be created when appending HTML. Detecting Multiples The problem lies in the fact tha ...

Failure of window marker to trigger click event in jquery-bing-maps

I'm encountering an issue where clicking on links within Window markers on Bing Maps redirects me to a new page instead of triggering a JavaScript event as intended. $('.single_address').on('click', function (evt) { alert(&apo ...

Unable to access parameters from Pug template when using onclick event

I am facing an issue with my pug template test.pug. It contains a button that, when clicked, should call a function using parameters passed to the template from the rendering endpoint. Below is the structure of my template: doctype html html head tit ...

The data display in MUI-Datatable is experiencing an issue where it is unable to read properties of undefined, specifically when trying to split the data

Whenever I include data within the MuiDatatable, it triggers this error: Cannot read properties of undefined (reading 'split') Is there a solution to this problem so that the data can be properly displayed? To demonstrate the issue, I have se ...