Clean the CSS that was added while loading Ajax content - javascript

I am appending an HTML document into my current page using Ajax, and removing those added divs when the close button is pressed. The problem is that when I close, the divs are removed from the document but the CSS <link rel="stylesheet" href="style.css"> are not removed, and the number keep increasing as I load and unload Ajax content. How to completely remove the loaded document with the header content (css, js) of that page?
edit: i dont know why people dont want to answer but they just come to negative voting.
this is the code that i have used to add(append the html document)
$(function(){
$("a[rel='tab']").click(function(e){
pageurl = $(this).attr('href');
$.get(pageurl, function(html) {
$(html).hide().appendTo('body').fadeIn(500);
}, 'html');
//to change the browser URL to the given link location
if(pageurl!=window.location){
window.history.pushState({path:pageurl},'',pageurl);
}
//stop refreshing to the page given in
return false;
});
});
and this code to remove the divs
function close(){
$("#mainContent").fadeOut(500, function() { $(this).remove(); });
window.history.back();
} ;

I can't see the document that you are attempting to add/remove, but I'm guessing it looks something like this:
<link rel="stylesheet" href="style.css">
<div id="main-content">
<p>Blah blah blah</p>
</div>
So when you add that content, the whole thing is inserted. When you remove it, you are only removing the div#main-content. To remove everything, two ideas come to mind:
Preferably, wrap the document in another <div> and remove that instead
Alternatively, you could select <link> elements that are siblings of the 'div#main-content`, but that has the potential to be more unpredictable.
If the document you are adding doesn't look like that, then please explain in the OP what it does look like and where the <link> elements are coming from.
If you are doing something like a HTML preview in another page, look into creating an iframe instead. Use AJAX to create a temporary URL as the source. The advantage is that you avoid conflicts that occur when you effectively merge two DOMs.

Related

javascript not affecting a div

I'm trying to build an FAQ page and wish to have the user click a question and only then an answer will side down under the question.
I have code that will work this when I put it all on one page. However I wish to use a div to load various files (the FAQ div is only one of a few files I wish to add into the div). So when I use the div and an 'window onload event' the div loads but all questions and answers are fully opened and exposed.
The script to dropdown answers, placed in the HEAD section of the MainPage.html also a call to jQuery.
<script type="text/javascript">
$(document).ready(function() {
$('#faqs h1').each(function() {
var tis = $(this), state = false, answer = tis.next('div').hide().css('height','auto').slideUp();
tis.click(function() {
state = !state;
answer.slideToggle(state);
tis.toggleClass('active',state);
});
});
});
</script>
The FAQ.html
<div id="faqs">
<h1>+ Question</h1>
<div>
<p><br>Answer Here</p>
</div><br>
<h1>+ Question</h1>
<div>
<p><br>Answer Here</p>
</div><br>
</div>
The script to load the div, placed in the HEAD section of the MainPage.html
<script>
window.onload = function(){
$('#target').load('FAQ.html');
}
</script>
The div, placed in the BODY section of the MainPage
<div id="target"></div>
I have tried placing the javascript in various place on the page but still the same result. Repeat: If I place the code of FAQ.html directly in the BODY section of the MainPage it all works properly.
I have researched this also under 'conflicting jQuery' but with no success. Suggestions appreciated please.
It looks a lot like $(document).ready is run before $('#target').load finishes.
To avoid that, take the entire function you pass to $(document).ready and pass it as a last argument to $('#target').load instead, so that it gets called when loading of FAQ.html has completed:
window.onload = function(){
$('#target').load('FAQ.html', function() {
$('#faqs h1').each(function() {
var tis = $(this), state = false, answer = tis.next('div').hide().css('height','auto').slideUp();
tis.click(function() {
state = !state;
answer.slideToggle(state);
tis.toggleClass('active',state);
});
});
});
}
I assume it's because of the
$(document).ready()
callback. You're specifying a function to happen when the DOM is loaded, but by the time you've loaded in the faq.hmtl file, that's already happened. See what happens if you remove the first and last lines inside your script tags.
Also, unrelated, you're using <h1> tags incorrectly. You should only have one <h1> tag per page, as a rule. The <dl> tag is probably the most semantically meaningful in this situation.

Solving page reload in HTML5 histroy

I have a problem with my code , iam using Html 5 history and its work fine in getting contents and changing url but when i refresh the page its show only the content without full page with css and here my code :
<script type="text/javascript">
$(function() {
$('.menuAnchor').click(function(e) {
href = $(this).attr("href");
loadContent(href);
// HISTORY.PUSHSTATE
history.pushState('', 'New URL: '+href, href);
e.preventDefault();
});
// THIS EVENT MAKES SURE THAT THE BACK/FORWARD BUTTONS WORK AS WELL
window.onpopstate = function(event) {
console.log("pathname: "+location.pathname);
loadContent(location.pathname);
};
});
function loadContent(url){
// USES JQUERY TO LOAD THE CONTENT
$.get(url, {}, function (data) {
$(".contn_btm_mid_bg").html(data);
//$.validator.unobtrusive.parse(".contn_btm_mid_bg");
});
// THESE TWO LINES JUST MAKE SURE THAT THE NAV BAR REFLECTS THE CURRENT URL
$('li').removeClass('current');
$('a[href="'+url+'"]').parent().addClass('current');
}
</script>
I use history.js to change my URL using ajax and it works fine for me. Your CSS shouldn't really change if you have it linked in your document. Are you overwriting it?
Declare your CSS in the head of the page that you're doing the ajax call on and on ajax load only update the DIV or whatever element with the contents of the ajax call. I do that with this plugin and it works great for me. My CSS is always there even on page refresh.
<html>
<head>
<link rel="stylesheet" type="text/css" href=" linktoyourfile.css" media="screen">
<!--js files etc -->
</head>
<body>
<div class="contn_btm_mid_bg"><!--ajax contents--></div>
</body>
</html>
EDIT:
Since I can't see your HTML or structure I will just tell you how I might do it based on your comment.
Don't call the whole page. Just call the div that contains the content you want to import via ajax. Not the whole page. Link the CSS on all your included pages in the header. Then use a DIV to hold the content, when you call that page, just call the id of the DIV not the entire page. example
Your other pages:
Then in your ajax call if your divs have the same class in all the pages you can do this below. Make sure you link your CSS in your other pages too.
function loadContent(url){
// USES JQUERY TO LOAD THE CONTENT
$.get(url, {}, function (data) {
$(".contn_btm_mid_bg").html($(data).find('.contn_btm_mid_bg').html());
//$.validator.unobtrusive.parse(".contn_btm_mid_bg");
});
// THESE TWO LINES JUST MAKE SURE THAT THE NAV BAR REFLECTS THE CURRENT URL
$('li').removeClass('current');
$('a[href="'+url+'"]').parent().addClass('current');
}

How to .load() just a specific div from a page into a a target div, not the whole page

I have the following script that loads a page into a div and not just the targeted div. This is most evident when going back to my index and my header and footer are jammed into the <div id="contentspace"></div>.
I read on here somewhere that the div needs to be placed in it's own page prior to being displayed. Not sure which method would do that. Is this possible without hashtags Thanks for your help
<script type="text/javascript">
$(function() {
$('#header a').click(function() {
$('#contentspace').empty();
$("#contentspace").load(this.href, function(response){
console.log($('#content', response).html())
event.preventDefault();
});
});
});
</script>
The method .load() can load page fragment, simply by specifying a valid jquery selector next to the url.
$('myelement').load('page.html #content', function() {
...
});
Note that when loading page fragments, jquery will remove any SCRIPT element it might contain.
In you example, you would do:
$("#contentspace").load(this.href + ' #content', function(response){
...
});
Did you read the documentation at all? Take a look at the section titled Loading page fragments in the jQuery API for .load(). Essentially you just pass a selector along with the URL of the page to load as the first argument of the method.

jQuery event that triggers after CSS is loaded?

I have a couple of links on my page (inside a <div id="theme-selector">) which allow you to change the CSS stylesheets:
$('#theme-selector a').click(function(){
var path = $(this).attr('href');
$('head link').remove();
$('head').append('<link type="text/css" href="'+path+'" rel="stylesheet" />');
return false;
});
Now, after I've changed the style on the page, I want to get the new background color, using the following code (which I put after the $('head').append call):
var bgcolor = $('body').css('background-color');
alert(bgcolor);
The problem is, I think, that it takes some time for the browser to download the new stylesheet and I sometimes get the old background color in my alert message. Is there some event I can bind that will only alert me after all the stylesheets are loaded on the page?
At the moment, all I can think of is using a setTimeout(function(){}, 5000); which isn't great, because what if it takes longer/shorter to load all the CSS on the page.
Let me know if I need to clarify anything and I can provide more code.
Rather than creating a new link element and appending it to the head, you could retrieve the contents of the stylesheet with an AJAX call, and insert it into an inline style block. That way, you can use jQuery's 'complete' callback to fire off your check.
$('#theme-selector a').click(function(){
var path = $(this).attr('href');
$.get(path, function(response){
//Check if the user theme element is in place - if not, create it.
if (!$('#userTheme').length) $('head').append('<style id="userTheme"></style>');
//populate the theme element with the new style (replace the old one if necessary)
$('#userTheme').text(response);
//Check whatever you want about the new style:
alert($('body').css('background-color'));
});
});
I haven't actually tested this code, so there may be some syntax-y errors, but the logic should be sound enough.
The load event can be watched for any element associated with a url, does this not work for you when loading the css stylesheet? http://api.jquery.com/load-event/
Try something like this:
var path = $(this).attr('href');
$('head link').remove();
var styleSheet = $('<link type="text/css" href="'+path+'" rel="stylesheet" />');
styleSheet.load(function(){alert("Loaded");});
$('head').append(styleSheet);
Edit: As pointed out below this only works in IE, who would have thought?
var cssLoaded = function()
{
alert($('body').css('background-color'));
};
$('#theme-selector a').click(function(){
var path = $(this).attr('href');
$('head link').remove();
$('head').append('<link onload="cssLoaded();" type="text/css" href="'+path+'" rel="stylesheet" />');
return false;
});
successfully tested in Chrome 28, IE 10, FF22
You could use lazyload (jQuery plugin) to load a css file.
It has the ability to call a function when the file is included.
Example:
// Load a CSS file and pass an argument to the callback function.
LazyLoad.css('foo.css', function (arg) {
// put your code here
});
Got here looking for a way to remove critical CSS ( element) after being 100% sure, that external sheets have lazyloaded and rendered. This would allow me to use universal, yet visually pleasing critical internal CSS globally over several projects.
Since some of the critical styles go visually against the lazyloaded ones, so they need to be overridden (too much work), or removed. This is what I want, in short:
Load the document with critical internal CSS
Lazyload the additional CSS after the document is rendered and interactive (good for SEO and UX)
Remove critical CSS from HTML after the fancy additional stylesheets have been loaded and truly rendered, to prevent flickering which occured with all other solutions (I have tested this a lot).
A 100% working solution (may it be unpopular) is to use setInterval(); after having the secondary css lazyloaded, to periodically check, whether a style, unique to secondary CSS has truly been applied. Then I can have the critical CSS removed (or whatever I want to do..).
I have created a live demo with comments on Codepen: https://codepen.io/Marko36/pen/YjzQzd and some info in a blogpost: Triggering a Javascript/jQuery event after CSS has loaded.
var CSSloadcheck = setInterval(function () {
if ($('body').css('opacity') != 1) {
//when opacity is set to 0.99 by external sheet
$('style#critical').remove();
clearInterval(CSSloadcheck);
}
}, 100);
You could simply keep on checking if the background colour is still the same, and then do your thing if ever it changes.
oldbackground=getbackground()
function checkbackground(){
if(oldbackground!=getbackground()){
oldbackground=getbackground()
//Do your thing
}
}
setInterval(checkbackground,100)

Same JQuery click function for numerous links

I have a page that has multiple links with various attributes (these attributes will be pulled in from a database):
index.php
<html>
<head>
<script type='text/javascript' src='header.js'></script>
</head>
<body>
My_Link_1
My_Link_2
<div id='my_container'> </div>
</body>
</html>
My header.js file has:
$(document).ready(function(){
$('.link_click').click(function(){
$("#my_container").load("classes/class.project.php", {proj: $(this).attr('id')} );
return false;
});
});
class.project.php is pretty simple:
<?php
echo "<div id='project_container'>project = ".$_POST['proj']." : end project</div>";
?>
This loads and passes the ID variable (which actually comes from a database) to class.project.php. It works fine for the first link click (either link will work). Once one link is clicked no other links with this div class will work. It feels like javascript loads the class.porject.php and it will not refresh it into that #my_container div.
I tried running this as suggested by peterpeiguo on the JQuery Fourm, with the alert box for testing wrapped inside .each:
Copy code
$(document).ready(function() {
$('.link_click').each(function() {
$(this).click(function() {
alert($(this).html());
});
});
});
This seems to work fine for the alert box. But when applying it to .load() it does not reload the page with the new passed variable. As a matter of fact, it doesn't even reload the current page. The link performs no function at that point.
The example site can be viewed here: http://nobletech.net/gl/
I looked at the link you posted, and the problem is that when you're doing load you're replacing the elements on the page with new ones, thus the event handlers don't work anymore.
What you really want to do is target the load. Something like:
$("#project_container").load("classes/class.project.php #project_container", {proj: $(this).attr('projid')} );
This only loads stuff into the proper container, leaving the links and other stuff intact.
Ideally, the php script should only return the stuff you need, not the whole page's markup.
BTW- Caching shouldn't be an issue in this case, since .load uses POST if parameters are passed. You only have to worry about ajax caching with GETs
Sounds like the request is getting cached to me.
Try this:
$.ajaxSetup ({
// Disable caching of AJAX responses */
cache: false
});
Sorry but this might be completely wrong but after examining your XHR response I saw that you are sending back html that replaces your existing elements.
So a quick fix would be to also send the following in your XHR response (your php script should output this also):
<script>
$('.link_click').each(function() {
$(this).click(function() {
alert($(this).html());
});
</script>

Categories

Resources