I'm using CKEditor inline feature.
I initiate a new editor instance every time the user hovers over a text area. The problem is that when the user hovers and focuses on a textarea for the first time, the editor toolbar takes a couple of seconds to appear because the editor is loading all the necessary assets.
My question is: How can I pre-load all the necessary CKEditor assets during an onclick event instead of when the user hovers a text area?
I tried adding all the assets in the HTML file and the editor appears instantly, however when I look at the DOM, the file assets are sourced twice. Meaning even when the files are already present, CKEditor still loads them.
You could go ahead and initialize the instances of the editor normally, but set visibility of the toolbar header and footer to hidden and reduce their height to 0. Then on hover you'll set the height to auto, and visibility to visible.
CKE Editor Javascript adds inline styles for height on the toolbar, so you'll need the !important declaration on the height.
https://jsfiddle.net/ucytmjj5/4/
span.cke_top,
span.cke_bottom {
visibility: hidden;
height: 0px !important;
}
div.cke:hover span.cke_top,
div.cke:hover span.cke_bottom {
visibility: visible;
height: auto !important;
}
You can instantiate a dummy editor on page onload or onclick. Keep dummy editor hidden using display: none. When your dummy editor is loaded, it will load all the assets and next time when you display the editor it won't reload the assets. Simple!
You could try showing the text area after CKEDITOR instance has been created. For example.
CKEDITOR.on('instanceCreated', function(evt) {
evt.editor.element.setStyle("display", "block");
});
CKEDITOR.replace('editor1');
#editor1 {
display: none;
}
<script src="https://cdn.ckeditor.com/4.7.3/standard/ckeditor.js"></script>
<textarea id="editor1"></textarea>
You could reuse the same instance of the editor every time, but replace the editor's text with the value of textarea that the user hovers over. That way the editor will only load once and be reused.
Try using CDN versions of the assets, if it fixes your problem then it may be a server issue.
If you are using assets from a server that doesn't have cache policies or policies that don't let the browser cache, the browser may be downloading these files more than once.
Related
I am writing a free online e-book which needs a few minor formatting tweaks:
http://rperl.org/learning_rperl.html
The "Full Table Of Contents" at the very top of the page starts out by being visible for a few seconds, then finally collapses itself to be hidden. What we need is for it to start as hidden, and not be visible at all for the several seconds while the page loads. You can see that I have already tried to solve this issue by setting "var index_hidden=1;" at the following link, otherwise the table of contents would never hide itself at all:
https://github.com/wbraswell/rperl/blob/gh-pages/javascripts/metacpan_rperl.js#L832-L833
It probably shouldn't matter, but I'm using some custom Perl scripts to generate this file from Perl POD source, I can give more info if needed.
Although the described behavior does not appear for me (OSX + Firefox). Here's what you might do:
Hide the element by default using CSS. Add this to your head element (extend with stronger hiding CSS when needed).
<style>.wait-for-js { display: none; }</style>
And hide your element by adding the class
<div id="index-container" class="hide-index wait-for-js">
Last but not least, to make this trick functional. Remove the class as soon as JS is loaded, which would also mean that other logic has been loaded and you're save to show the table of contents. Be sure to load this JavaScript last thing you'll do.
<script>
document.getElementById('index-container').className = 'hide-index';
</script>
Or if you're using jQuery
<script>$('.wait-for-js').removeClass('wait-for-js');</script>
Welcome to SO!
The closest thing I can find to what I'm trying to do on SO is this, but sounds like this is not a workable solution anymore and it is not specific to iFrames anyway:
Click through a DIV to underlying elements
Basically I have a DIV that gets added to a page that contains an iFrame. The iFrame contents can be minimized so they don't always take up all the space of the iFrame. The iFrame is transparent so that you can still see the web page behind it. I need to be able to click on the elements in the web page behind it, but have had no luck so far.
They have a roughly 400x400 iFrame but when the contents in it are minimized, you can still click on the web page behind it. I tried doing something similar but can't get it to work.
Even in the transparent regions I cannot click on the page behind it. I also tried using pointer-events:none as mentioned in other posts but this does not help. It only disables the elements in the iFrame but has no affect on being able to click through it.
Do anyone know how to achieve this? A way to have a larger iFrame, where the contents in it can be minimized and you can still click on what's behind the iFrame?
UPDATE:
It would appear that this is not possible when using frames.
Have you tried pointer-events: none?
http://robertnyman.com/2010/03/22/css-pointer-events-to-allow-clicks-on-underlying-elements/
Strategy 1: iFrame Resizer
If you're able to get scripts into both the host page and the page contained within the iFrame, you can use Bradshaw's iFrame Resizer JS.
It will dynamically resize your iFrame to fit its content. Works cross-domain.
The use cases for it include:
You are authoring both the host page, and the iFrame page.
You are authoring either the host page or the iFrame page, and are collaborating with the author of the other page.
I can't tell if your use case meets either of those criteria.
Strategy 2: Overlapping iFrames
Using JQuery, you can toggle the visibility of 2 (or n) iFrames which overlap completely or partially. You can load each iFrame with the same content, or different content. When any iFrame is invisible, you can click through it to the content behind it, whether that's another iFrame, or anything else.
In your application, you would be sizing the 2 iFrames differently: iFrame1="full size", iFrame2="minimized."
In my application (below), the 2 iFrames mostly overlap and have the same content, but I was padding them differently and shifting their position slightly, depending on whether something else on the page was present or absent. I'm also resizing both iFrames dynamically to fit their content using iFrame Resizer (above), but that might not be required for your application.
I recommend using different border colors for your iFrames (below), while you fiddle with their position and size.
I only learned JS like, 5 mins ago, so, my apologies if I've misunderstood your question.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
// This is the Bradshaw resizer script. Required iff you need dynamic resizing.
<script src="[https://MyiFramehost.com/web/embed/js/inline.js]"/></script>
<div id="padded" style="width:100%" >
<iframe id="oos_inline" style="border:solid;border-color:green;width:100%;position:relative;padding:65px 0px 0px 0px;top:-65px;"></iframe>
</div>
<div id="normal"style="width:100%;" >
<iframe id="oos_inline_padded" style="border:solid;border-color:blue;width:100%;position:relative;padding:0px 0px 0px 0px;"></iframe>
</div>
<script>
var iframe_padded = document.getElementById("oos_inline_padded");
var iframe = document.getElementById("oos_inline");
if(document.getElementById("home-page")!=null){
iframe.src = "https://the_embedded_site.com";
$(iframe).show();
$(iframe_padded).hide();
} else {
iframe_padded.src = "https://the_embedded_site.com";
$(iframe).hide();
$(iframe_padded).show();
}
// This starts dynamic resizing. Required iff you need dynamic resizing.
iFrameResize({log:true})
</script>
I think you missed:
myDiv.style.opacity = "0";
myDiv.style.filter = "alpha(opacity=0)"; /* For IE8 and earlier */
BTW, use a CSS class instead of applying CSS via JS. Let me know how it goes.
I want to prevent an specific background-image being displayed on a page, possibly using jquery. However, the page and DOM is loaded before the JS is activated.
What I want to do is the following:
.pagelayout-login #page{
background: none;
}
I have tried the same in JQuery using:
$(document).ready(function(){
$(".pagelayout-login #page").css("background","none");
});
However, both modify the stylesheet after the image has been loaded and displayed.
If I add "run_at : "document_start" inside my content scripts, the CSS get's overridden by the page's CSS.
Is there a way to prevent the background from being displayed before it starts loading?
you can add the CSS at the beginning :
chrome.tabs.insertCSS(tab.id, {code:'my css code', allFrames:false, runAt:"document_start"});
or add a script at the end like this :
chrome.tabs.executeScript(tab.id, {code:'my script code', allFrames:false, runAt:"document_end"});
with the CSS, you need to be the first, because it's a "Cascading Style".
with the script, it must be the last change.
You can try to add !important to your CSS.
I'd think this would be a lot easier the moment you remove the $(document).ready, everything inside that function runs after the page has completed loading.
Since this is in a Chrome extension, don't be afraid to use !important to ensure that your CSS overrides the page's CSS even if you "run_at : "document_start":
.pagelayout-login #page{
background: none !important;
}
This may or may not prevent the image from loading since it's still being referenced by the page's CSS, but it will at least prevent it from displaying right away. You will need to conduct your own tests to determine if Chrome will still attempt to request the image during page load in spite of this.
I am using the Google Webfont Loader to get my webfonts loaded with a callback and it is working fine.
Although, when a couple of components: Google +1 button, Twitter Search Widget and the Add This button is loaded, they add a new stylesheet to the DOM and makes the browser render the site again. This is causing the font-face to disappear and then show for each new stylesheet added to the dom.
I could hide the font entirely until the components are loaded but they tend to be pretty slow so that would leave me with a pretty bad user experience. About 1 sec of a headline-less site.
Andy tips on how to force font-face to not redraw or how to block dynamically loaded CSS from within Google, Twitter and FBs embed scripts?
Update: Demo here http://kristoferforsell.com/dev/fontexample/
This is currently an inherent issue with browsers and the #font-face property. The blink occurs when the font is loaded and the page updates to reflect the font. If you wish to remove the "blink" entirely, the only sure fire way is to include the font as a data URI in the style sheet. Of course, using the standard "safe" fonts will also remove the blink.
Data URIs allow you to actually embed the code for the font in the stylesheet so there's no blink when the page refreshes to show the desired font. Using data URIs, will obviously increase the file size (kb) of any style sheet.
An online converter to get base64 code can be found here
Usage for #font-face would be like so.....
#font-face {
font-family: "My Font";
src: url("data:font/opentype;base64,[ the base64 code here ]");
}
Not sure if it would fix your issue but you could use css to set the visibility of the elements to hidden until the font is loaded. Google's API provides wf-loading and wf-active classes which are added to the body to address this issue.
I always set up a separate stylesheet just for the #font-face rule, and within that put in the following rules, where replace is the class of the element that's being replaced, for you that would just be the p tag.
.wf-loading .replace { visibility: hidden;}
Yours would be
.wf-loading p { visibility: hidden;}
Then as soon as the webfont is loaded, JS puts the wf-active class on the body, and your text shows up. Let me know how that goes and if you have any issues then just drop me a line. It might also be worth doing some searching for "flash of unstyled content" or "flash of unstyled text" as this is a well known and well documented bug.
I can suggest a simple and dirty trick I have used myself to solve issues like this. If you implement this, from the user's side the effect will be that the entire page will load at once (with the correct Web Fonts), but after a delay. Once loaded, nothing will flicker or change.
Wrap your entire page contents in a div and set its visibility to hidden. Then use js to turn on the visibility once the whole page (stylesheets and all) is loaded.
Here's the code:
<head>
<script>
function show()
{document.getElementById('wrapper').style.visibility='visible';}
</script>
</head>
<body onload="show()">
<div id="wrapper">
...your entire page contents...
</div>
</body>
The onload ensures that the visibility is switched on only after the entire body has loaded. Although I haven't used Web Fonts, I use this trick to fade in the entire contents of this website with no changing or updating afterwards. But yes, there will be a delay before the entire page comes into view.
EDIT: I added Google Web Fonts to the site I linked. Still works fine. No font-face flickering.
This is a shot in the dark, as I've not tested it:
Could you create another html page with only those social networking buttons, and then load that into an iframe? Then only set the src to the iframe once the document is fully loaded, so it doesn't hold anything up.
In html:
<iframe id="socialMedia"></iframe>
In script:
$(document).ready(function() {
$('#socialMedia').src = "http://mysite.com/mysocialmediastrip.html";
});
Where mysocialmediastrip.html contains all the social media buttons. Setting the src will cause that iframe to reload and pull in that content, but IIRC, the rest of the page will be left alone -- all of the button rendering will have been done in mysocialmediastrip.html, not in your main page.
I totally understand what you are saying about the delay process, waiting while window loads before you actually show your goods. Abhranil provided a good solution but you can take his solution further. You can use jQuery's ajax to load your specific page content that's using the special font type. Why? because ajax comes with a special function called beforeSend(). Within the beforeSend function(), you can load a very cool gift animation that will display on your screen, before your main content is ready to viewed.
Use that moment to show some creativity towards your audience, before the main event!
The best and most simple answer is adding font-display: block when specifying a font face
#font-face {
font-display: block; /* Fix flickering */
}
You should also preload the font in the html file
<head>
<link rel="preload" as="font" href="/path_to_your_font.ttf">
<-- repeat for all typeface -->
</head>
The problem is, on most sites on the web, there are background images. They take time to load. Ordinarily, it wouldn't be a problem if the images were optimized, and small enough. However, on some of my sites, the javascript files find their way to load before anything else on the page, even though they're in the footer! This creates a white "flash" before the background image loads. Why is my javascript loading first before anything else? I'm having this problem on many sites, and I see it everywhere. Here's the site I'm currently working on:
http://www.bridgecitymedical.com/wordpress/
Thanks!
tl;dr How can I defer loading of javascript on my websites so that the background image loads before anything else, thus preventing that white "flash" before the browser finishes downloading the image.
Don't delay loading parts of your site - what if the background image were to have an error in transmission and never arrive? Your scripts would never load.
Instead, if you really dislike the "white" flash, set the background color of the document to a more pleasing color, more in line with your background image. You can do so in the same css style:
body {
background: #EDEBED url(myGrayBackgroundImage.jpg);
}
It's simple, has virtually no cost, won't break, and won't delay things from downloading unnecessarily. It looks like you're already doing something like this - I wouldn't change it. I don't think anybody has the expectation that your site look a certain way before it loads.
You may use something like this:
HTML
<!-- Add a class to flag when the page is fully loaded -->
<body onload="document.body.classList.add('loaded')">
CSS
/* Hide slider image until page is fully loaded*/
body:not(.loaded) #slider img {
display:none;
}
I was having the same issue and found it pretty strange that this isn't talked about more. I still haven't found any documentation on this, but please comment if you find anything regarding RFC's for css background image loading priorities, etc.
Anyways, the only thing I found is that <img> load immediately while background-image() seems to load on dom ready.
So my solution was to place a <img> with display:none just before the <div> with the background image. This will load the image immediately and then it gets used immediately for the background-image.
<img src="my-image.jpg" style="display: none;" />
<div style="background-image: url('my-image.jpg');"></div>
One thing to note is that you could still get flickering on images that are not optimized. So for jpg's make sure to compress them and set the "progressive" attribute when creating them.
I wanted to add something, in case of having a black background image set for the body. I was experimenting with transitions in between pages in the same site. I finally used this (neatly loads black-background from black, avoiding the flash yeah!):
html{
background-color: black;
}
body{
-webkit-animation: fadein 1.5s; //I use chrome
background: linear-gradient( rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.75) ), url('wall_pattern.jpg');
color: white;
}
So, while changing the background color does help it's important to note that the reason the page is not loading quickly is likely due to javascript being in the header. You can remedy this by putting your javascript tags
<script type="text/javascript" src="/path/to/js/javascript.js"></script>
in the footer of your pages so that it loads after the browser has already read the css and displayed most of the page. I realize this is an old post, but I happened upon it while thinking about this problem myself and realized (through remembering conversations and posts I'd seen before) that I had the js in my header.
If you change the render time it should stop people from getting flash banged by your page loading white.
I would use a query string "?201611" on the image URL in css.
This tells the browser which version of the image to load. So instead of checking for new version every time, it will load the version kept in cache. The flash effect will happens only the first time the website is visited.
ex. http://domain.com/100x100.jpg?201611