Question: is it possible to have object1 providing an attribute of object2 in a way, that no getters and setters are needed? So I could do a = object1.attribute and object1.attribute = a.
Example: I am implementing support for dynamic aligning of the absolutely positioned HTML objects on the page. All kinds of aligns should be supported - left, right, top, bottom, horizontal center, vertical center or even evenly spaced. To reduce the amount of duplicated code, I came up with the solution to implement class Direction, which can be horizontal and vertical and works in the Facade-ish mode with regards to the Element. It this is passed as an attribute to the aligning function. Similarly, I am handling the left/right/middle and distribute evenly distinction, but to keep it simple, let's ignore it here.
Here is the class.
Direction = function(selector) {
this.selector = selector;
}
Direction.prototype.get = function(element) {
return parseInt(element.style[this.selector]);
}
Direction.prototype.set = function(element, value) {
element.style[this.selector] = value + 'px';
}
Here are the "constants" available to the client.
Direction.VERTICAL = new Direction('left');
Direction.HORIZONTAL = new Direction('top');
Here is the public method performing the "minimal" align (left or top).
alignMin = function(elements, direction) {
var min = Number.MAX_VALUE;
for (var i = 0; i < elements.length; i++) {
min = Math.min(min, direction.get(elements[i]));
}
for (var i = 0; i < elements.length; i++) {
direction.set(elements[i], min);
}
}
And the client here demonstrates the intended use.
alignDivsToLeft = function() {
alignMin(document.getElementsByTagName("div"), Direction.VERTICAL);
}
Working example on a JSFiddle: http://jsfiddle.net/7Tpam/
Question again: All this works, I was just wondering, if instead of Direction.get() and Direction.set() methods I could do something (a reference to a value?) to directly access the "proxified" attribute, so the alignMin function could use just
...
min = Math.min(min, direction.value); // possibly with parseInt()
...
and
...
direction.value = min; // possibly with + 'px'
...
If there is a simple solution for this, it would be a shorter, clearer and more elegant way, especially in cases with more attributes (position, dimension, ...). Plus there is the factor of the curiosity (still learning magic of JavaScript, so..).
Javascript in some browsers supports getters and setters as described in this article
Using your objects:
Direction = function(selector) {
this._selector = selector;
}
Direction.prototype = {
get selector(){
return this._selector;
},
set selector(selector){
this._selector = selector
}
}
Usage:
var direction = new Direction("left");
console.log(direction.selector); // getter
direction.selector = 'right' //setter
JSFiddle: http://jsfiddle.net/7Tpam/1/
This would seem in the first instance to be what you're describing, but be aware it does not have global support
Firefox
Safari 3+ (Brand New)
Opera 9.5 (Coming Soon)
Source: above-linked article
Related
I have an object that contains a list of browser widths
breakpoints {
smallMobile: 0,
mobile: 480,
tablet: 672,
desktop: 868,
largeDesktop: 1050
}
I want to add a class to the body of the document based on whether the browser width falls between two values in the breakpoints object.
What I have so far
var key;
for (key in breakpoints) {
if (breakpoints.hasOwnProperty(key))
if (winWidth >= breakpoints[key]) {
$('body').removeClass().addClass(key);
} else {
$('body').removeClass(key);
}
}
}
Now this works, however it also removes ALL classes from the body. Instead I would like to add only one class, and not have to remove anything unless the breakpoint no longer matches.
I'm sure there has to be a way. Any help would be appreciated :)
EDIT
Current output at various widths
>= 1050: <body class="smallMobile mobile tablet desktop largeDesktop">
>= 868: <body class="smallMobile mobile tablet desktop">
>= 672: <body class="smallMobile mobile tablet">
Ideal output
>= 1050: <body class="largeDesktop">
>= 868: <body class="desktop">
>= 672: <body class="tablet">
(For the record I use Media Queries, but I need access to classnames for an edge case)
I've slightly modified your code and saved the class thats the highest applicable one. Then I remove every class and apply the applicable one.
// create a variable to store the only class you want to apply
var apply = "";
for (var key in breakpoints) {
// keep overwriting the apply var if the new key is applicable
if (winWidth >= breakpoints[key]) {
apply = key;
}
// remove any existing classes with that keyname
$('body').removeClass(key);
}
// add the key to the body as a class
$('body').addClass(apply);
Also, you can remove breakpoints.hasOwnProperty(key) as the for-loop only loops through keys that actually exist anyway, so you are doing an unnecessary check.
Update
At #juvian's note, I'll add a way to make sure that the order in which you make your object makes no difference:
var apply = "";
var check = 0;
for (var key in breakpoints) {
// Also check if the value is higher than the last set value
if (winWidth >= breakpoints[key] && breakpoints[key] >= check) {
apply = key;
check = breakpoints[key];
}
$('body').removeClass(key);
}
$('body').addClass(apply);
It's because you're using removeClass() without any parameter in it.
If a class name is included as a parameter, then only that class will
be removed from the set of matched elements. If no class names are
specified in the parameter, all classes will be removed.
Source: http://api.jquery.com/removeClass/
So, you should find the right class to remove and then call this function with a param.
Consider to store your breakpoints in sorted array instead of map:
var dimensions = [];
for (var key in breakpoints) {
dimensions.push({ name: key, width: breakpoints[key] })
}
dimensions.sort(function(a, b) { return b.width - a.width });
Now dimensions is
[
{"name":"largeDesktop","width":1050},
{"name":"desktop","width":868},
{"name":"tablet","width":672},
{"name":"mobile","width":480},
{"name":"smallMobile","width":0}
]
Of course you can hardcode it in this structure and not grep/sort each time.
Finally, find highest width with
for (var i = 0; i < dimensions.length; i++) {
if (winWidth >= dimensions[i].width) {
$("body").addClass(dimensions[i].name);
break;
}
}
However, if you want to create responsive layout, media queries is the way to go. Media queries also will take windows resize/orientation change events into account.
Here is a way you can get the one that matches with the highest value:
var wid = 868;
var max = 0;
var size = null;
Object.keys(breakpoints).map(function(a){
size = wid >= breakpoints[a] ? a : size;
max = wid >= breakpoints[a] ? Math.max(max,breakpoints[a]) : max;
})
console.log(max, size) // 868, 'desktop'
if you use .removeClass() without parameter then all class on selected element will remove as like prabu said, but if you want, i give some example so you will not confused how to remove class if window width less than breakpoints
var key;
for (key in breakpoints) {
if (breakpoints.hasOwnProperty(key)) {
$("body").addClass(key);
if (winWidth<breakpoints[key]) {
$("body").removeClass(key);
}
}
}
I got this style applied to a div
div#content {
border: 1px solid skyblue;
}
and i want to be able to alert the width of the border, I have tried with this:
window.alert( document.getElementById( "content" ).style.borderWidth );
I heard that depends of the browser maybe you can help me
I'm using Firefox 18
Please try the below javascript:
alert($("#content").css("border-left-width")); //using jquery.
or
alert(getComputedStyle(document.getElementById('content'),null).getPropertyValue('border-left-width'));//without jquery.
getComputedStyle(element, pseudo)
element:The element to get a styling for
pseudo:A pseudo-selector like ‘hover’ or null if not needed.
Reference link: http://javascript.info/tutorial/styles-and-classes-getcomputedstyle
I might be too late but as you never marked it as answered, I thought I could give it a try.
If your problem was compatibility between browser I would create a custom method that I could use in almost every browser there is (that means going back to the very basics).
I actually dug a lot to do this. I use some of the code from jQuery because I did not want to use jQuery but still have the backwards compatibility that jQuery does.
This function solves your question and at the bottom there are some examples on how to use it.
This functions uses the "module pattern" through the immediate function that will be run as soon as the script loads creating a method that will NOT polute the global scope but extend its functionality through a function to do what you wanted.
// I give it a name but it can also be anonymous
(function preloadedFunctions(){
// Preseted methods.
if(window.getComputedStyle){
window.getComputedStylePropertyValue = function(element, prop){
var computedStyle = window.getComputedStyle(element, null);
if(!computedStyle) return null;
if(computedStyle.getPropertyValue) {
return computedStyle.getPropertyValue(prop);
} else if (computedStyle.getAttribute) {
return computedStyle.getAttribute(prop);
} else if(computedStyle[prop]) {
return computedStyle[prop];
};
};
}
// jQuery JavaScript Library v1.9.0
// http://www.minhacienda.gov.co/portal/pls/portal/PORTAL.wwsbr_imt_services.GenericView?p_docname=6240612.JS&p_type=DOC&p_viewservice=VAHWSTH&p_searchstring=
// For IE8 or less
else if ( document.documentElement.currentStyle ) {
var rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),
rposition = /^(top|right|bottom|left)$/,
core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source;
window.getComputedStylePropertyValue = function(element, prop){
var left, rsLeft,
ret = element.currentStyle && element.currentStyle[ prop ],
style = element.style;
if ( ret == null && style && style[ prop ] ) {
ret = style[ prop ];
}
if ( rnumnonpx.test( ret ) && !rposition.test( prop ) ) {
left = style.left;
rsLeft = element.runtimeStyle && element.runtimeStyle.left;
if ( rsLeft ) {
element.runtimeStyle.left = element.currentStyle.left;
}
style.left = prop === "fontSize" ? "1em" : ret;
ret = style.pixelLeft + "px";
style.left = left;
if ( rsLeft ) {
element.runtimeStyle.left = rsLeft;
}
}
return ret === "" ? "auto" : ret;
};
};
})();
i.e.
1.-
var borderWidth = getComputedStylePropertyValue(document.getElementsByTagName("div")[0], "border-width");
console.log(borderWidth);
2.-
var div = document.getElementById("someID");
console.log(getComputedStylePropertyValue(div, "border-width"));
If somebody is still looking, this seems to be easiest way to do it with plain JS.
let border =
+getComputedStyle((document.getElementById("idOfYourElement")))
.borderTopWidth.slice(0, -2)
Explanation below:
document.getElementById("idOfYourElement") - Return our HTML element.
getComputedStyle - Return css attributes of chosen element as object.
.borderTopWidth - Corresponding attribute from getComputedStyle object (return array like this: ("10px")).
.slice(0, -2) - Cut the last 2 characters from our array so we get rid of px at the end.
And + at the start - Parse rest of our string, that contains number we want, to the integer.
You can try this:
var border = document.getElementById("yourDiv").clientWidth - document.getElementById("yourDiv").offsetWidth;
alert(border);
Note, that the value will be rounded to an integer. If fractional value is required, you need to use getComputedStyle instead (see other answers).
Very old question, but anyway...
This solution is plain JavaScript, and should work in older browsers too.
It measures the size of the element, with, and without borders.
The following example should work correctly if the borders around the element are all the same size.
If not, the procedure doesn't change much, you just have to set the borders equal to zero, one by one.
var ele=document.getElementById("content");
// measures the element width, WITH borders
var w=ele.offsetWidth;
var cssBackup=ele.style.cssText;
// sets the borders to zero
ele.style.border="0px";
// computes the border size
var bord=(w-ele.offsetWidth)/2;
// resets the css
ele.style.cssText=cssBackup;
alert(bord);
When left & right border has same width:
function getWidth(div) {
return (div.offsetWidth - div.clientWidth) /2
}
getWidth(document.querySelector('#content'))
According to W3Schools, this property is supported by major browsers. Thus you shouldn't have any difficulty in using it.
However, using a JavaScript framework like jQuery would always help you not worrying about trivial issues like this.
Works for me
let content = document.querySelector('#content');
// here 'borderWidth' is similar to element.style syntax
let contentBorderWidth = getComputedStyle(content).borderWidth; // 1px
// number, without 'px'
let contentBorderWidthNumber = parseFloat(getComputedStyle(content).borderWidth); // 1
// demo
content.innerHTML = contentBorderWidth +', '+ contentBorderWidthNumber;
// in your case, to alert
window.alert(contentBorderWidth +', '+ contentBorderWidthNumber);
div#content {
border: 1px solid skyblue;
}
<div id="content"></div>
More about getComputedStyle.
Using jQuery or straight Javascript, I'm looking for the best way to find the leftmost div (or in general the DOM element with the minimum or maximum position on either axis).
So far I have two solutions:
Iterate through the div objects that I want to consider, saving the smallest left position found.
Build an array of objects and using javascript's sort() function with a comparison function that looks at the left property, then choosing the 0th element.
I know that solution 1 would be O(N), but I'm not sure what the efficiency of the sort() function is in most browsers, or if there is a completely different approach.
Consider this:
you keep track of one element and one position, you access each element once
you keep track of all elements and access all positions multiple times because of sorting
What do you think is the fastest? :)
option 1: iterate through it only once
var $smallest = {left: 000000000, item: null};
var $left = 0;
$('selector').each(function(){
$left = $(this).offset().left;
if ($left < $smallest.left)
{
$smallest.left = $left;
$smallest.item = this;
}
});
option 2: iterate through it at least twice
var $array = [];
$('selector').each(function(){
var $this = $(this);
$array.push({left: $this.offset().left, item: this});
});
$array.sort(function(a,b){
if (a.left < b.left) return -1;
if (a.left > b.left) return 1;
return 0;
});
// smallest is $array[0]
option 1 is always faster in this case since you only have to sort it while selecting, sorting almost comes for free in that case.
edit: of course, using only the DOM for this is again, way faster.
Probably not going to do any better than O(n) and the best you'll do pure sorting is O(nlogn). The fastest way would be to walk the DOM. I would call getElementsByTagName("div") and iterate through keeping track of the left most element.
function findLeftMostDiv() {
var leftest = { "left": 999999999999, elem: null };
var divs = document.getElementsByTagName("div");
for(i=0; i<divs.length; i++) {
var div = divs[i];
var curleft = findPos(div);
if(curleft < leftest.left) {
leftest.left = curleft;
leftest.elem = div;
}
}
return leftest.elem;
}
function findPos(obj) {
var curleft=0;
if(obj.offsetParent) {
do {
curleft += obj.offsetLeft;
} while (obj = obj.offsetParrent);
}
return curleft;
}
I have an array which is part of a small JS game I am working on I need to check (as often as reasonable) that each of the elements in the array haven't left the "stage" or "playground", so I can remove them and save the script load
I have coded the below and was wondering if anyone knew a faster/more efficient way to calculate this. This is run every 50ms (it deals with the movement).
Where bots[i][1] is movement in X and bots[i][2] is movement in Y (mutually exclusive).
for (var i in bots) {
var left = parseInt($("#" + i).css("left"));
var top = parseInt($("#" + i).css("top"));
var nextleft = left + bots[i][1];
var nexttop = top + bots[i][2];
if(bots[i][1]>0&&nextleft>=PLAYGROUND_WIDTH) { remove_bot(i); }
else if(bots[i][1]<0&&nextleft<=-GRID_SIZE) { remove_bot(i); }
else if(bots[i][2]>0&&nexttop>=PLAYGROUND_HEIGHT) { remove_bot(i); }
else if(bots[i][2]<0&&nexttop<=-GRID_SIZE) { remove_bot(i); }
else {
//alert(nextleft + ":" + nexttop);
$("#" + i).css("left", ""+(nextleft)+"px");
$("#" + i).css("top", ""+(nexttop)+"px");
}
}
On a similar note the remove_bot(i); function is as below, is this correct (I can't splice as it changes all the ID's of the elements in the array.
function remove_bot(i) {
$("#" + i).remove();
bots[i] = false;
}
Many thanks for any advice given!
Cache $("#" + i) in a variable; each time you do this, a new jQuery object is being created.
var self = $('#' + i);
var left = parseInt(self.css("left"));
var top = parseInt(self.css("top"));
Cache bots[i] in a variable:
var current = bots[i];
var nextleft = left + current[1];
var nexttop = top + current[2];
Store (cache) the jQuery object of the DOM element within the bot representation. At the moment it's been created every 50ms.
What I mean by this is that for every iteration of the loop, you're doing $('#' + i). Every time you call this, jQuery is building a jQuery object of the DOM element. This is far from trivial compared to other aspects of JS. DOM traversal/ manipulation is by far the slowest area of JavaScript.
As the result of $('#' + i) never changes for each bot, why not store the result within the bot? This way $('#' + i) gets executed once, instead of every 50ms.
In my example below, I've stored this reference in the element attribute of my Bot objects, but you can add it your bot (i.e in bots[i][3])
Store (cache) the position of the DOM element representing the bot within the bot representation, so the CSS position doesn't have to be calculated all the time.
On a side note, for (.. in ..) should be strictly used for iterating over objects, not arrays. Arrays should be iterated over using for (..;..;..)
Variables are extremely cheap in JavaScript; abuse them.
Here's an implementation I'd choose, which incorporates the suggestions I've made:
function Bot (x, y, movementX, movementY, playground) {
this.x = x;
this.y = y;
this.element = $('<div class="bot"/>').appendTo(playground);
this.movementX = movementX;
this.movementY = movementY;
};
Bot.prototype.update = function () {
this.x += this.movementX,
this.y += this.movementY;
if (this.movementX > 0 && this.x >= PLAYGROUP_WIDTH ||
this.movementX < 0 && this.x <= -GRID_SIZE ||
this.movementY > 0 && this.y >= PLAYGROUND_HEIGHT ||
this.movementY < 0 && this.y <= -GRIDSIZE) {
this.remove();
} else {
this.element.css({
left: this.x,
right: this.y
});
};
};
Bot.prototype.remove = function () {
this.element.remove();
// other stuff?
};
var playground = $('#playground');
var bots = [new Bot(0, 0, 1, 1, playground), new Bot(0, 0, 5, -5, playground), new Bot(10, 10, 10, -10, playground)];
setInterval(function () {
var i = bots.length;
while (i--) {
bots[i].update();
};
}, 50);
You're using parseInt. As far as I know, a bitwise OR 0 is faster than parseInt. So you could write
var left = $("#" + i).css("left") | 0;
instead.
Furthermore, I wouldn't make use of jQuery functions to obtain values like these every 50 ms, as there's always a bit more overhead when using those (the $ function has to parse its arguments, etc.). Just use native JavaScript functions to optimize these lines. Moreover, with your code, the element with id i has to be retrieved several times. Store those elements in a variable:
var item = document.getElementById(i);
var iStyle = item.style;
var left = iStyle.left;
…
(Please note that I'm not a jQuery expert, so I'm not 100% sure this does the same.)
Moreover, decrementing while loops are faster than for loops (reference). If there's no problem with looping through the elements in reverse order, you could rewrite your code to
var i = bots.length;
while (i--) {
…
}
Use offset() or position() depending on if you need coordinates relative to the document or the parent. position() is most likely faster since browsers are efficient at finding offsets relative to the parent. There's no need for parsing the CSS. You also don't need the left and top variables since you only use them once. It may not be as readable but you're going for efficiency:
var left = $("#" + i).position().left + bots[i][1];
var top = $("#" + i).position().top + bots[i][2];
Take a look here for a great comparison of different looping techniques in javascript.
Using for...in has poor performance and isn't recommended on arrays. An alternative to looping backwards and still using a for loop is to cache the length so you don't look it up with each iteration. Something like this:
for(var i, len = bots.length; i < len; i++) { ... }
But there are MANY different ways, as shown in the link above and you might want to test several with your actual application to see what works best in your case.
For a JavaScript library I'm implementing, I need to clone an element which has exactly the same applied style than the original one. Although I've gained a rather decent knowledge of JavaScript, as a programming language, while developing it, I'm still a DOM scripting newbie, so any advice about how this can be achieved would be extremely helpful (and it has to be done without using any other JavaScript library).
Thank you very much in advance.
Edit: cloneNode(true) does not clone the computed style of the element. Let's say you have the following HTML:
<body>
<p id="origin">This is the first paragraph.</p>
<div id="destination">
<p>The cloned paragraph is below:</p>
</div>
</body>
And some style like:
body > p {
font-size: 1.4em;
font-family: Georgia;
padding: 2em;
background: rgb(165, 177, 33);
color: rgb(66, 52, 49);
}
If you just clone the element, using something like:
var element = document.getElementById('origin');
var copy = element.cloneNode(true);
var destination = document.getElementById('destination');
destination.appendChild(copy);
Styles are not cloned.
Not only will you need to clone, but you'll probably want to do deep cloning as well.
node.cloneNode(true);
Documentation is here.
If deep is set to false, none of the
child nodes are cloned. Any text that
the node contains is not cloned
either, as it is contained in one or
more child Text nodes.
If deep evaluates to true, the whole
subtree (including text that may be in
child Text nodes) is copied too. For
empty nodes (e.g. IMG and INPUT
elements) it doesn't matter whether
deep is set to true or false but you
still have to provide a value.
Edit: OP states that node.cloneNode(true) wasn't copying styles. Here is a simple test that shows the contrary (and the desired effect) using both jQuery and the standard DOM API:
var node = $("#d1");
// Add some arbitrary styles
node.css("height", "100px");
node.css("border", "1px solid red");
// jQuery clone
$("body").append(node.clone(true));
// Standard DOM clone (use node[0] to get to actual DOM node)
$("body").append(node[0].cloneNode(true));
Results are visible here: http://jsbin.com/egice3/
Edit 2
Wish you would have mentioned that before ;) Computed style is completely different. Change your CSS selector or apply that style as a class and you'll have a solution.
Edit 3
Because this problem is a legitimate one that I didn't find any good solutions for, it bothered me enough to come up with the following. It's not particularily graceful, but it gets the job done (tested in FF 3.5 only).
var realStyle = function(_elem, _style) {
var computedStyle;
if ( typeof _elem.currentStyle != 'undefined' ) {
computedStyle = _elem.currentStyle;
} else {
computedStyle = document.defaultView.getComputedStyle(_elem, null);
}
return _style ? computedStyle[_style] : computedStyle;
};
var copyComputedStyle = function(src, dest) {
var s = realStyle(src);
for ( var i in s ) {
// Do not use `hasOwnProperty`, nothing will get copied
if ( typeof s[i] == "string" && s[i] && i != "cssText" && !/\d/.test(i) ) {
// The try is for setter only properties
try {
dest.style[i] = s[i];
// `fontSize` comes before `font` If `font` is empty, `fontSize` gets
// overwritten. So make sure to reset this property. (hackyhackhack)
// Other properties may need similar treatment
if ( i == "font" ) {
dest.style.fontSize = s.fontSize;
}
} catch (e) {}
}
}
};
var element = document.getElementById('origin');
var copy = element.cloneNode(true);
var destination = document.getElementById('destination');
destination.appendChild(copy);
copyComputedStyle(element, copy);
See PPK's article entitled Get Styles for more information and some caveats.
After looking at a couple of good solutions across the WEB, I decided to combine all the best aspects of each and come up with this.
I left my solution in plain super fast Javascript, so that everybody can translate to their latest and great JS flavour of the month.
Representing the vanilla from manilla.....
* #problem: Sometimes .cloneNode(true) doesn't copy the styles and your are left
* with everything copied but no styling applied to the clonedNode (it looks plain / ugly). Solution:
*
* #solution: call synchronizeCssStyles to copy styles from source (src) element to
* destination (dest) element.
*
* #author: Luigi D'Amico (www.8bitplatoon.com)
*
*/
function synchronizeCssStyles(src, destination, recursively) {
// if recursively = true, then we assume the src dom structure and destination dom structure are identical (ie: cloneNode was used)
// window.getComputedStyle vs document.defaultView.getComputedStyle
// #TBD: also check for compatibility on IE/Edge
destination.style.cssText = document.defaultView.getComputedStyle(src, "").cssText;
if (recursively) {
var vSrcElements = src.getElementsByTagName("*");
var vDstElements = destination.getElementsByTagName("*");
for (var i = vSrcElements.length; i--;) {
var vSrcElement = vSrcElements[i];
var vDstElement = vDstElements[i];
// console.log(i + " >> " + vSrcElement + " :: " + vDstElement);
vDstElement.style.cssText = document.defaultView.getComputedStyle(vSrcElement, "").cssText;
}
}
}
None of those worked for me, but I came up with this based on Luigi's answer.
copyStyles(source: HTMLElement, destination: HTMLElement) {
// Get a list of all the source and destination elements
const srcElements = <HTMLCollectionOf<HTMLElement>>source.getElementsByTagName('*');
const dstElements = <HTMLCollectionOf<HTMLElement>>destination.getElementsByTagName('*');
// For each element
for (let i = srcElements.length; i--;) {
const srcElement = srcElements[i];
const dstElement = dstElements[i];
const sourceElementStyles = document.defaultView.getComputedStyle(srcElement, '');
const styleAttributeKeyNumbers = Object.keys(sourceElementStyles);
// Copy the attribute
for (let j = 0; j < styleAttributeKeyNumbers.length; j++) {
const attributeKeyNumber = styleAttributeKeyNumbers[j];
const attributeKey: string = sourceElementStyles[attributeKeyNumber];
dstElement.style[attributeKey] = sourceElementStyles[attributeKey];
}
}
}