set and get of css attribute with native JS code

Keywords: Attribute JQuery IE Windows

Now let's implement a simple version of the plug-in, which can achieve the acquisition and setup of css attributes without the help of jQuery.

First step

First, create a css-tool.js file. At first, it looks like this:

(function(window,undefined){
 "use strict";

  var cssTool = function(){
    return new cssTool.prototype.init();
  }

  cssTool.prototype = {
    init: function(){
      console.log('init success');
      return this;
    },
  }

  cssTool.prototype.init.prototype = cssTool.prototype;
  // Exposed interface
  window.cssTool = cssTool;

})(window);

Global scope can be seen as an apartment building. We create an immediate anonymous function, which is equivalent to an apartment in an apartment building. What we do in the room is hidden, that is, to isolate the scope and avoid conflicts with external variables. Take windows as a parameter to the room, and then you don't have to go outside again to find windows to use. The leading semicolon is to ensure that grammatical errors occur after file merge and compression. undefined is not supported in older browsers, so add a parameter for compatibility.

We created a private method called cssTool, which is equivalent to finding a small room in the house to put methods like get and set. Next, we add an init method to the prototype for initialization. Then we point init's prototype to the prototype of cssTool in the way of jQuery, so that when we create an instance with init as a constructor, we can make the plug-in have two ways to call:

  • var ct = new cssTool() Construct an instance of cssTool
  • Call cssTool() directly and return the cssTool instance as well.

get method

General mode

Modern Browsers and IE9+
window.getComputedStyle(elem,null).getPropertyValue(attr)

IE678
elem.currentStyle.getAttribute(camelCase(attr))

Compatible processing

Hump Naming Conversion-camelCase

For current Style, he is very specific in IE6 browser. He only likes variables named by hump nomenclature, while IE78 has a little bit of ups and downs. The hump nomenclature and the middle zone'-'are all in the list. In order to be compatible and easy to operate, we have unified conversion to hump nomenclature.

/**
 * Conversion of hump nomenclature, IE678
 * font-size --> fontSize
 * @param {String} attr
 * @param {String} match  Matched strings, such as -c
 * @param {String} originText (\w)Is a capture, here is the captured character, such as c
 * @return Returns the css attribute name of the hump naming method
 */
functioncamelCase(attr){
  return attr.replace(/\-(\w)/g, function(match,originText){
    return originText.toUpperCase();
  });
}

Transparency Acquisition - getFilter

The transparency of IE678 is set by filter:alpha(opacity=0). We use regular expressions to match the value of transparency at this time. Since the value obtained at this time is between 0 and 100, we need to convert it to our usual form of 0-1.

/**
 * IE678 Get the value of transparency below
 * @param  elem dom to get the value
 * @return {Number} Transparency value, default 1
 * IE678 Set transparency filter: alpha(opacity=0) with a value of 0-100
 */
functiongetFilter(elem){
  var _filter = elem.currentStyle.getAttribute('filter').match(/alpha\(opacity=(.*)\)/i);
  var value = parseFloat(_filter[1]);
  if(!isNaN(value)){
    // Converted to 0-1
    return value ? value/100 : 0;
  }
  return 1;
}

Acquisition of float value

As mentioned in the previous blog, float is a reserved word in ECMAScript. So there are alternatives in browsers, such as cssFloat in modern browsers and styleFloat in IE678. After testing, the value of float can also be obtained by directly using getProperty Value ("float") in modern browsers. IE678 is not, so for float, a simple hack is needed.

Getting width | height style

For an element without setting its height and width, the value obtained directly under IE678 is auto. Modern browsers will directly return its px value, our goal is to return px value under IE.

// Get the width and height return values auto that are not set by the external stylesheet directly
// In order to obtain accurate px values, the getBoundingClientRect method is used.
// GetBounding ClientRect obtains four points of the element relative to the upper left corner of the document view
// The top, left, bottom and right values can be calculated simply.
var condition = attr === 'width'
             || attr === 'height'
             && elem.currentStyle[attr] === 'auto';
if(condition){
  var clientRect = elem.getBoundingClientRect();
  return (attr === 'width' ?
          clientRect.right - clientRect.left :
          clientRect.bottom - clientRect.top
         ) + 'px';
}

set method

The set method is much simpler than the get method because we have cssText, an artifact that spans IE6 + and modern browsers.

The style of the element can be read and written through elem.style.cssText, which actually operates on the value of the style attribute on the html tag. Therefore, it can not be assigned directly, or the value of the entire style attribute will be overwritten. We modify the attributes in a cumulative manner.

In addition, there is a small pit in IE browser. If cssText is not empty, the last semicolon of the return value will be deleted, so we need to add a semicolon before the accumulated attributes.

/**
 * Setting element css style values
 * @param elem dom elements for setting values
 * @param {String} attr Set style names, such as font-size
 * @param {String} value Set style values, such as 16px
 */
set: function(elem, attr, value){
  // IE78 Setting Transparency Requires Special Processing
  if(attr === 'opacity'){
    // hack for IE7
    // The filter filter requires hasLFooout=true to execute
    // Execution in IE browser and hasLFooout=false
    if(!!elem.currentStyle && !elem.currentStyle.hasLFooout){
      elem.style.zoom = 1;
      attr = 'filter';
      value = 'alpha(opacity=' + value * 100 + ')';
    }
  }
  // General mode
  elem.style.cssText += ';' + (attr + ':' + value) + ';';
}

supplement

Simply explain the role of the new operator

var Foo = function(){
  return new Foo.prototype.init();
}

Foo.prototype = {
  init: function(){
    this.age = 18;
    return this;
  },
  age: 20
}

console.log(Foo().age); // 18
console.log(Foo.prototype.age); // 20


When using the new operator, init is called as a constructor. An implicit object is created inside the init and pointed to by this. this.age=18 indicates that an age attribute is added to the implicit object. Finally, return this is not necessary. The constructor returns this by default. Foo.prototype.age is not affected at this time.

When the new operator is not used, it is equivalent to a function call on an ordinary object. this points to the object to which init belongs, namely Foo.prototype. this.age=18 is equivalent to the assignment of Foo.prototype.age, which is essentially different from using the new operator.

Summary

At this point, the course will be over. A common css() method in jQuery covers a lot of knowledge points. Cross-browser compatibility is also the focus of our discussion. This time, we just implemented a very simple css operation plug-in. If there is something unclear or wrong, you are welcome to leave a message or mention issue to help me improve this small plug-in.

Posted by Simsonite on Sat, 23 Mar 2019 19:42:27 -0700