Replace the element's style using a JavaScript object

While there are numerous versions of this query, the existing answers fail to provide in-depth analysis.

Query: How does this result in a height of 200 pixels?

Consider the following code snippet:

var el = document.querySelector('#r');

console.log('First:: ' + el.offsetHeight);

el.style = {
  height: el.offsetHeight + 500 + 'px'
}

console.log('Second:: ' + el.offsetHeight);
<div id="r" style="height:200px;width:800px;overflow:auto;border:1px    solid;margin:20px;box-sizing:border-box"></div>

I suspect el.style is read-only, leading me to anticipate that setting an object will fail silently, resulting in an output of:

First:: 200, Second:: 200

However, the actual outputs are:

First:: 200, Second:: 0

Why is this the case?

Query: Why does using Object.assign to set el.style work?

Object.assign(el.style,{
   height : el.offsetHeight + 500 
})

Could someone offer a more detailed explanation?

Answer №1

Regarding your initial inquiry:

MDN mentions that while the style object is typically read-only, Firefox, Chrome, and Opera allow modifications to it (https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style). However, the offsetHeight property itself is readonly (https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetHeight), leading to a scenario where setting the style attribute may inadvertently reset this value to zero. Since offsetHeight is a calculated attribute rather than an explicitly set one, the browser's interpretation of modifying the style leads to this unexpected outcome.

In response to your second question:

The functionality of Object.assign is explained directly in its documentation. It does not replace the entire object; instead, it replaces the enumerable own properties of the object being targeted. This distinction is outlined clearly in the official documentation for Object.assign: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

"Properties in the target object will be overwritten by properties in the sources if they have the same key. Later sources' properties will similarly overwrite earlier ones.

The Object.assign() method only copies enumerable and own properties from a source object to a target object."

Therefore, in your initial coding attempt:

el.style = {
  height: el.offsetHeight + 500 + 'px'
}

You were trying to replace the entire object, resulting in failure. On the other hand, Object.assign simply copies properties, allowing for a successful operation.

Answer №2

According to the information from the Chromium source at this link,

When a property is set, it is passed on to el.style.cssText as specified in the document found at this location.

The spec indicates [PutForwards=cssText]

Therefore, if we assign a string.,

el.style = 'some valid css string'; 
// it takes the string and assigns it to cssText 
el.style.cssText = 'some valid css string';

// When assigning an object
el.style = {...}; 
// it takes the object and converts it to a string using toString()
el.style.cssText = '[object Object]';
// Since it is not valid, it clears all styles

Answer №3

I decided to do some research because I had a list of style properties that needed changing and I wanted to find a cleaner way to do it using an object. For anyone else who may be curious about this topic, here's the solution I came up with:

var newStyles = { 
  zIndex: 10000,
  position: "absolute",
  top: newY,
  left: newX,
  opacity: 1,
  height: newHeight + "px",
  width: newWidth + "px"
}

for(let property of Object.keys(newStyles)){
  element.style[property.toString()] = newStyles[property.toString()];
}

Hope this helps!

Answer №4

The problem lies in the following code snippet:

el.style = {
  height: el.offsetHeight + 500 + 'px'
};

This code not only fails to work as intended (the element's CSS height does not get set to

700px</code), but it also completely eliminates any inline styles that were previously applied to the element (in the <code>style
attribute):

https://i.sstatic.net/zr8C7.png

Additionally, since your <div> is empty, its height will default to zero. As a result, the value of el.offsetHeight ends up being 0.

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

Guide on properly formatting arithmetic expressions in a TextView for TalkBack recognition

In search of a way to make a fitness app more accessible, I need assistance in displaying a message on a smartwatch emulator that can be easily understood by users utilizing the TalkBack feature. The challenge lies in ensuring that the word 'plus&apos ...

I require the ability to execute a JavaScript or jQuery script within a PHP environment

To update the page and dynamically populate the second dropdown based on the selection in the first dropdown, follow these steps: Use PHP to select the dropdown value, triggering the JavaScript function `reloadproject()` to refresh the page with the sele ...

Jquery: Pressing Enter will cause the input field to lose

Take a look at this fiddle I created: http://jsfiddle.net/7wp9rs2s/. This is the progress I have made on my project so far. In the fiddle above, you can double click on one of the 4 items and a textbox will appear for editing. Instead of clicking out of t ...

I require the slideshow div to smoothly move elements down as it transitions between slides

I'm facing an issue with a jquery slideshow that contains quotes of varying lengths. The problem is, the longer quotes overlap with the content below them. I'm trying to figure out how to make the longer quotes push the rest of the page down, avo ...

What makes AJAX take so much time to load?

Hey everyone, I’ve been working on compiling and sending some forms to a PHP file but I've been noticing that the process is quite slow. Even when I use var_dump in PHP to only display the POST values, it still takes a considerable amount of time co ...

What are the methods for setting the width and height of an Angular mat dialog box?

I'm currently working with a Mat dialog box in Angular and I'm trying to include styles for width and height within that object. However, I'm encountering errors and can't seem to resolve them. Is there another method for setting width ...

Just sent out an email including an attachment with HTML content or a webpage link to access on Google

My email recipients primarily use Gmail as their email service provider. To address this, I saved the contents of this page as an HTML file named index.html and stored it on my drive for easy sending. However, the issue lies in the fact that the page does ...

Working with iFrames through Splinter/Selenium in Python

Just a heads up: I can work with either Selenium or the Splinter API wrapper for Selenium! I've encountered some hurdles while trying to navigate iframes on Twitter.com using the Python Splinter API. For instance, with Browser('firefox', ...

Using JQuery to Customize Navigation Menu Targeting

On my website, I am trying to make an href button and a menu fade in as the page loads. However, I am struggling to find the correct code due to its placement within multiple tags, especially since I am new to JS and JQuery. I have provided a fiddle with a ...

Step-by-step guide on compressing a JavaScript array

What is the best way to compress an array? I am currently attempting to compress an array using the lz-string library and converting it to/from strings. However, I am encountering issues with decompression, as I am getting null, 0, or [] as the output. B ...

Scroll sideways with AJAX content replacement

I've successfully discovered various methods for loading and replacing content with ajax, as well as ways to hide/show with effects. However, I'm now seeking a technique that allows the new content to slide into a div while the old content slide ...

Struggling with transitioning from the Twitter search API to the status API

While using the search API to fetch tweets from a specific user, everything was working flawlessly except for the fact that it couldn't retrieve tweets when the username contained numbers. Based on a suggestion, I switched to using the status API que ...

Does jqgrid navgrid have an event called "on Refresh"?

Is there a way to trigger an event before the grid automatically refreshes? I am looking for something similar to "onSearch" but for the reset button. Below is the code snippet for the navgrid: $("#jqGrid").jqGrid('navGrid','#jqGridPag ...

Is it possible to utilize AJAXToolKit and Jquery on a single webpage?

Is it possible to utilize both AJAXToolKit and jQuery on a single page? For example, let's say we have ScriptManager in the same page along with including ...

Activate the feature of smooth shading using Three.js

When rendering an object with textures using MTL and OBJ files in Three.js, I encountered an issue where my model was displayed with flat shading. How can I enable smooth shading? var scene = new THREE.Scene(); var mtlLoader = new THREE.MTLLoader(); mtl ...

Retrieving the value of a basic object

When I receive an object from an API, the data looks like this- { "query1": 0.443} My goal is to extract the number 0.443 by using: request(options, function (error, response, body) { if (error) throw new Error(error); ...

Angular 4 scripts fail to execute after switching views

I am facing an issue with my Angular 4 app. All scripts work fine when the page is loaded for the first time. However, if I navigate to a different component within the app and then return to the main page, the scripts stop working. The console log shows a ...

Why isn't the Vue component refreshing its view after the state changes in Vuex?

Recently, I delved into the world of vue and learned about its redux counterpart vuex. However, I'm facing an issue where changes in the vuex state are not triggering reactive updates to the view in a vue component. export const store = new Vuex.Store ...

What is preventing this brief code from functioning properly? I am trying to extract a value from an input field and add it to a div element

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <script src="//ajax.googleapis.com/ajax/libs/jque ...

Persist AJAX request across page reloads

Seeking a solution to a perplexing dilemma that has left me incapable of finding a swift resolution. Perhaps there is someone here who can provide guidance. I am curious: if I initiate an AJAX request on my HTML page using jQuery and then trigger a refres ...