In our web app, I'm trying to hit our server to determine if they have made any custom CSS tweaks to the layout of the web app. Upon getting a boolean flag of this, I'm returning the CSS from the server and injecting a new head link after the last one...
The problem is, this isn't updating the page's style or layout. If I go into the sources of the page elements and click on that CSS document in the dev console, I can force it to "notice" that this css is available by simply changing the value of a style reference.
This is the jquery I'm using to inject the CSS:
$("head link[rel='stylesheet']").last().after("<link rel='stylesheet' href='4DACTION/WEB_Mobile_CustomCSS' type='text/css' media='screen'>");
Any idea why it wouldn't force the page to use it until I've made a change to it in the debugger?
I used Bootstrap to create an example doing exactly what you described using your code in a setTimeout callback:
setTimeout(function () {
$("head link[rel='stylesheet']").last().after("<link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css' type='text/css' media='screen'>");
}, 1000);
check it out: http://jsfiddle.net/v089p29a/ it switches from flat buttons to 3D ones.
I'm not sure why this is not working for you. Maybe your URL is not valid like adeneo suggested. Also be sure to put your code in the $(window).load() or $(document).ready() event handlers to ensure that the DOM is ready to be manipulated.
Related
I have two routes/views in my AngularJS application that are using conflicting CSS. I have two separate external stylesheets that I want to use for these routes. For example foo.css for foo route and bar.css for bar route. That way I can resolve the conflict.
However, I will have to load bar.css and unload foo.css when navigating from foo to bar.
How do I do this? Is there a library/module that can help me to achieve this scenario?
I've looked into ocLazyLoad, but I'm not sure how to unload the loaded CSS.
AngularJS Way
In a comment below, the OP suggested the way that seems most appropriate to me in AngularJS - using the ng-disabled directive. You just have to make <html> your ng-app attribute element so that the directive gets properly executed.
<link rel="stylesheet" href="/path/to/style-1.css" ng-disabled="theme.name === 'theme1'">
<link rel="stylesheet" href="/path/to/style-2.css" ng-disabled="theme.name === 'theme2'">
This way both styles get loaded immediately (causing no flicker on change later). Different approach would be needed if some of the styles should not be loaded initially.
Original Answer
See this question. Then just find the appropriate <link> tags and enable/disable them at will. I don't think this has anything to do with AngularJS.
I am looking for a way to modify some text inside the HTML before it is being parsed by the browser.
More precisely, I would like to remove some tags from the HTML so the image resources would not be fetched by the browser, only when I am ready I could insert these tag back to have them loaded.
Is it possible to do that via some JS/Jquery or CSS, if so, how?
the motivation here is to be able to block the loading of some resources on a page and have them loaded only when needed according to some logic. this needs to be done by some kind of scripting added to the page
Because you're doing this in JavaScript the HTML is already being processed when it comes to launch your <script> tags.
You could move your <script> tags into the <head> from the <body>, or move it to the very beginning of the body. However the problem here is that you'll have to wait for your elements to actually be created in the DOM before you can work with them.
You could use something like setTimeout() or similar and continually look for them until you find them, but there's still going to be a slight delay between them being created and your script finding them, at which point they might already start to load.
The only surefire way is to process the markup server side long before it gets to the browser.
My answer here possibly could be of use, if you can place noscript tags in key places in your markup prior to parsing/evaluation:
Client-Side Dynamic Removal of <script> Tags in <head>
This method—for javascript-enabled agents—would delay the rendering of the entire page however, or at least the regions that you needed to affect.
basic generalised theory
Wrapper your body or specific region with a noscript tag identified with either a class or id. Place some javascript to execute directly after the close noscript that grabs the tag and reads the html contents as a string. At this point you could modify the html string however you like and then re-inject it back into the DOM replacing the noscript tag.
more specific implementation
If you know before-hand which resources you need to postpone—say all your images—you could wrap each image in-question with a noscript tag. Then trigger off some JavaScript that grabs all noscripts and rewrites the contained image html to use a placeholder or lower quality version of the image. At the same time you could set up event listeners or timeouts that inject the actual images when the time is right.
The Lazy Load Plugin for jQuery is maybe what you are looking for. It delays loading of images in long web pages.
You can use any jQuery event such as click or mouseover. You can also use your own custom events such as foobar. Default is to wait until user scrolls down and image appears on the window.
Beside all the It is also possible to delay loading of images. Following code waits for page to finish loading (not only HTML but also any visible images). Five seconds after page is finished images are loaded automatically.
$(function() {
$("img:below-the-fold").lazyload({
event : "sporty"
});
});
$(window).bind("load", function() {
var timeout = setTimeout(function() {
$("img.lazy").trigger("sporty");
}, 5000);
});
Check the delayed loading demo.
I have written a Firefox extension which alters the look and feel of Facebook. For this I used JS code to inject CSS styles to override FB defined values. But for some url patterns I don't want to force my styles. The issue here is the FB doesn't seem to load the full page but parts of page (but somehow the url in address changes).
This means when the new page loads my old styles will still remain applied and I want to restore them to their original values. How should I do that?
You should inject all your custom CSS styles into one <style> element, and then remove this <style> element (using JavaScript) when a new page is loaded on which you don't want your custom CSS.
Here's an example using jQuery: http://jsfiddle.net/thirtydot/BAPZF/
The problem is simple, but can't figure out a solution. Many thanks for those who helps.
I want to modify a web page (DOM tree) before it is displayed on screen.
I understand that the DOM tree is fully loaded in memory before being processed.
Do any of you knows a way to process this fully loaded DOM tree while it is on memory
and then let it be displayed with its new structure ?
The reason i want to do that, is because i'm working on an addon that is adding content to an existing web site.
added-> Just need to mention that the existing web site is not mine, so i can't use php to modify the website content is not mine.
But right now, the web site is displayed without the addon content
and you see the content coming after 1 second (because i append the content after website is already displayed), so you see the website content moving.
Thanks for helping.
It's not very difficult. Just hide the body using CSS and on the onload-event of the document do your manipulation and show the body.
Short example:
<html>
<head>
<title>example</title>
<style type="text/css">
<!--
html.scripted body{display:none;}
-->
</style>
<script type="text/javascript">
<!--
//set class for html-element, so the css-rule above will be applied to the body
document.getElementsByTagName('html')[0].className='scripted';
//on page load
window.onload=function()
{
//do the manipulation
document.body.appendChild(document.createElement('em')).appendChild(document.createTextNode('dynamic content'));
alert('manipulation done');
//show the body
document.body.style.display='block';
}
//-->
</script>
</head>
<body>
static content
</body>
</html>
In regard to Brad's comment below you may consider if there may be other ways. As the real issue seems to be the moving content, it could be possible to place a static placeholder where the dynamic content will appear later.
You mention PHP in your tags, so why not build your document server-side? Then, it doesn't matter.
If you must do this client side, then I also wouldn't worry about this. Web pages are rendered progressively anyway. Maybe you have a fast computer and a quick connection to your servers, but I guarantee you that most of your users do not.
Just add some code to the bit where the DOM is ready to make your page enhancements. Relevant: Javascript DOM ready without an entire framework
The only way to manipulate the DOM before it's loaded is by using a pre-processor like php.
Javascript can only manipulate the DOM after it's loaded.
For any further help beyond that you would have to provide a more specific example :-)
I finally found a solution.
I make the addon looking at web page navigation. In fact, it looks at url changes so that I know the user is moving to a different location (therefore I know I have to do something before I even got the 'Load' event of the web page).
Then I just try to access an element (that I know will be in the DOM, like the header) using a loop. Then when the element appears (before the 'Load' event) I insert the code and stop looping/listening.
If anyone need more details of how it is all done, I'll gladly answer your question.
Thanks.
I have a few dynamic pages and I want to alter certain elements before the page has fully rendered.
My snippet is something like:
document.body.getElementById("change").innerHTML = "<img src...";
I do not have access to change the content server side.
Where is the best place to put the snippet to have the code run before the page it has rendered?
Rather, is putting the Javascript in either the HEAD (inside the window.onload event?) or before the closing BODY (not inside an event listener) optimal?
I'm afraid you are highly unlikely to be able to execute your script before the page renders. Sure you can place an inline script and have it use document.write(...) at the place you'd like it to display your content, but this is a horrible solution. Orherwise the best you can do is at the 'DOM Ready' event, although it's difficult to do on all browsers consistently, you really need a library to abstract the details. jQuery provides it's ready method to fire an event when the DOM is ready, rather than when the page and all resources are finished loading.
Since the browser usually renders elements immediately after they have been parsed the best way would be do place the code in a script element directly after the referenced element:
<div id="change"></div>
<script type="text/javascript">
document.body.getElementById("change").innerHTML = "<img src...";
</script>
Not sure I understand your problem correctly, but if you use an event listener inside the head (such as jQuery's $(document).ready()), you will be able to alter the element once the dom structure has been loaded by passing your snippet to the function (handler) being called when the event fires.
<HEAD>
//...
<SCRIPT type="text/javascript">
$(document).ready(function() {
$("#change").append(
$("<img src=\"...\">")
) ;
}) ;
<SCRIPT>
</HEAD>
Using core javascript you will have to fork your event listeners for mozilla (W3C) and internet explorer event specifications. There's loads of documentation on how to do that on the internet.
Either way the best thing to do in this case obviously would be to create the content yourself, not altering it post rendering.
AFAIK you cannot do this. Because before a page is rendered there won't be any element and you can't access elements that haven't been loaded to the DOM tree.
If you do not want to render any elements before you make the DOM changes, you could set CSS display: none on the body element and then change it to display: block once you're done.