Finding what the clientHeight will be after layout - javascript

I have a div with a series of spans under it (this.content). The div had "word-wrap: break-word", "min-width: 400px" and "white-space: normal" and "overflow-x: auto:".
I need to calculate the number of lines the text will wrap to. I was hoping to go this route:
var hiddenParent = document.createElement("div");
hiddenParent.style.width = width + "px";
hiddenParent.style.height = "20000px";
hiddenParent.style.display = "block";
hiddenParent.style.wordWrap = "break-word";
hiddenParent.style.whiteSpace = "normal";
hiddenParent.style.overflowX = "auto";
hiddenParent.style.maxWidth = hiddenParent.style.width;
var newElement = TreeDataItem.HtmlElementSource.createElement("div");
newElement.style.maxWidth = hiddenParent.style.maxWidth;
hiddenParent.appendChild(newElement);
newElement.innerHTML = this.content;
rows newElement.style.clientHeight/charHeight;
But the clientHeight doesn't get calculated. I don't want it rendered so I was putting it under a hiddentElement.
I'm missing something obvious or I can't do this. Help!

Related

How to split HTML content into virtual pages

I'm using quilljs editor that returns html editor.getContent()
I want to generate a pages preview by split the HTML contents based on the height of the page,
I first tried this solution https://stackoverflow.com/a/54984668/7511165
content is overflowing if its a long paragraph, so I tried to split the content when its larger than the page, But I could not calculate the the splitting index based on the offsceeenDiv,
So I tried the CSS column
https://stackoverflow.com/a/56141110/7511165
This idea is cloning all the content on every page, so it's good for performance at all
Any solution?
note:
The content is HTML (h1, h2, p, pre), not text
update 1
Code I tried with CSS column method :
let newContent =`<h1 class="cht chapterTitleView-${id}">${chapterTitle}</h1>${chapterContent}`
const pageWidth = getComputedStyle(document.documentElement)
.getPropertyValue('--page-width') // 370;
.replace('px', '');
const content = document.getElementById('content');
content.style.display = 'block';
content.innerHTML = newContent;
const totalWidth = content.scrollWidth;
const totalPages = totalWidth / pageWidth;
const html = content.innerHTML;
const container = document.querySelector(`#chapter-preview-${id} .chapterPreviewContainer`)
// 7. create the pages dom
for (let p = 0; p < totalPages; p++) {
let pageWrapper = document.querySelector("#temp-chapter-page").innerHTML.replaceTemplateVars({CID: id, ID:p , PAGE: p + 1});
container.insertAdjacentHTML("beforeend", pageWrapper);
const page = container.querySelector(`#chapter-page-${id}-${p}`);
page.innerHTML = html;
page.style.cssText = `width: ${totalWidth}px; transform: translateX(-${p * pageWidth}px);`;
}

Make a div in Javascript and output it to the DOM

I am having a little trouble right now creating multiple divs through javascript. This form has helped me create one. but I am trying to create 3. If anyone could help that would be great. I looked on one form How can I create and style a div using JavaScript? and was able to create one div. But I cannot figure out out to create multiple divs that are calling from an HTML div ID.
window.onload = function() {
var div = document.createElement("div");
div.style.width = "100px";
div.style.height = "300px";
div.style.background = "#FF0000";
div.innerHTML = "Going";
document.getElementById("one").appendChild(div);
var two = document.createElement("two");
div.style.width = "200px";
div.style.height = "200px";
div.style.background = "#FF0000";
div.innerHTML = "To Do";
document.getElementById("two").appendChild(two);
var three = document.createElement("three");
div.style.width = "300px";
div.style.height = "100px";
div.style.background = "#0000FF";
div.innerHTML = "Great";
document.getElementById("three").appendChild(three);
};
<div id="one"></div>
<div id="two"></div>
<div id="three"></div>
Write your javascript something like this
window.onload = function() {
var div1 = document.createElement("div");
div1.style.width = "100px";
div1.style.height = "300px";
div1.style.background = "#FF0000";
div1.innerHTML = "Going";
document.getElementById("one").appendChild(div1);
var div2 = document.createElement("div");
div2.style.width = "200px";
div2.style.height = "200px";
div2.style.background = "#FF0000";
div2.innerHTML = "To Do";
document.getElementById("two").appendChild(div2);
var div3 = document.createElement("div");
div3.style.width = "300px";
div3.style.height = "100px";
div3.style.background = "#0000FF";
div3.innerHTML = "Great";
document.getElementById("three").appendChild(div3);
};
As you can see in the picture below. Your code creates tags <two></two> and <tree></tree>, which is not valid html tags.
To solve this problem, just pass div instead of two and three into document.createElement() function. Like so:
var two = document.createElement("div");
... element styling here ...
two.style.width = "200px";
two.style.height = "200px";
...
var three = document.createElement("div");
... element styling here ...
three.style.width = "200px";
three.style.height = "200px";
...
Here is something fun to play with, might be helpful.
function CREATE_DIV( _WHERE_DO_YOU_WANT_IT_ , _STYLE_IT_ , _ID_IT_ , _INNER_TEXT_ ){
var div = document.createElement("div");
/* SET THE ID */
div.id = _ID_IT_;
/* SET THE INNERHTML */
div.innerHTML = _INNER_TEXT_;
/* SET THE STYLE PROPERTIES */
for(var RESULT in _STYLE_IT_){
if( _STYLE_IT_.hasOwnProperty(RESULT)){
/* ADD WHAT YOU NEED */
/* ADD WHAT YOU NEED */
console.log(RESULT+':'+_STYLE_IT_[RESULT]);
if(RESULT==='background'){div.style.background = _STYLE_IT_[RESULT]; }
if(RESULT==='position'){ div.style.position = _STYLE_IT_[RESULT]; }
if(RESULT==='width'){ div.style.width = _STYLE_IT_[RESULT]; }
if(RESULT==='height'){ div.style.height = _STYLE_IT_[RESULT]; }
if(RESULT==='left'){ div.style.left = _STYLE_IT_[RESULT]; }
if(RESULT==='top'){ div.style.top = _STYLE_IT_[RESULT]; }
if(RESULT==='padding'){ div.style.padding = _STYLE_IT_[RESULT]; }
if(RESULT==='border'){ div.style.border = _STYLE_IT_[RESULT]; }
//div.style.setAttribute( RESULT, _STYLE_IT_[RESULT] );//.RESULT = _STYLE_IT_[RESULT];
}}
/* APPEND OR ADD DIV TO ELEMENT */
/* ( _WHERE_DO_YOU_WANT_IT_ ) */
_WHERE_DO_YOU_WANT_IT_.appendChild(div);
}///
////
////
window.onload = function() {
var I_WANT_IT_HERE = document.getElementsByTagName('BODY')[0];
var GIVE_IT_AN_ID = 'DIV_01';
var INNER_HTML_TEXT= 'Div 1<BR>Whatever i want in my DIV !!!'
var STYLE = {}; // CREATE javascript Object of data. NOT Array.
STYLE['position'] = 'absolute';
STYLE['width'] = '90%';
STYLE['height'] = '33%';
STYLE['left'] = '0px';
STYLE['top'] = '0px';
STYLE['border'] = '2px dotted red';
STYLE['background']='rgba(300, 300, 300, 0.7)';
CREATE_DIV(I_WANT_IT_HERE , STYLE , GIVE_IT_AN_ID , INNER_HTML_TEXT);
STYLE['padding'] = '8px';
STYLE['left'] = '0px';
STYLE['top'] = '33%';
var GIVE_IT_AN_ID = 'DIV_02';
var INNER_HTML_TEXT= 'Div 2'
CREATE_DIV(I_WANT_IT_HERE , STYLE , GIVE_IT_AN_ID , INNER_HTML_TEXT);
var STYLE = {};// THIS RESETS STYLE
// EXAMPLE no position is set.
STYLE['padding'] = '8px';
STYLE['left'] = '0px';
STYLE['top'] = '66%';
STYLE['border'] = '1px dotted blue';
var GIVE_IT_AN_ID = 'DIV_03';
var INNER_HTML_TEXT= '<BR><BR><BR><BR>Div 3 is under Div 1'
CREATE_DIV(I_WANT_IT_HERE , STYLE , GIVE_IT_AN_ID , INNER_HTML_TEXT);
STYLE['left'] = '0px';
STYLE['top'] = '66%';
STYLE['border'] = '1px dotted lime';
var GIVE_IT_AN_ID = 'DIV_04';
var I_WANT_IT_HERE = document.getElementById('DIV_02');
var INNER_HTML_TEXT= 'Div 4 is inside Div 2<SPAN ID=SPAN></SPAN>'
CREATE_DIV(I_WANT_IT_HERE , STYLE , GIVE_IT_AN_ID , INNER_HTML_TEXT);
STYLE['border'] = '1px dotted blue';
var I_WANT_IT_HERE = document.getElementById('SPAN');
var INNER_HTML_TEXT= 'This is a span inside of DIV 02 & DIV 04'
CREATE_DIV(I_WANT_IT_HERE , STYLE , GIVE_IT_AN_ID , INNER_HTML_TEXT);
/*************************/};

How do you stop a Child Element from appending multiple times?

Okay I know you have to use the removeChild() method, but how and where? So I'm trying to make a script that tells me the width and height of the window size so its easier to make media queries in CSS. Okay I know how to do this website by website basis, but I want to make this script where it can apply to ALL websites which is WHY I have to have the appendChild. Everything works the way I want it too, but it keeps appending if you see this in the firebug tool.
The only thing one needs to do to see the code in action is to add the onresize="getWinSize()"; to the body.
Also if there is a better way to write this let me know (: Please no jQuery.
<body onresize="getWinSize()";>
Here is the code.
function getWinSize () {
var newDiv = document.createElement('div');
newDiv.id = "windowSizeOutput";
document.body.appendChild(newDiv);
var wd = window.innerWidth;
var ht = window.innerHeight;
var display = document.getElementById("windowSizeOutput");
display.style.background = "white";
display.style.height = "45px";
display.style.width = "100px";
display.style.border = "2px solid black";
display.style.position = "fixed";
display.style.left = "10px";
display.style.top = "200px";
display.innerHTML = "Width: " + wd + "px" + " Height: " + ht + "px";
}
In the getWinSize() function you can always check for the element existence and then remove it if it already exists. Something like this:
function getWinSize () {
var element = document.getElementById("windowSizeOutput");
if(element)
element.parentNode.removeChild(element);
var newDiv = document.createElement('div');
newDiv.id = "windowSizeOutput";
document.body.appendChild(newDiv);
var wd = window.innerWidth;
var ht = window.innerHeight;
var display = document.getElementById("windowSizeOutput");
display.style.background = "white";
display.style.height = "45px";
display.style.width = "100px";
display.style.border = "2px solid black";
display.style.position = "fixed";
display.style.left = "10px";
display.style.top = "200px";
display.innerHTML = "Width: " + wd + "px" + " Height: " + ht + "px";
}
You don't necessarily need to remove the element every time, you can just update its content
Either by checking if it is already in the document:
function getWinSize() {
var display = document.getElementById("windowSizeOutput");
if (!display) {
display = document.createElement('div');
display.id = "windowSizeOutput";
document.body.appendChild(display);
var wd = window.innerWidth;
var ht = window.innerHeight;
display.style.background = "white";
display.style.height = "45px";
display.style.width = "100px";
display.style.border = "2px solid black";
display.style.position = "fixed";
display.style.left = "10px";
display.style.top = "200px";
}
display.innerHTML = "Width: " + wd + "px" + " Height: " + ht + "px";
}
Or by saving the node out of the scope of the function
var display = null;
function getWinSize() {
if (!display) {
display = document.createElement('div');
display.id = "windowSizeOutput";
document.body.appendChild(display);
var wd = window.innerWidth;
var ht = window.innerHeight;
display.style.background = "white";
display.style.height = "45px";
display.style.width = "100px";
display.style.border = "2px solid black";
display.style.position = "fixed";
display.style.left = "10px";
display.style.top = "200px";
}
display.innerHTML = "Width: " + wd + "px" + " Height: " + ht + "px";
}
(And you can eventually put the initialization code in another function for clarity)

Picking out specific individual controls out in javascript

So what I am trying to do here is copy an html table out of clubMemebers. Paste that table into two new places, and on the second "new" table called tblBody; set its first rows visibility to hidden, change the text in the cells to '' (nothing) and make its height = 0px... basically.
The problem is probably quite an obvious one to most people... they both are linked to a single table so a change to one will make a change to them all...
How can I separate these tables to do what I need to do? I've tried to search but all I came up with is copying tables to clipboard or excel.
Here bellow is the html and the javascript I am using.
<div id="DivHeaderRow"></div>
<div class="gridDiv" id="gridDiv" onscroll="OnScrollDiv(this)"></div>
<div id="DivFooterRow"></div>
<table style="width: 100%;" class="MemberTbl" runat="server" id="clubMembers" >
<tr class="Header" style="position:fixed;"></tr>
</table>
and the javascript:
function MakeStaticHeader(gridId, height, width, headerHeight, isFooter) {
var tblHead = document.getElementById(gridId);
var tblBody = document.getElementById(gridId);
if (tblHead) {
var DivHR = document.getElementById('DivHeaderRow');
var DivMC = document.getElementById('gridDiv');
var DivFR = document.getElementById('DivFooterRow');
//*** Set divheaderRow Properties ****
DivHR.style.height = headerHeight + 'px';
DivHR.style.position = 'relative';
DivHR.style.top = '10px';
DivHR.style.zIndex = '10';
DivHR.style.verticalAlign = 'top';
DivHR.style.overflow = 'hidden';
//*** Set divMainContent Properties ****
DivMC.style.position = 'relative';
DivMC.style.zIndex = '1';
//*** Set divFooterRow Properties ****
DivFR.style.width = (parseInt(width) - 16) + 'px';
DivFR.style.position = 'relative';
DivFR.style.top = -headerHeight + 'px';
DivFR.style.verticalAlign = 'top';
DivFR.style.paddingtop = '2px';
DivFR.style.overflow = 'hidden';
if (isFooter) {
var tblfr = tbl.cloneNode(true);
tblfr.removeChild(tblfr.getElementsByTagName('tbody')[0]);
var tblBody = document.createElement('tbody');
tblfr.style.width = '100%';
tblfr.cellSpacing = "0";
//*****In the case of Footer Row *******
tblBody.appendChild(tbl.rows[tbl.rows.length - 1]);
tblfr.appendChild(tblBody);
DivFR.appendChild(tblfr);
}
//****Copy Header in divHeaderRow****
var tblBodyRow = tblBody.rows[0];
tblBodyRow.style.visibilty = 'hidden';
tblBodyRow.style.height = '0px';
for(var i = 0, tblBodyRow; tblBodyCell = tblBodyRow.cells[i]; i++)
{
tblBodyCell.innerHTML = '';
}
DivHR.appendChild(tblHead.cloneNode(true));
DivMC.appendChild(tblBody.cloneNode(true));
}
}
function OnScrollDiv(Scrollablediv) {
document.getElementById('DivHeaderRow').scrollLeft = Scrollablediv.scrollLeft;
document.getElementById('DivFooterRow').scrollLeft = Scrollablediv.scrollLeft;
}
window.onload = function () {
MakeStaticHeader('clubMembers', 100, 400, 25, false)
}
Maybe your problem would be fixed changing your lines:
var tblHead = document.getElementById(gridId);
var tblBody = document.getElementById(gridId);
for:
var tblHead = document.getElementById(gridId).cloneNode(true);
var tblBody = document.getElementById(gridId).cloneNode(true);
However, maybe you could try with jquery to manipulate DOM elements... Then, with something like this could be enough (see Fiddle):
tableHtml = $('#clubMembers').html();
$('#DivHeaderRow').html(tableHtml);
$('#DivHeaderRow').find("tr").first().hide();
$('#gridDiv').html(tableHtml);

JavaScript / CSS overflow-x not stretching around floated elements

I'm trying to make a basic GUI for a JavaScript web app, that lets users use the web app on any device, without putting too much time and effort into making it too responsive. I figured I could easily use basic overflow properties for container divs, so the user can scroll to the desired button, rather than changing the layout completely for different screen resolutions.
I'm trying to make the top toolbar (File, Edit, Insert etc..) with an overflow-x set to scroll, which holds divs floated to the left. For some reason, the overflow-x does nothing, so some of the buttons are hidden. Why is this?
jsFiddle
// STYLE WINDOW
document.body.style.margin = "0px";
document.body.style.padding = "0px";
document.body.style.backgroundColor = "#66666A";
document.body.style.color = "#0099AA";
document.body.style.fontFamily = "calibri, sans-serif";
function getScrollbarWidth()
{var o = document.createElement('div');o.style.overflowY = "scroll";o.style.visibility = "none";var i = document.createElement('div');o.appendChild(i);document.body.appendChild(o);var r = o.offsetWidth-i.offsetWidth;o.parentNode.removeChild(o);return(r);}
function getScrollbarHeight()
{var o = document.createElement('div');o.style.overflowX = "scroll";o.style.visibility = "none";document.body.appendChild(o);var r = o.offsetHeight;o.parentNode.removeChild(o);return(r);}
// CREATE EDITOR TOOLBAR
toolbar = document.createElement('div');
toolbar.style.position = "fixed";
toolbar.style.top = "0px";
toolbar.style.left = "0px";
toolbar.style.width = "100%";
toolbar.style.height = 32+getScrollbarHeight()+"px";
toolbar.style.overflowX = "scroll";
toolbar.style.overflowY = "hidden";
toolbar.style.backgroundColor = "#33333A";
toolbar.buttons = {};
toolbar.addButton = function(buttonName){
var newButton = document.createElement('div');
newButton.style.width = "128px";
newButton.style.height = "16px";
newButton.style.float = "left";
newButton.style.paddingTop = "8px";
newButton.style.paddingBottom = "8px";
newButton.style.textAlign = "center";
newButton.style.fontSize = "15px";
newButton.style.color = ";DD8800";
newButton.innerHTML = buttonName;
this.buttons[buttonName] = newButton;
this.appendChild(newButton);
}
toolbar.addButton("File");
toolbar.addButton("Edit");
toolbar.addButton("Insert");
toolbar.addButton("Settings");
toolbar.addButton("Share");
toolbar.addButton("Help");
// CREATE EDITOR WINDOW SELECTOR
windowSelector = document.createElement('div');
windowSelector.style.position = "fixed";
windowSelector.style.top = 32+getScrollbarHeight()+"px";
windowSelector.style.left = "0px";
windowSelector.style.bottom = "0px";
windowSelector.style.width = 128+getScrollbarWidth()+"px";
windowSelector.style.overflowY = "scroll";
windowSelector.style.backgroundColor = "#33333A";
windowSelector.buttons = {};
windowSelector.addButton = function(buttonName,imageURL){
this.buttons[buttonName] = document.createElement('div');
this.buttons[buttonName].style.width = "128px";
this.buttons[buttonName].style.height = "64px";
this.buttons[buttonName].style.backgroundColor = "#22222A";
this.buttons[buttonName].style.borderTop = "1px solid #115588";
var buttonImage = document.createElement('div');
buttonImage.style.width = "32px";
buttonImage.style.height = "32px";
buttonImage.style.margin = "8px";
buttonImage.style.marginTop = "16px";
buttonImage.style.marginBottom = "16px";
buttonImage.style.float = "left";
buttonImage.style.backgroundImage = "url('"+imageURL+"')";
buttonImage.style.backgroundSize = "contain";
buttonImage.style.backgroundPosition = "center center";
this.buttons[buttonName].appendChild(buttonImage);
var buttonTitle = document.createElement('div');
buttonTitle.style.width = "72px";
buttonTitle.style.height = "16px";
buttonTitle.style.paddingTop = "24px";
buttonTitle.style.paddingBottom = "24px";
buttonTitle.style.paddingLeft = "8px";
buttonTitle.style.float = "left";
buttonTitle.style.color = "#77BBDD";
buttonTitle.style.fontSize = "14px";
buttonTitle.innerHTML = buttonName;
this.buttons[buttonName].appendChild(buttonTitle);
this.appendChild(this.buttons[buttonName]);
}
windowSelector.addButton("Sprites","");
windowSelector.addButton("Objects","");
windowSelector.addButton("Scripts","");
windowSelector.addButton("Rooms","");
windowSelector.addButton("Backgrounds","");
windowSelector.addButton("Sounds","");
windowSelector.addButton("Paths","");
windowSelector.addButton("Timelines","");
windowSelector.addButton("Constants","");
// CREATE APPLICATION SCRIPT
application = document.createElement('script');
document.body.appendChild(application);
document.body.appendChild(toolbar);
document.body.appendChild(windowSelector);
Elements will only overflow horizontally if they have no other choice. Usually this is a good thing, but in some cases... yeah.
floats will wrap. Instead, try using display:inline-block on the items, and white-space:nowrap on the container.
This will force the elements to overflow horizontally.

Categories

Resources