Hide a javascript created div until all content is rendered - javascript

So I have a mobile webpage that needs to get some content from the web to be displayed in a modal. The modal itself is created via Javascript which is a div container which is set to display:none when closed.
<body>
Display this content:
<button onclick="displayModal()">display</button>
<script type="text/javascript">
var htmlContents = "<div>some pretty heavy content</div>";
var modal = //some code to create the modal div element.
modal.style.display = 'none';
function displayModal() {
modal.innerHTML = htmlContents;
modal.style.display = 'block';
}
</script>
</body>
Then the user clicks a button, then we populate the innerHTML of the div with some HTML and then switch the modal to display: block
The problem here is that the contents we're adding to innerHTML may be pretty heavy. Lots of images and css which may take some time to render (1 or 2 seconds on old devices). However, they start poping up into the view one by one. So the user may see images and divs out of place while things render.
Is there any way to switch the modal to visible ONLY after all the contents have been rendered offscreen.
P.S: This is written on pure javascript (no jquery or any other library since performance is a concern).

I think there are a couple of ways you could do this. I think if you move the modal.innerHTML = htmlContents out of the displayModal() function you could get the images and modal contents to load before the user clicks on it. So it would look like this:
<body>
Display this content:
<button onclick="displayModal()">display</button>
<script type="text/javascript">
var htmlContents = "<div>some pretty heavy content</div>";
var modal = //some code to create the modal div element.
modal.style.display = 'none';
modal.innerHTML = htmlContents;
function displayModal() {
modal.style.display = 'block';
}
</script>
</body>
I also found this jQuery library that may help, it seems like a lot of people are using it:
https://github.com/desandro/imagesloaded

Related

How to hide elements of an external widget on my website

I am trying to instal a chat widget in my website and I would like to hide certain elements of the chat widget.
The chat is provided by Tidio but I guess this apply to any widget.
I am specifically trying to hide a button that minimise the chat button as highlighted in the image below.
I have inspected the button and found out that button has a class exit-chat, so I run this script where I try to get the button with document.getElementsByClassName("exit-chat") however the document is somehow null. I have also tried to add a delay before getting the button but it does not work.
Here is the code I have written and here is the link to a codepen
<script src="//code.tidio.co/fouwfr0cnygz4sj8kttyv0cz1rpaayva.js" async="async"></script>
<!-- Swap your javascript code above -->
<script>
(function() {
function onTidioChatApiReady() {
(function() {
//code run after the widget is loaded
window.tidioChatApi.open();
const loading = document.getElementsByClassName("loading");
loading[0].style.display = "none";
const tidioo = document.getElementById("tidio-chat");
tidioo.style.display = "display";
var timeoutInSeconds = 2;
setTimeout(function() {
console.log("timeout");
const minimizee = document.getElementsByClassName("exit-chat");
console.log(minimizee==null);
minimizee[0].style.display = "none";
minimizee[1].style.display = "none";
}, timeoutInSeconds * 1000)
})();
}
if (window.tidioChatApi) {
window.tidioChatApi.on("ready", onTidioChatApiReady);
} else {
document.addEventListener("tidioChat-ready", onTidioChatApiReady);
}
})();
</script>
<div class="loading">
<p>Loading...</p>
</div>
Can you please help to understand where I get this wrong and explain how to hide that button?
Thanks!!
If you embedded an iframe that is hosted in another website, you will not be able to edit the style of the elements inside the iframe by adding CSS to your website.

HTML5 / JS - preProcess of uploaded html page and simulate pagebreaks

I'm making a html-5 based report generator. I created a button to upload a [HTML] page containing multiple paragraphs and tables, which is continuous.
Now my task is to display the whole contents into separated a4-sized pages, just like in Microsoft Word.]
This is the sketch: >>>LINK<<<
Here are part of my codes.
function xx (){
var fi = document.getElementById('fi').files[0];
reader.onload = function (e){
var reader = new FileReader();
var inner ="";
inner += this.result;
inn.innerHTML ="<center><div class='bg' id='0'><div id='testmain'>"+inner+"</div></div></center>";
}
reader.onerror = function (e){
dd.innerHTML = "error<br>";
}
reader.readAsText(fi);
}
After displaying the result of pages, users can click a specific part of the paper, just like a paragraph, then a pagebreak is created and the pages changes, the remaining content are pushed starting from top of next page.
Could you please give me some ideas about how to realize it?
Instead of using comments as chat to present my suggestion, here's my answer:
I once tried to do such a thing, back in html4. Here's the logic I was using. Create a div that has the exact size of your page CONTENT (after margins and all) put all your content in it and cycle through its direct children. If the current child's bottom is lower than his parent, take it and all the following children and put them in a new div CONTENT. Rinse and repeat.
For this, you will need to calculate the height of the container and cross-check it against the offset+height of the elements. My vanillaJS is a bit rusty as for browser specifics and all... So I will display the logic using jQuery but most of it can easily be made in pure JS. The code will assume that we have a div.page that has the right CSS to make it exactly the size of a content page, and that will not resize to content (overflow:hidden) and the document will contain one of those div with all the content of what should be in the pages...
$(document).ready(function(){
var $page = $('div.page');
var newPage = true;//To track if we loop
while(newPage){
newPage = false;
$page.children().each(function(){
if($(this).offset().top+$(this).outerHeight() > $page.offset().top+$page.height()){
$page = $('<div>').addClass('page').appendTo('body');
$(this).nextAll().appendTo($page);
$(this).prependTo($page);//Don't forget the element too.
newPage = true;
}
});
}
});

javascript nullifies when setting the document.body.innerHTML

Good day.
I am currently working on a project that prints a desired <div> to a printer.
Here is the code:
var printContents = document.getElementById(id).innerHTML;
var originalContents = document.body.innerHTML;
document.body.innerHTML = printContents;
document.body.style.display = "none";
window.print();
document.body.innerHTML = originalContents;
document.body.style.display = "block";
This code works and prints the desired <div>, but after that I need to put back the previous page again so I used this statement:
document.body.innerHTML = originalContents;
document.body.style.display = "block";
This displays the previous page but the functionalities of my buttons are gone?! Can someone explain to me what happened and is there a solution to this problem? Thanks in advance!
This is happening because you've wiped out the old DOM which had events wired up to it, and replaced it with a totally new, different DOM that just happens to have the same HTML.
Presumably you're taking this approach because the printable zone is determined at runtime. A less-destructive solution might be to create a new <iframe> and copy the desired markup into that; then invoke print() on the iframe. Something like:
var printElement = function(element) {
var frame = document.createElement('iframe');
document.appendChild(frame);
frame.contentDocument.innerHTML = element.innerHTML;
frame.contentWindow.print();
document.removeChild(frame);
};
You'll also need to copy over any CSS references into the <iframe>.
(note this is pseudo-code and not tested)
Your code clears the document and then puts back the HTML stored in originalContents, but this variable stores only a string, so all previously registered event handlers are gone.
Why don't you create a print stylesheet and hide everything except the content that you want to print?
<link rel="stylesheet" type="text/css" href="print.css" media="print">
When you reset the innerHTML, you don't get all your event handlers back. They are wiped out when you create entirely new DOM elements.
One idea would be to have two master divs in the body, one that is your normal display and one that is what you want to print. You can then hide whichever one you don't want to display like this:
<body>
<div id="mainContent">main screen content goes here</div>
<div id="printContent">generated print content goes here</div>
</body>
// hide main content
var mainDiv = document.getElementById("mainContent");
mainDiv.style.display = "none";
// put content to print in the print div and show it
var printDiv = document.getElementById("printContent");
printDiv.innerHTML = document.getElementById(id).innerHTML;
printDiv.style.display = "block";
// print
window.print();
// restore visibility
mainDiv.style.display = "block";
printDiv.style.display = "none;
You could also just use the whole body for printing and use a stylesheet with media="print" to control the visibility of the things you do/don't want to print.
You can add a click event to all dives inside your page so that user can click the div.
after that add a class to that div which the class is defined within the print CSS file.
inside css print file use the following code:
`*{display:none}
.printableDiv{display:block}`
to define a print css file use this code :
<link rel="stylesheet" type="text/css" href="print.css" media="print"> (which Rafael has told you ).
good luck

Hide document body on page load

I have a javascript that is loaded in the document head that needs to hide the document body until all page contents have loaded. I have tried:
$(document.body).hide();
But there still appears to be a flicker in some browsers. I am using the latest jQuery library (1.6.2). Firing the event on domready does hide the document body, but causing a flicker as well.
All that I can control is what is in the javascript. I cannot manipulate the static html pages as the script is being developed as a plugin.
Hiding content until the page is loaded is an anti-usability feature. Some parts of the content may take while to load, meanwhile your visitors see nothing. Browsers render content as it is received because users chose that as the preferred model in the very begining.
If you persist with this approach, you must hide the content using script. Otherwise, users with javascript disabled or not available, or where the script fails to execute correctly, will never see the content.
The simplest way to hide content using script is to use document.write to create a style sheet, then remove it to show the content:
document.write( '<style class="hideStuff" ' +
'type="text/css">body {display:none;}<\/style>');
window.onload = function() {
setTimeout(
function(){
var s, styles = document.getElementsByTagName('style');
var i = styles.length;
while (i--) {
s = styles[i];
if (s.className == 'hideStuff') {
s.parentNode.removeChild(s);
return;
}
}
}, 1000); // debug pause
}
The best way to do this is to put all content in a container div and have a style sheet that hides it by default. You can then show the content once everything is loaded. There is no way to run Javascript before the default page content renders so the only way to start out hidden is with a statically defined CSS rule:
HTML:
<body>
<div id="container">
all dynamic page content goes here
</div>
</body>
CSS in a stylesheet with the page to make it initially not visible:
#container {display: none;}
And, then you can do whatever you want with javascript and when you're done building the page, you do this to make it visible:
document.getElementById("container").style.display = "block";
or in jQuery:
$("#container").show();
You can use CSS and JS:
In the top of your document, below the TITLE use CSS:
<style type="text/css">body {visibility: hidden;}</style>
And after this use JS to restore the visibility:
<script type="text/JavaScript">
document.write('<style type="text/css">body {visibility: visible;}</style>');
</script>
Enjoy :)

Need to set 1 span's style to display:block on page load for an image gallery made up of span's set to display:none

i have some javascript in the head of a page that controls an image gallery where the user clicks a thumbnail image and a larger image and some text are revealed in a span. there are 10 of these thumbnails per page and i need to find out how to set the 1st thumbnail's hidden span to "block" on page load.
<script type="text/javascript">
function hideSpan(spanName) {
var obj = document.getElementById(spanName);
obj.style.border="0px";
obj.style.color="#fff";
obj.style.display="none";
obj.style.left="333px";
obj.style.padding="0";
obj.style.position="absolute";
obj.style.top="55px";
obj.style.width="244px";
}
function showSpan(spanName) {
var spanEl, count = 1;
while(spanEl = document.getElementById('link' + count++)){
spanEl.style.display = 'none';
}
var obj = document.getElementById(spanName);
obj.style.display="block";
}
</script>
any help with this is VERY appreciated thank you.
The simple, breezy way is to do this:
<body onload="showSpan('link1');">
The trouble here is that the onload event attached to body that way is executed a little late in the page loading (After all the parts-- including images-- are loaded) so it'll be murder for your dial up users. jQuery implements a much better way:
$(document).ready(function () {
showSpan('link1');
});
If you're not using jQuery, then someone here much wiser than I more than likely knows the correct way to do it using "proper" JavaScript, I don't remember the event name that jQuery uses off the top of my head.

Categories

Resources