Utilizing JSON Response Data to dynamically set a background image for each item in a JavaScript loop

Currently, I am leveraging an ajax request to showcase a loop of Drupal posts.

    $( document ).ready(function() {
$.ajax({
    type:"GET",
    url:"https://www.nba.com/api/1.1/json/?type=photo_gallery&tags=community&size=4",
    success: function(data) {
    let galleriesWrapper = document.getElementById("wrapper--community-galleries");
    function create(tagName, props) {
      return Object.assign(document.createElement(tagName), (props || {}));
    }
    function ac(p, c) {
      if (c) p.appendChild(c);
      return p;
   }
for (var i=0; i< data.content.length; i++) {
var link = create("a", {
  className: "wrapper--single-gallery",
  href: data.content[i].url,
  style: "background-image:url(" + data.content[i].images.large + ")"
});
var videoTitle = create("div", {
  className: "single-gallery--title",
  src: data.content[i].title
});
videoTitle.textContent = data.content[i].title;
ac(galleriesWrapper, ac(link, videoTitle));
      } 
    },
    dataType: "jsonp",
  });
});

I am fetching the post's image from the .json file and incorporating it as the CSS background-image for that specific item within the loop.

The functionality performs flawlessly in Chrome and Firefox, however, encounters difficulties in IE.

A helper function called "create" is utilized, which employs Object.assign to efficiently generate and append DOM elements.

Initially, my challenge with IE arose due to the absence of an object.asign polyfill, resulting in no items being displayed.

Rectifying this Issue:

if (typeof Object.assign != 'function') {
Object.assign = function(target) {
'use strict';
if (target == null) {
  throw new TypeError('Cannot convert undefined or null to object');
}

target = Object(target);
for (var index = 1; index < arguments.length; index++) {
  var source = arguments[index];
  if (source != null) {
    for (var key in source) {
      if (Object.prototype.hasOwnProperty.call(source, key)) {
        target[key] = source[key];
      }
    }
  }
}
  return target;
  };
}

After integrating this at the beginning of my JS script, the loop items are successfully displayed in IE, however, the code used to inject the background-image style inline fails (only displaying an item with the correct post title from the ajax request but with a blank background).

Update: The issue seems to be related to attempting to append the style property. When implementing the following:

var link = create("a", {
  className: "wrapper--single-gallery",
  href: data.content[i].url,
  style: "background-image:url(" + data.content[i].images.large + ")"
});

The link is created with the class name and the href, yet the style property is not appended.

Suspecting it might be linked to how I inserted the URL from the JSON request data, I tried using just the style "color:red". This led to the same outcome of the style tag not being attached to the link.

Check out the JS FIDDLE EXAMPLE here: https://jsfiddle.net/nolaandy/w3gfawcg/

Answer №1

The issue lies not with Object.assign itself, but rather with how the styles are being set.

You have a couple of options:

  1. Assign each style directly to the element's style property

    link.style.backgroundImage = "url(" + data.content[i].images.large + ")"
    
  2. Swap out Object.assign for _.merge and set the styles as an object (https://lodash.com/)

    function create(tagName, props) {
        // Swap Object.assign for _.merge (https://lodash.com/)
        return _.merge(document.createElement(tagName), (props || {}));
    }
    
    // ....
    
    var link = create("a", {
       className: "wrapper--single-gallery",
       href: data.content[i].url,
       // Update styles to be an object
       style: {
           backgroundImage: "url(" + data.content[i].images.large + ")"
      }
    });
    

I recommend going with the second option as it provides a cleaner solution: https://jsfiddle.net/w3gfawcg/7/

Answer №2

Blake's guidance led me to the solution. Much appreciated, Blake.

Here is the simple resolution:

for (let i = 0; i < data.content.length; i++) {
    let link = createLink("a", {
        className: "wrapper--single-gallery",
        href: data.content[i].url,
    });
    $(link).css("background-image", "url(" + data.content[i].images.large + ")");
}

Inspired by Blake from Mozilla: "Avoid setting styles by directly assigning a string to the style property (e.g., elt.style = "color: blue;"), as it is considered read-only. The style attribute returns a CSSStyleDeclaration object, which is also read-only. Instead, properties of the style can be manipulated."

Interestingly, Firefox executed the original code properly even though it was not following best practices.

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

What Makes Bootstrap Spinner Ineffective in High-Performance Computing Scenarios

I understand that Javascript operates on a single thread, but I am puzzled as to why the spinner is not showing or hiding before/after a compute-intensive task in the following code. Here is the outline of the code: showSpinner(); computeIntensiveTask(); ...

Step-by-step guide to generating a Paypal Button using Vue 3 script setup

After going through the PayPal Developer Docs, I'm still struggling to understand how to integrate the PayPal Button into Vue.js. The code examples provided are unclear, and I can't determine if it's related to Vue 2, Vue 3, or even Angular. ...

The functionality to import JSON data into Google Spreadsheets is compromised when the API includes the characters " | "

I am attempting to bring JSON data into Google Sheets using a Wikidata API. However, one of the symbols utilized in this API is the vertical bar: |. It serves as an "and". For instance, if I wish to import data in BOTH English and Greek, then I need to us ...

Discovering the method for detecting the closure of a Bootstrap modal

I have a question regarding detecting the closure of a Bootstrap modal using the hidden.bs.modal event. The modal can be closed in various ways: Explicitly closing it with $('#modal').modal('hide') or $('#modal').modal(&apos ...

Is there a method available to retrieve the video duration prior to uploading it?

Is there a method to restrict users from uploading videos longer than 30 seconds? ...

Send variable to jQuery from a div element

I'm struggling with adjusting the height and width of a dialog box using a jquery function. I want to pass a parameter from within the DIV, but I haven't been successful in finding a solution. Any suggestions would be greatly appreciated. $.fx.s ...

JS use regex to set input field value

Is there a way to automatically format the input value in an HTML time picker field using regex and the replace function? For example, when a user enters numbers, the input value should be formatted accordingly based on a specific pattern. I attempted to ...

I'm having trouble understanding why the MUI CORE basic rating code is returning undefined for setValue. Can anyone help

My first experience with MUI CORE was not smooth as I encountered an error when trying to use active rating and the set value is not defined i mport './App.css'; import 'bootstrap/dist/css/bootstrap.min.css'; import Movie from './ ...

How to locate the cell with a specific class using JavaScript/jQuery

I need help with the following code snippet: var output = '<tr>'+ '<td class="class1">One</td>'+ '<td class="selected">Two</td>'+ '<td>< ...

Error: string literal left incomplete with spaces only

I am attempting to run parameters from a JavaScript function, but I am encountering an issue with quotes when there is a white space present. This error specifically pertains to Mozilla: SyntaxError: unterminated string literal Below is the relevant p ...

Load several OBJ files simultaneously with various textures

After experimenting with various examples on ThreeJS, I have successfully managed to load multiple OBJ files into my scene along with multiple textures. However, I encountered an issue where the textures were being assigned to the objects based on the &apo ...

Discover the secret to restricting JSON API functionality in your WordPress plugin

I am interested in using WordPress to build a website, specifically looking to export site posts using the JSON API. However, I encountered an issue when attempting to limit the displayed posts by category. Clicking on the "get_category_posts" link within ...

Unable to open drop-down menu in Bootstrap-select on ASP.NET web application by clicking

Currently, as I work on developing an ASP.NET web application, I find myself facing significant challenges in getting the bootstrap-select feature to function correctly. Despite browsing through various threads on SO for solutions, the problem remains unr ...

Determining the height of child elements within a React component

One challenge I'm facing inside a React component is the need to calculate the total height of my child containers, specifically the three h3 elements, in order to accurately determine the height of my parent div during a transition animation. While I ...

Utilizing Firebase 9.0.1 Functions in Vue.js 3

As a newcomer to Vue, I decided to tackle my second tutorial which involved integrating Firebase backend with Vue. However, the tutorial was based on Vue 2 and an older version of Firebase. Determined to stay current, I set out to replicate the project usi ...

Using JavaScript onChange event with ModelChoiceField arguments

In my Django project, I have a Students model with various fields. I created a ModelChoiceField form allowing users to select a record from the Students table via a dropdown. forms.py: class StudentChoiceField(forms.Form): students = forms.ModelChoic ...

Updating content in AngularJS based on the sidebar can be achieved by following these steps:

Yesterday, I posed a question about how to implement multiple views with Angular in order to have a header and sidebar. After receiving some helpful insights, I was able to make progress on creating a header and sidebar for my AngularJS App. You can view ...

Determine in Jquery if all the elements in array 2 are being utilized by array 1

Can anyone help me figure out why my array1 has a different length than array2? I've been searching for hours trying to find the mistake in my code. If it's not related to that, could someone kindly point out where I went wrong? function contr ...

Execute an executable file with elevated permissions using Node.js

I'm looking to run an .exe file as an administrator using Node. I attempted the following code, but it's not working: exec('runas /user:Administrator "app.exe"', function(err, data) { console.log(err) ...

Tips for changing the content of a text input field using JavaScript/jQuery

I am looking to dynamically change the values of specific form elements, particularly input text fields. However, when I load my HTML page, the input field appears blank instead of containing the value 1. Below is an example of my current approach. <!D ...