Adding variables to SVG drop-shadow for-loop in Javascript - javascript

I want to add multiple "drop-shadow" filters to an SVG, to achieve a 3D style effect, with the edges being a gradient -- similar to this (I'll later add an interval to animate it). I've used this to generate a gradient array with 70 shades.
However, I cannot get the "drop-shadow" property to work with my for-loop.
Unlike "text-shadow" style for example where I can do something like this:
var current = element.style.textShadow;
var appliedStyle = -i + 'px ' + i + 'px ' + gcolor[i];
element.style.textShadow = current+appliedStyle;
I couldn't figure out how to get the current "drop-shadow" property and concatenate another filter to it. So I came up with the idea to just add classes. This is my best attempt at coding it:
let text = document.querySelector(".brand-svg");
let gcolor = ["#ffb576","#ffb275","#ffb074","#ffad73","#ffab72","#ffa871","#ffa670","#ffa370","#ffa16f","#ff9e6e","#ff9c6d","#ff996c","#ff976b","#ff946a","#ff9269","#ff9068","#ff8d67","#ff8b66","#ff8865","#ff8664","#ff8363","#ff8163","#ff7e62","#ff7c61","#ff7960","#ff775f","#ff745e","#ff725d","#ff705c","#ff6d5b","#ff6b5a","#ff6859","#ff6658","#ff6357","#ff6156","#ff5e56","#ff5c55","#ff5954","#ff5753","#ff5452","#ff5251","#ff4f50","#ff4d4f","#ff4b4e","#ff484d","#ff464c","#ff434b","#ff414a","#ff3e49","#ff3c49","#ff3948","#ff3747","#ff3446","#ff3245","#ff2f44","#ff2d43","#ff2b42","#ff2841","#ff2640","#ff233f","#ff213e","#ff1e3d","#ff1c3c","#ff193c","#ff173b","#ff143a","#ff1239","#ff0f38","#ff0d37","#ff0a36"];
for (var i = 1; i <= 70; i++) {
text.classList.add("shadowlayer"+i);
var current = document.querySelector(".shadowlayer"+i);
current.style.setProperty(`-webkit-filter`, `drop-shadow 0px (${-i})px (${gcolor[i]})`);
};
body {
display: flex;
justify-content: center;
}
.brand-svg {
width: 400px;
}
<svg class="brand-svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 748.17 433.89"><defs>
<style> .brand-svg path, polygon {fill:#fff;stroke:#ffb777;stroke-miterlimit:10;stroke-width:3px;}</style>
</defs>
<path class="svg-b-d" d="M746.37,26.21q-1.07-10.31-13.43-17.09T701.85,1.74c-1,0-2,0-3,0a142.7,142.7,0,0,0-37.5,5.51,200.39,200.39,0,0,0-43.71,18L559.68,57l86.6,47.6,57.94-31.84q21.79-12,32.51-24.13T746.37,26.21ZM694.43,46q-3.63,7.51-18.36,15.6l-10.41,5.73L627,46.1l10.4-5.72q14.73-8.1,28.39-10.09a51.29,51.29,0,0,1,7.33-.56,32,32,0,0,1,15.63,3.68Q698,38.51,694.43,46Z"/>
<polygon class="svg-b-n" points="539.34 112.27 583.62 136.62 493.18 137.64 449.59 161.6 536.18 209.2 579.78 185.24 536.24 161.31 625.93 159.87 669.53 135.91 582.93 88.31 539.34 112.27"/>
<path class="svg-b-a" d="M308.71,209.12l35.73,75.55,45.77-25.15-6.22-11,46.35-25.47,20,3.42,45.95-25.26L359,181.48Zm90.59,8.56-25.13,13.81-11.53-20.15Z"/>
<path class="svg-b-r" d="M326.64,290.81q1-8-7.66-12.75-8.07-4.43-20.48-4.66l-1.27,0q-11.94,0-26.85,4.31a160.09,160.09,0,0,0-32.6,13.82L173,327.12l86.6,47.61,43.6-24-30.88-17.18,57.2,2.72L377.4,310,314,308.37Q325.61,298.76,326.64,290.81Zm-47.71,17.27c-.91,1.81-3.46,3.85-7.65,6.16L254,323.74l-14.68-8.07,17.28-9.5a33.36,33.36,0,0,1,11.28-4.06,21.59,21.59,0,0,1,2.7-.18,12.06,12.06,0,0,1,5.93,1.37Q280.29,305.39,278.93,308.08Z"/>
<path class="svg-b-b" d="M186,353.17q-6.37-3.5-16.52-3.5c-1.16,0-2.37,0-3.61.1a84.43,84.43,0,0,0-27.06,6.61q8.9-6.78,10.07-13.14t-6.4-10.53a34,34,0,0,0-16.65-3.82,63.66,63.66,0,0,0-12.28,1.3q-17.93,3.53-39.14,15.19l-70.89,39L90.13,432,163,391.9q22.57-12.4,28.49-22.45T186,353.17ZM80.89,378.94l-12.24-6.73,16.9-9.28a33.73,33.73,0,0,1,10.27-4,15,15,0,0,1,2.45-.21,10.35,10.35,0,0,1,5.1,1.24c2,1.12,2.6,2.46,1.68,4.05s-3.35,3.45-7.27,5.61Zm58.23.6q-1.44,2.34-7.33,5.58L112,396,99.72,389.3l19.84-10.91q7.53-4.14,12.81-4.14a10.27,10.27,0,0,1,5,1.2C139.5,376.62,140.09,378,139.12,379.54Z"/></svg>
Why doesn't this work? Is there an easier way to do this?

The filter property accepts multiple filters, so you can repeat drop-shadow:
filter: drop-shadow(30px 10px 4px #44d) drop-shadow(70px 1px 4px #f0d);
All you need to do is pass correct string to style property filter.
In your case code would look something like this:
let text = document.querySelector(".brand-svg");
let gcolor = ["#ffb576","#ffb275","#ffb074"];
for (var i = 0; i < gcolor.length; i++) {
text.style.filter = `${text.style.filter} drop-shadow(0px ${-i}px 0px ${gcolor[i]})`;
}

Related

Why does redrawing my image not work properly?

You helped me get the draw function work properly. Here's the complete program, which works perfectly until the "draw" button is clicked. Instead of drawing a new image, the entire window vanishes. Any help greatly appreciated!
This code is formatted as instructed, 4 spaces per tab. I don't know any more details to add.
<!DOCTYPE html>
<html>
<head>
<title>Digital Holograms</title>
<style>
div {
float: left;
height: 580px;
width: 500px;;
padding: 0 10px;
}
#column1 {
background-color: #FFFFFF;
}
#column2 {
background-color: #FFFFFF;
width: 500px
}
</style>
</head>
<body>
<div id="column1">
<canvas id="my-canvas" width="500" height="500"></canvas>
<script>
let selFun = 0 // selected function to draw
// user may change this by selection box
let canvas = document.querySelector('#my-canvas')
let context = canvas.getContext('2d')
context.fillStyle = 'black'
function draw(n) {
let contourInterval = 1500
let contourWidth = 500
let fsize = 1000
let x0 = fsize / 2
let y0 = fsize / 2
for (j = 0, y = -y0; j < fsize; j++, y++) {
for (i = 0, x = -x0; i < fsize; i++, x++) {
let fun = 0
switch(n) {
case 0:
fun = (x*x + y*y)
break;
case 1:
fun = (x*x - y*y)
break;
default:
fun = (x*x + y*y)
}
if (Math.abs(fun % contourInterval) < contourWidth) {
context.fillRect(x+x0/2, y+y0/2, 1, 1)
}
}
}
document.write('<h4 style="text-align: center;">Hologram of z = x&#x00B2 + y&#x00B2</h4>');
}
draw(selFun)
function getSelection() {
let selFun = document.getElementById("selectFunction").value
//document.write(selFun)
}
</script>
<h3>To view other holograms:</br>Select a function, then press draw</h3>
<select id="selectFunction" onchange="getSelection()">
<option value=0>z = x&#x00B2 + y&#x00B2</option>
<option value=1>z = x&#x00B2 - y&#x00B2</option>
</select>
<button type = "button";
onclick = draw(selFun)>Draw</button>
</div>
</body>
</html>
There a several glitches that are preventing this code working as intended.
1) The loss of content on button press
This is a result of an incorrect use of document.write() (which can only be effectively used by inline scripts to inset text as the page is loading. Running it on a loaded page causes document.open() to be executed, clearing the existing document. See: https://developer.mozilla.org/en-US/docs/Web/API/Document/write
The correct way to update information on the page is to change the innerText or innerHTML of an existing element, or insert a new element with the required text.
In my snippet I added the h4 tag, with an id of updatedTitle, to the html (initially with no content, which will be added by the script):
<h4 id="updatedTitle" style="text-align: center;"></h4>
The innerText of the tag is added by the last line of the draw() function:
document.getElementById("updatedTitle").innerText = `Hologram of ${equation}`;
Note, the template literal ${equation}, this was used to allow the equation to be updated when a new option is drawn, by fetching the markup for the equation from the element (shown later).
2) Drop Down changes not registering
After correcting point 1), there was still a problem: pressing the draw button failed to render a new graph. After some investigation with console.log()s at various parts of the execution cycle I determined that the onchange of the dropdown element was not being received by the javascript.
The reason for this turned out to be a case of very bad luck - the choice of the function name intended to handle the change: getSelection. It turns out that getSelection is a built-in method of the Window object and seemingly cannot be used as a user function name.
Changing the function name to readSelection() cured this problem;
(https://developer.mozilla.org/en-US/docs/Web/API/Window/getSelection)
3) Button onclick event argument not accessible
The button's onlick event calls the draw() function, and attempts to send selFun as an argument. As written, selFun is not accessible from the element.
Instead, the onlick was changed to simply call the draw() function without any argument.
selFun is declared, and assigned with 0, in the global scope of the script and so is accessible from function in the script. Thus the argument n used in the switch block of the draw() function can be replaced directly with selFun (and n also deleted from the function parameter):
4) modification to readSelection()
The original values of the option list items were 0 and 1, entered as (unquotted) numbers in the markup. Although this is allowed, the 0 and 1 are converted to strings when the value attribute is read regardless of whether they were quotted or not (much like the contents of a text input field). Javascript is good at coercing numbers from digit characters but I was getting a bug where selFun was not being read properly for the case statement. Formally setting selFun to an integer value cured this:
selFun = parseInt(document.getElementById("selectFunction").value);
Since readSelection is invoked each time the drop down changes, it is also the place to keep track of which equation should be used in the label on next draw. Hence the following line was included in the function:
equation = document.getElementById("selectFunction").children[selFun].innerText;
with equation being declared (and set to the dropdown initial state) in the global scope of the script, to be read and used to form a label, as discussed in 1) above.
5) Draw only working for first change of equation
Once the above changes were made, changing the dropdown and pressing the button resulted in the new equation being rendered. However, subsequent changes and attempts to draw did not appear to do much.
This was because the second equation was being drawn on top of the first and, once both equations were drawm further drawing didn's show any change.
The solution was to include a standard clear step at the start of the draw() function:
context.clearRect(0, 0, canvas.width, canvas.height);
6) Element accessibility
The entire script was moved to the foot of the html to allow all elements to load before running the script, this prevented some errors where the js was trying to access elements that did not yet exist.
The programme seems to work as intended now. I don't understand anything about the equation plots but they are most impressive and, should you add more to it in future, perhaps you will comment back here so I can have a look!
Working snippet:
let selFun = 0
let equation = document.getElementById("selectFunction").children[selFun].innerHTML; // to be used to update graph label;
let canvas = document.querySelector('#my-canvas');
let context = canvas.getContext('2d');
context.fillStyle = 'black';
function draw() {
// clear canvas'
context.clearRect(0, 0, canvas.width, canvas.height);
let contourInterval = 1500;
let contourWidth = 500;
let fsize = 1000;
let x0 = fsize / 2
let y0 = fsize / 2
for (j = 0, y = -y0; j < fsize; j++, y++) {
for (i = 0, x = -x0; i < fsize; i++, x++) {
let fun = 0
switch(selFun) {
case 0:
fun = (x*x + y*y);
break;
case 1:
fun = (x*x - y*y);
break;
default:
fun = (x*x + y*y);
} // end switch
if (Math.abs(fun % contourInterval) < contourWidth) {
context.fillRect(x+x0/2, y+y0/2, 1, 1)
} // end if;
} // next i;
} // next j;
const titleH4 = document.getElementById("updatedTitle");
document.getElementById("updatedTitle").innerText = `Hologram of ${equation}`;
} // end draw;
draw();
function readSelection() {
selFun = parseInt(document.getElementById("selectFunction").value);
equation = document.getElementById("selectFunction").children[selFun].innerText;
} // end readSelection function;
div {
float: left;
height: 580px;
width: 500px;;
padding: 0 10px;
}
#column1 {
background-color: #FFFFFF;
}
#column2 {
background-color: #FFFFFF;
width: 500px
}
select {
width: 200px;
height: 1.5em;
font-size: 2em;
border-radius: 5px;
background: cyan;
text-align: center;
}
button {
width: 100px;
height: 1.5em;
font-size: 2em;
}
<div id="column1">
<canvas id="my-canvas" width="500" height="500"></canvas>
<h3>To view other holograms:</br>Select a function, then press draw</h3>
<select id="selectFunction" onchange="readSelection()">
<option value="0">z = x&#x00B2 + y&#x00B2</option>
<option value="1">z = x&#x00B2 - y&#x00B2</option>
</select>
<button type = "button" onclick="draw()">Draw</button>
<h4 id="updatedTitle" style="text-align: center;"></h4>
</div>
edit
Regarding the appearance of the dropdown and button - they can be styled much like any other html element. I've added some arbitrary changes to their apperance by adding rules for select and button elements to the css. The elements can be given a class name if more specific styling is needed without affecting other elements of the same kind.
I don't know what your code is trying to do but when the button is pressed you are updating the source completely.
Here is that bad code :)
document.write('<h4 style="text-align: center;">Hologram of z = x&#x00B2 + y&#x00B2</h4>');
Add it inside a div instead of writing it to the whole document.
document.getElementById("example").innerHTML = 'your codes';

Javascript className changes aren't working

I have a small test page setup to test a sprite sheet I have. Each sprite in sprites.css looks like this...
.a320_0 {
top: 0px;
left: 0px;
width: 60px;
height: 64px;
background: url("images/sprites.png") no-repeat -787px -398px;
}
My page looks like this...
var i = 0
function imageChange() {
setTimeout(function() {
var hdg = i * 15;
document.getElementById('image').className = "a320_" + hdg;
i++;
if (i < 24) {
imageChange();
}
}, 1000)
}
imageChange()
<div id='imageContainer'>
<div id='image'></div>
</div>
I'm logging the class name during the loop and can see it changing and the names correspond to classes that exist in my style sheet. sprites.css and sprites.png are both in the images folder and the images folder is in the same directory as my page.
If I just copy one of the rules from my style sheet and put it directly onto my page and replace the name with #image for testing purposes I can display that particular image so my sprite coordinates are fine but if I do the same thing on my actual css file I don't get the same result leading me to believe that my style sheet might not be loading. Even if I just put the styles directly into my document and try to use .className = , it still doesn't work. I had this working recently but it doesn't seem to be working anymore. I'm kind of lost here...
It should be document.getElementById("image").classList.add("a320_" + hdg);.
var i = 0;
function imageChange() {
setTimeout(function() {
var hdg = i * 15;
document.getElementById("image").classList.add("a320_" + hdg);
i++;
if (i < 24) {
imageChange();
}
}, 1000);
}
imageChange();
.a320_0 {
top: 0px;
left: 0px;
width: 60px;
height: 64px;
background: url("https://source.unsplash.com/random") no-repeat -787px -398px;
}
<div id='imageContainer'>
<div id='image'></div>
</div>
Codepen
While your script is correct, you seem to have made a major syntax error which is not giving you the desired results.
When adding class name to an HTML element using JavaScript, the syntax is as follows:
selector.property.action("property value");
for example your code should be:
document.getElementById('image').classList.add("a320_" + hdg);
So the correction needs to be done only in the javascript part:
var i = 0
function imageChange() {
setTimeout(function() {
var hdg = i * 15;
document.getElementById('image').classList.add("a320_" + hdg)
i++;
if (i < 24) {
imageChange();
}
}, 1000)
}
imageChange()
Hope this was helpful!

Why is documentFragment no faster than repeated DOM access?

I was always under the impression that rather than touching the DOM repeatedly, for performance reasons, we should use a documentFragment to append multiple elements to, and then append the fragment into the document once, rather than just repeatedly appending new elements one-by-one into the DOM.
I've been trying to use Chrome's dev tools to profile these two approaches, using this test page:
<button id="addRows">Add rows</button>
<table id="myTable"></table>
Test 1 uses this code to append 50000 new rows to the table:
let addRows = document.getElementById('addRows');
addRows.addEventListener('click', function () {
for (let x = 0; x < 50000; x += 1) {
let table = document.getElementById('myTable'),
row = document.createElement('tr'),
cell = document.createElement('td'),
cell1 = cell.cloneNode(),
cell2 = cell.cloneNode(),
cell3 = cell.cloneNode();
cell1.textContent = 'A';
cell2.textContent = 'B';
cell3.textContent = 'C';
row.appendChild(cell1);
row.appendChild(cell2);
row.appendChild(cell3);
table.appendChild(row);
}
});
Clicking the button while recording in Chrome's Timeline tool results in the following output:
Test 2 uses this code instead:
let addRows = document.getElementById('addRows');
addRows.addEventListener('click', function () {
let table = document.getElementById('myTable'),
cell = document.createElement('td'),
docFragment = document.createDocumentFragment();
for (let x = 0; x < 50000; x += 1) {
let row = document.createElement('tr'),
cell1 = cell.cloneNode(),
cell2 = cell.cloneNode(),
cell3 = cell.cloneNode();
cell1.textContent = 'A';
cell2.textContent = 'B';
cell3.textContent = 'C';
row.appendChild(cell1);
row.appendChild(cell2);
row.appendChild(cell3);
docFragment.appendChild(row);
}
table.appendChild(docFragment);
});
This has a performance profile like this:
The second, supposedly much faster alternative to the first, actually takes longer to run! I've run these tests numerous times and sometimes the second approach is slightly faster, and sometimes, as these images show, the second approach is slightly slower, but not once has there been any significant difference between the two approaches.
What is happening here? Are browsers optimized so well now that this makes no difference anymore? Am I using the profiling tools incorrectly?
I'm on Windows 10, with Chrome 57.0.2987.133
Well actually your test code just insert nodes and do not alter their content or CSS which would in fact force the rendering engine to a reflow.
I have prepared 3 tests to demonstrate this dramatic difference.
Simple DOM modificiation resulting Layout Trashing
Simple DOM modificiation through window.requestAnimationFrame()
Virtual DOM modification through document.createDocumentFragment()
Notes:
You might like to test on full screen.
In Firefox I have obtained even more dramatic results.
// Resets the divs
function resetLayout() {
divs = document.querySelectorAll('div');
speed.textContent = "Resetting Layout...";
setTimeout(function() {
each.call(divs, function(div) {
div.style.height = '';
div.offsetTop;
});
speed.textContent = "";
}, 16);
}
// print the result
function renderSpeed(ms) {
speed.textContent = ms + 'ms';
}
var divs = document.querySelectorAll('div'),
raf = window.requestAnimationFrame,
each = Array.prototype.forEach,
isAfterVdom = false,
start = 0;
// Reset the Layout
reset.onclick = resetLayout;
// Direct DOM Access
direct.onclick = function() {
isAfterVdom && (divs = document.querySelectorAll('div'), isAfterVdom = false);
start = performance.now();
each.call(divs, function(div) {
var width = div.clientWidth;
div.style.height = ~~(Math.random()*2*width+6) + 'px';
div.style.backgroundColor = '#' + Math.floor(Math.random() * 16777215).toString(16);
});
// Render result
renderSpeed(performance.now() - start);
};
// Access DOM at the next frame by requestAnimationFrame
rAF.onclick = function() {
isAfterVdom && (divs = document.querySelectorAll('div'), isAfterVdom = false);
start = performance.now();
each.call(divs, function(div) {
var width = div.clientWidth;
// Schedule the write operation to be run in the next frame.
raf(function() {
div.style.height = ~~(Math.random()*2*width+6) + 'px';
div.style.backgroundColor = '#' + Math.floor(Math.random() * 16777215).toString(16);
});
});
// Render result
raf(function() {
renderSpeed(performance.now() - start);
});
};
// Update the vDOM and access DOM just once by rAF
vdom.onclick = function() {
var sectCl = divCompartment.cloneNode(true),
divsCl = sectCl.querySelectorAll('div'),
dFrag = document.createDocumentFragment(),
width = divCompartment.querySelector('div').clientWidth;
isAfterVdom = true;
end = 0;
start = performance.now();
each.call(divsCl, function(div) {
div.style.height = ~~(Math.random()*2*width+6) + 'px';
div.style.backgroundColor = '#' + Math.floor(Math.random() * 16777215).toString(16);
});
dFrag.appendChild(sectCl);
divCompartment.parentNode.replaceChild(dFrag, divCompartment);
// Render result
renderSpeed(performance.now() - start);
};
html {
font: 14px Helvetica, sans-serif;
background: black;
color: white;
}
* {
box-sizing: border-box;
margin-bottom: 1rem;
}
h1 {
font-size: 2em;
//word-break: break-word;
-webkit-hyphens: auto;
}
button {
background-color: white;
}
div {
display: inline-block;
width: 5%;
margin: 3px;
background: white;
border: solid 2px white;
border-radius: 10px
}
section {
overflow: hidden;
}
#speed {
font-size: 2.4em;
}
<body>
<h1>Updating 1000 DOM Nodes</h1>
<section>
<button id="reset">Reset Layout</button>
<button id="direct">Update Directly</button>
<button id="rAF">Update by rAF</button>
<button id="vdom">Update by vDOM</button>
<section id="speed"></section>
<section id="divCompartment">
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</section>
</body>
Sorry... Due to the 30000 character limit in the answers and the length of the previous one i have to place another one as an extension to my previous answer.
I guess everybody's heard that direct DOM access is no good... Yes that's what i had always been told and so believed in the correctness of the virtual DOM approach. Though i hadn't quite understood the fact that while both the DOM and vDOM are represented on the memory, how come one is faster than the other? Actually streching my test further i have come to believe that the real bottle neck boils down to the JS engine performance if you update the DOM properly.
Now lets imagine the case of having 1000 divs to be updated repeatedly on background-color and height CSS properties.
If you do this directly on DOM elements all you have to do is to keep a nodeList of these elements and simply alter their style.backgroundColor and style.heigth properties.
If you do this by a document fragment you have the apparent benefit of not touching the DOM multiple times, instead first you have to
clone the parent container of the 1000 div elements.
access the nodeList containing the divs like parent.children
perform necessary alterations on each div element,
create a document fragment
re-clone the previously cloned (step 1) parent container element and append it to a document fragment (or alternatively you may chose to clone the divs' container from the DOM if you need the fresh ones but this way or that way for each modification you have to clone them)
append the document fragment to the parent of div container in the DOM and remove the old div container. Basically a Node.replaceChild operation.
In fact for this test we don't need a document fragment since we are not creating new nodes but just updating the already existing ones. So we can skip the step 4 and at step 5 we can directly use the cloned copy of our divs container as a source to our replaceChild operation.
How to update DOM properly..? Definitely asynchronously. So as for the previous example if you move the direct update portion to an asynchronous timeline like setTimeout(_ => renderDirect(),0) it will be the fastest among all. But then repeatedly updating the dome can be a little tricky.
One way to achieve this is to repedeatly feed a setTimeout(_ => renderDirect(),0) with our DOM updates like.
for (var i = 0; i < cnt; i++) setTimeout(_ => renderDirect(divs,width),0);
In the above case the performance of the JS engine is very material on the results. If our code is too light, than multiple cycles will stack up on a single DOM update and we will observe only a few of them. In this particular case, we got to see only like 9 of the 50 updates.
So delaying each turn further might be a good idea. So how about;
for (var i = 0; i < cnt; i++) setTimeout(_ => renderDirect(divs,width),i*17);
Well this is much better, I've got 22 of the 50 updates actually painted on my screen. So it happens to be, if the delay is chosen to be long enough you'll have all the frames painted. But how much long is a problem. Since if it's too long you have idle time for your rendering engine and it resembles slow DOM update. So for this particular test, it turns out to be something like 29-30ms ish... is the optimal value to observe 50 separate DOM updates of all 1000 divs in 1400 ms. Well at least on my desktop with Chrome. You may observe something entirely different depending on the hardware or the browser.
So the setTimeout resolution doesn't look very promising to me. We have to automate this job. Lucky us, we have the right tool for this job. rAF to help again. I have come up with a helper function to abuse the rAF (requestAnimationFrame). We will update the 1000 divs all at once, in one go, by directly accessing the DOM at the next available animation frame. And... while we are still in the asynchronous timeline we will request another animation frame from within the currently executing callback. So another rAF is called from the callback of the rAF recursively. I named this function looper
var looper = n => n && raf(_ => (renderDirect(divs, width),looper(--n)));
well it's a bit of an ES6 code. So let me translate it into classing JS.
function looper(n){
if (n !== 0) {
window.requestAnimationFrame(function(){
renderDirect(divs,width);
looper(n-1);
});
}
}
Now everything should be automated.. It seems pretty cool and done in 1385ms.
So since now we are a little more knowledgeable we may play with the code.
// Resets the divs
function resetLayout() {
divs = document.querySelectorAll('div');
speed.textContent = "Resetting Layout...";
setTimeout(function() {
each.call(divs, function(div) {
div.style.height = '';
div.backcgoundColor = '';
});
speed.textContent = "";
}, 16);
}
// print the result
function renderSpeed(ms) {
speed.textContent = ms + 'ms';
}
function renderDirect(divs,width){
each.call(divs, function(div) {
div.style.height = ~~(Math.random()*2*width+6) + 'px';
div.style.backgroundColor = '#' + Math.random().toString(16).substr(-6);
});
// Render result
renderSpeed(performance.now() - start);
}
function renderByVDOM(sct,prt,wdt){
var //dFrag = document.createDocumentFragment();
divs = sct.children;
each.call(divs, function(div) {
div.style.height = ~~(Math.random()*2*wdt+6) + 'px';
div.style.backgroundColor = '#' + Math.random().toString(16).substr(-6);
});
//dFrag.appendChild(sct);
prt.replaceChild(sct, divCompartment);
// Render result
renderSpeed(performance.now() - start);
}
var divs = document.querySelectorAll('div'),
width = divs[1].clientWidth;
raf = window.requestAnimationFrame,
each = Array.prototype.forEach,
isAfterVdom = false,
start = 0,
cnt = 50;
// Reset the Layout
reset.onclick = resetLayout;
// Direct DOM Access
direct.onclick = function() {
var looper = n => n && raf(_ => (renderDirect(divs, width),looper(--n)));
isAfterVdom && (divs = document.querySelectorAll('div'), isAfterVdom = false);
start = performance.now();
//for (var i = 0; i < cnt; i++) setTimeout(_ => renderDirect(divs,width),i*29);
looper(cnt);
};
// Update the vDOM and access DOM just once by rAF
vdom.onclick = function() {
var sectCl = divCompartment.cloneNode(true),
parent = divCompartment.parentNode,
looper = n => n && raf(_ => (renderByVDOM(sectCl.cloneNode(true), parent, width),looper(--n)));
isAfterVdom = true;
start = performance.now();
looper(cnt);
};
html {
font: 14px Helvetica, sans-serif;
background: black;
color: white;
}
* {
box-sizing: border-box;
margin-bottom: 1rem;
}
h1 {
font-size: 2em;
-webkit-hyphens: auto;
}
button {
background-color: white;
}
div {
display: inline-block;
width: 5%;
margin: 3px;
background: white;
border: solid 2px white;
border-radius: 10px
}
section {
overflow: hidden;
}
#speed {
font-size: 2.4em;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>repl.it</title>
<link href="index.css" rel="stylesheet" type="text/css" />
<script src="index.js" async></script>
</head>
<body>
<h1>Updating 1000 DOM Nodes</h1>
<section>
<button id="reset">Reset Layout</button>
<button id="direct">Update Directly</button>
<button id="vdom">Update by vDOM</button>
<section id="speed"></section>
<section id="divCompartment">
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</section>
</section>
</body>
</html>
So the tests look like direct access through rAF is better than cloning and working on the clone and replacing the old one with it. Particularly when a huge DOM chunk is replaced it seems to me that the GC (Garbage Collect) task gets involved in the middle of the job and things get a little sticky. I am not sure how it can be eliminated. Your ideas are most welcome.
A Side Note:
This test also shows that the current (Version 91.0.838.3) of the new chromium based Edge Browser is performing DOM renderings ~15% faster than the current (Version 89.0.4389.114) Chrome.
I'm not sure how exactly to interpret your profiler results but running it through benchmark.js test shows second option is faster in Chrome: https://jsbench.me/awj1gwhk9i/1
ALso faster in FF (although a bit less difference)

remove Highlighted Text SectionWise in Iframe

I am following this plugin https://github.com/mir3z/texthighlighter for text Highlighitng in IFrame. Upon Selection Text if i want to remove perticular section of the Selected{colored} text it is not happening. even though this plugin provides removing of highlighted text line by line ... but i need it differently as below
(function() {
var iframe = document.getElementById('iframeDiv'), colors = new ColorPicker(
document.querySelector('.color-picker')), hltr;
var i = 0;
highlights = 1;
iframe.onload = function() {
var hltr = new TextHighlighter(
iframe.contentDocument.body,
{
onAfterHighlight : function(range, highlights) {
i++;
var xColor = $('.selected').css(
'border-right-color');
highlights[highlights.length - 1].parentNode.innerHTML += '<div class="clored_div'+i+'" style="position: absolute;right: 13px;width: 40px;border-right: 14px solid '+xColor+';height: 40px;background:none;border-bottom: 14px solid transparent;border-top: 10px solid transparent;box-shadow: none;height: 0;margin: 0 auto 20px;width: 0;"><img id="removeHighLight" onClick="removeColor();"; title="<fmt:message key="colorRemove"/>" src="<fmt:message key="images"/>/close_rm.png" alt="Close" style="height: 15px;position: absolute;right: -21px;top: -23px;width: 15px;z-index: 9999;"/></div><div id=section' + i +'></div>'
function removeColor(){
$('.clored_div"'+i+'"').remove();
}
},
colors.onColorChange(function(color) {
hltr.setColor(color);
});
};
//for the src HTML please keep any HTML under same application and access like this
iframe.src = 'http://localhost:8080/html/example.htm';
})();
i want to call this function of this section of colored text in order to remove the color.
function removeColor(){$('.clored_div"'+i+'"').remove();}
anyOne help me out with this problem.. if you need more code or understanding for this problem please ask
Thank you so much in Advance.
parent.removeColor();
Iframe is having this function declared, but it is defined in mainPage.

When using element.style = <some CSSStyleDeclaration> makes element dissapear

I use, (pls never mind the selector, I know it should be changed but it is found nevertheless).
let leftArrow = <HTMLElement> document
.querySelector('div[style="position: absolute; left: 6px; transform: skewX(22.6deg);' +
' transform-origin: 0px 0px 0px; height: 24px; width: 10px;' +
' box-shadow: rgba(0, 0, 0, 0.6) 0px 1px 6px; background-color: rgb(255, 255, 255);"]');
Then I use:
let myStyle = leftArrow.style; //this gets me a CSSStyleDeclaration object
console.log(myStyle); // those are equal objects
console.log(leftArrow.style); // those are equal objects
But when I do:
leftArrow.style = myStyle; //this should change nothing ?!
my element dissappears ?!
My goal is to use a class and then do sth like this:
leftArrow.style = this.getStyleFromClass(selector_to_find_class_name);
But after simple:
leftArrow.style = myStyle;
my element from upper one becomes :
<div></div>
which makes it basically not visible. Why ?
I think what you are trying to do is apply the original inline styles back. To do this, you can use cssText to get the values, and than you can set it back.
var div = document.getElementById("x");
var backUp = div.style.cssText;
div.style.backgroundColor = "yellow";
div.style.color = "blue";
window.setTimeout( function () {
div.style.cssText = backUp;
}, 4000);
<div id="x" style="background-color:red">Hello</div>
leftArrow.style = myStyle; //this should change nothing ?!
Yes but only if you have:
let myStyle = leftArrow.style; //this gets me a CSSStyleDeclaration object
letArrow.style = myStyle;
This is most likely not the code you have and you are generating the object on the fly. Do not assign to style directly. Instead assign to members of style e.g. letArrow.style.color = "red"

Categories