Div content loaded via ajax doesn't appear in IE - ajax

Here is the ajax call:
function loadContent( url ) {
jQuery.ajax({
url: url,
success: function(data)
{
// set content
jQuery("#overlayDiv").html(data);
// hide loading spinner
jQuery("#overlayCleared").hide();
}
});
}
It works fine in all the other browsers except IE, in which the div remains empty.. :(
The css I'm using is:
div#overlayDiv {
overflow: auto;
position: relative;
height: 95%;
}
div.video_overlay { /* this class will be added to the div using jQuery */
padding-left: 0px;
width: inherit;
top: 35px;
}
What can I do about it?
Many thanks

Actually, there's also the possibility that you ran into the IE Ajax caching problem, where IE tends to cache results from GET requests. See http://ajaxian.com/archives/ajax-ie-caching-issue.
Solution is to use POST (Note: jquery defaults to GET)

i ran into the same issue a couple of days ago and i simply made this change and it fixed the problem.
(*Considering the url points to localhost)
ensure that your url points to 127.0.0.1 when testing on ie e.g;
use ------> http://127.0.0.1/
instead of ----> http://localhost/

I just solved this very same issue for a big HTML5 application that required IE8 compatibility. The HTML returned by the Ajax calls is quite complex and includes SCRIPT tags with lots of JQuery and standalone JavaScript code.
Apart from the well known IE caching problem (and some others), the key of this kind of issue resides on IE being extremely picky at the time of letting dinamic HTML content be loaded into any element, in my case it was a DIV. Not only is IE picky but shows a sort of random behaviour like rendering a part of the returned HTML or nothing at all without any apparent relationship between the partially rendered HTML and the finally discovered coding issue.
On top of that it throws no HTML coding errors at all making it a real nigthmare to debug this kind of scenarios. In my case I had no choice but recurring to the 90's debugging techniques. I took the returned HTML code from Chrome by copying the node code in the inspection view of this browser, put it into a flat .html file and used this server side code to read the code from the flat file.
$myfile = fopen("flatfile.html", "r") or die("Unable to open the file");
echo fread($myfile,filesize("flatfile.html"));
fclose($myfile);
From then on use the returned code and input it into the container object, start by dividing it into two (letting each part be a coherent piece of code on its own), see what part of the two is rendered and what not and so on with each part until you find the offending piece of code.
One important thing to note is IE8 will work no matter how complex de mix of HTML and Javascript is, you just have to painfully debug your code. If I say so it is becouse you will find many posts stating that IE7,8 cannot handle complex Ajax returned code or that JQuery's .html() property won't work in such cases. It's not true, take your time and you'll find where your issue is, do not give up.

Related

Single page application with Rails 4 and AngularJS

Ok, this idea might seem quite a bit crazy and it kindo' is (at least for me at my level).
I have a fairly standarad rails app (some content pages, a blog, a news block, some authentication). And I want to make it into a single page app.
What I want to accomplish is:
All the pages are fetched through AJAX like when using turbolinks, except that the AJAX returns only the view part (the yield part in the layout) withought the layout itself, which stays the same (less data in the responces, quicker render and load time).
The pages are mostly just static html with AngularJS markup so not much to process.
All the actual data is loaded separately through JSON and populated in the view.
Also the url and the page title get changed accordingly.
I've been thinking about this concept for quite a while and I just can't seem to come up with a solution. At this point I've got to some ideas on how this actualy might be done along with some problems I can't pass. Any ideas or solutions are greatly appreciated. Or might be I've just gone crazy and 3 small requests to load a page are worse then I big that needs all the rendering done on server side.
So, here's my idea and known problems.
When user first visits the app, the view template with angular markup is rendered regularly and the second request comes from the Angular Resource.
Then on ngClick on any link that adress is sent to ngInclude of the content wrapper.
How do I bind that onClick on any link and how can I exclude certain links from that bind (e.g. links to external authentication services)?
How do I tell the server not to render the layout if the request is comming from Angular? I though about adding a parameter to the request, but there might be a better idea.
When ngInclude gets the requested template, it fires the ngInit functions of the controllers (usually a single one) in that template and gets the data from the server as JSON (along with the proper page title).
Angular populates the template with the received data, sets the browser url to the url of the link and sets the page title to what it just got.
How do I change the page title and the page url? The title can be changed using jQuery, but is there a way through Angular itself?
Again, I keep thinking about some kind of animation to make this change more fancy.
Profit!
So. What do you guys think?
OK, in case enyone ever finds this idea worth thinking about.
The key can be solved as follows.
Server-side decision of whether to render the view or not.
Use a param in the ngInclude and set the layout: false in the controller if that param is present.
Have not found an easier way.
Client-side binding all links except those that have a particular class no-ajax
Here's a directive that does it.
App.directive('allClicks', function($parse) {
return {
restrict: 'A',
transclude: true,
replace: true,
link: function(scope, element, attrs) {
var $a = element.find('a').not($('a.no-ajax')),
fn = $parse(attrs['allLinks']);
$a.on('click', function(event) {
event.preventDefault();
scope.$apply(function() {
var $this = angular.element(event.target);
fn(scope, {
$event: event,
$href: $this.attr('href'),
$link: $this
});
});
});
}
};
})
And then use it on some wrapper div or body tag like <body ng-controller="WrapperCtrl" all-links="ajaxLink($href)"> and then in your content div do <div id="content" ng-include="current_page_template">
In your angular controller set the current_page template to the document.URL and implement that ajaxLink function.
$scope.ajaxLink = function(path) {
$scope.current_page_template = path+"?nolayout=true";
}
And then when you get your JSON with your data from the server don't forget to use history.pushState to set the url line and document.title = to setr the title.

How to retrieve images (decoded if possible) present in a wepage using XPCOM

How to get all the images, after decoding if possible, on a webpage through XPCOM ?
The image might be specified in HTML as a background url in some CSS property, inside img tag, or in any form that a web developer might have included.
I tried looking into imgIContainer, imgIDecodeObserver and many other interfaces. Although there is a way through which we can provide image URI to Mozilla so that it loads the image, decodes it and returns imgIContainer. But I couldn't find anyway to get all images in current webpage.
This has to be done in either Java or Javascript.
Any suggestions?
#Wladimir - Thanks for your help.
I want all the images including CSS constructs (background images). So now I am listening to events from nsIWebProgressListener.
onStateChange: function(webProgress, request, stateFlags, status) {
if ((~stateFlags & (nsIWebProgressListener.STATE_IS_REQUEST | nsIWebProgressListener.STATE_STOP)) == 0) {
var imgReq = request.QueryInterface(CI.imgIRequest);
if (imgReq)
var img = imgReq.image;
}
}
The problem is that request.QueryInterface(CI.imgIRequest) throws exception for all NON-image requests. Although those exceptions can be ignored by putting code inside try-catch block, but I'd prefer to do things cleanly.
Is there any condition that can be checked to know whether request is for image or not?
There is existing code that you can look at. The Page Info dialog has a Media tab that successfully shows most images on the page. The important function is grabAll() in pageInfo.js, it is called for each element (via a TreeWalker). As you can see, there is no generic way to get the image, this function rather uses window.getComputedStyle() to extract the values of a bunch of the CSS properties for this element: background-image, border-image, list-style-image, cursor. It will also look for <img>, <svg:image>, <link> (favicon), <input>, <button>, <object> and <embed> tags. It doesn't manage to recognize everything however, e.g. these CSS constructs will not be recognized:
.foo:before
{
content: url(image.png);
}
.foo:hover
{
background-image: url(image.png);
}
Still, this is probably as far as you can get - unless you want to look at the requests made by the web page as it loads.
Edit: If you look at the requests as they are performed (via a web progress listener), you can do the following:
if (request instanceof CI.imgIRequest)
var img = request.URI.spec;
Note that request.image won't help you much, almost all methods of imgIContainer are only accessible from native code.

loading colorbox from within AJAX content

Firstly I am very new to all forms of javascript, particularly anything remotely AJAX. That said, over the course of the last day I have managed to code a script that dynamically refreshes a single div and replaces it with the contents of a div on another page.
The problem however is that several of my other scripts do not work in the ajax refreshed content. The most important of which being "colorbox".
I have spent several hours this evening researching this and am seeing lot's of stuff regarding .load, .live... updating the DOM on refresh etc...etc... But to be quite honest most of it is going over my head currently and I wouldn't know where to begin in terms of integrating it with the code I currently have.
My Ajax refresh code is as follows (My apologies if I haven't used best practice, it was my first attempt):-
$(function() {
$(".artist li.artist").removeClass("artist").addClass("current_page_item");
$("#rightcolumnwrapper").append("<img src='http://www.mywebsite.com/wp-content/images/ajax-loader.gif' id='ajax-loader' style='position:absolute;top:400px;left:190px;right:0px;margin-left:auto;margin-right:auto;width:100px;' />");
var $rightcolumn = $("#rightcolumn"),
siteURL = "http://" + top.location.host.toString(),
hash = window.location.hash,
$ajaxSpinner = $("#ajax-loader"),
$el, $allLinks = $("a");
$ajaxSpinner.hide();
$('a:urlInternal').live('click', function(e) {
$el = $(this);
if ((!$el.hasClass("comment-reply-link")) && ($el.attr("id") != 'cancel-comment-reply-link')) {
var path = $(this).attr('href').replace(siteURL, '');
$.address.value(path);
$(".current_page_item").removeClass("current_page_item");
$allLinks.removeClass("current_link");
$el.addClass("current_link").parent().addClass("current_page_item");
return false;
}
e.preventDefault();
});
$.address.change(function(event) {
$ajaxSpinner.fadeIn();
$rightcolumn.animate({ opacity: "0.1" })
.load(siteURL + event.value + ' #rightcolumn', function() {
$ajaxSpinner.fadeOut();
$rightcolumn.animate({ opacity: "1" });
});
});});
I was hoping someone might be kind enough to show me the sort of modifications I would need to make to the above code in order to have the colorbox load when the contents of #rightcolumn have been refreshed.
There is also a second part to this question. My links to the pictures themselves are now also being effected by the hashtag due to the above code which will in turn prevent the images themselves from loading correctly in the colorbox I should imagine. How can I prevent these images from being effected and just have them keep the standard URL. I only want the above code to effect my internal navigation links if at all possible.
Many thanks guys. I look forward to your replies.
That's a lot of code to review so I'll focus first on the conceptual side of things. Maybe that you will give you some clues...
It sounds like when you load content via Ajax the DOM is changed. No worries, that's kind of what we expect. However, scripts loaded before the Ajax calls may have difficulty if they are bound to elements that weren't there at page load time or are no longer there.
JQuery's live function is one solution to that. Instead of binding to a specific element (or collection of elements) at particular point in time, live lets you specify a binding to an element (or collection) of elements without regard to when they show up in the DOM (if ever).
ColorBox, however, in its default "vanilla" use abstracts that all away and, I believe, uses classic DOM binding - meaning the elements must be present at bind time. (Since you don't show your call to ColorBox I can't see how your using it.)
You may want to consider re-initalizing ColorBox after each content load by Ajax to be certain the binding happens the way you need it to.
Use $('selector').delegate() it watches the DOM of 'selector' and .live() is deprecated.
Use this to watch your elements AND fire the colorbox initilization. This way the colorbox is not dependent on the DOM element, but the other way around.
$("body").delegate("a[rel='lightbox']", "click", function (event) {
event.preventDefault();
$.colorbox({href: $(this).attr("href"),
transition: "fade",
innerHeight: '515px',
innerWidth: '579px',
overlayClose: true,
iframe: true,
opacity: 0.3});});
This should basically solve your problem and is cross browser tested.
The a[rel='lightbox'] in the delegate closure is the reference to what ever link you're clicking to fire the colorbox, whether it has been loaded with the initial DOM or with an AJAX request and has been added to the DOM in a live fashion. ie: any tag like this:
<a rel='lightbox' href="http://some.website.com">Launch Colorbox</a>

onclick does not fire in first Item in GalleryView 1.1

So I have a page using GalleryView 1.1 here. I like the behaviors just fine except that the left-most item's onclick event won't fire for some reason.
I also grabbed the 2.1 version from the GoogleCode page; the author's page at http://spaceforaname.com/ has gone. So here is a page implementing 2.1.
Since 2.1 has a bunch of behaviors I hate and seems to completely prevent my onclick events I would like to sort out the issue with the left-most item's onclick in the v1 page.
I have read through the code but failed to find what is interfering.
The function looks like this:
$('.myslides').click(function() {
//alert($(this).attr('alt'));
$('#big_pic').attr("src", $(this).attr('alt'));
return false;
});
and the items like this
<li><img src='g/weddings/slides/1.jpg' width='165' height='110' alt='/g/weddings/slides/1_big.jpg' class='myslides'/></li>
I have tried moving the class attribute to the LI, and also adding an anchor around the image and giving it the class but neither of these had a visible effect.
// Edit
The page validates and yes I know the big pics are blurry. Don't have them from GD so did best I could stretching thumbs.
Does anyone have an idea of how I should pursue debugging this?
So when inspecting the elements in question I found that the working thumbnails were all image elements but the non working first thumbnail was a div with id "pointer".
Since the author's site with the docs has evaporated I can say what function #pointer has in my filmstrip slides but in jquery.galleryview-1.1.js on line 319 I changed its width to 1px in the JS CSS and this resolved the issue of the obstructed onclick. #pointer may have a function I am not employing here. At any rate the issue is resolved.
Width was previously set to
'width':opts.frame_width-pointer_width+'px',
Now set to
pointer.attr('id','pointer').appendTo(j_gallery).css({
'position':'absolute',
'zIndex':'1000',
'cursor':'pointer',
'top':getPos(j_frames[0]).top-(pointer_width/2)+'px',
'left':getPos(j_frames[0]).left-(pointer_width/2)+'px',
'height':opts.frame_height-pointer_width+'px',
'1px',
'border':(has_panels?pointer_width+'px solid '+(opts.nav_theme=='dark'?'black':'white'):'none')
});
Also tried adding display:none but this resulted in jerky animation.

Is there a way to AJAX load a page and change URL in URL bar without hashing?

This is probably going to get a resounding no, but I am wondering if it possible to have the URl change dynamically with using hashing, and without invoking a http request from the browser?
My client is keen on using AJAX for main navigation. This is fine, when the end user goes to the front page first, but when they want to use the deep linking, despite it working, it forces an extra load time as the page loads the front page, then invokes the AJAX from the hash.
UPDATE: Could it be possible, given that what I want to avoid is the page reload (the reason is that it looks bad) to stem the reload by catching the hash with PHP before the headers are sent, and redirecting before the page load. This way only one page loads, and the redirect is all but invisible to the user. Not sure how to do this, but seems like it is possible?
Yes, this is possible. I often do this to store state in the hash part of the URL. The result is that the page doesn't reload, but if the user does reload, they're taken to the right page.
Using this method, the URL will look like: "/index#page=home" or "/index#page=about"
You'll need to write a JavaScript function that handles navigation, and you'll need a containing div that gets rewritten with the contents fetched from AJAX.
Home
About
Questions
<div id="content"></div>
<script type="text/javascript">
function link(page) {
location.hash = "page="+page;
loadPage(page);
}
// NOTE: This is using MooTools. Use the AJAX method in whatever
// JavaScript framework you're using.
function loadPage(page) {
new Request.HTML({
url: "/ajax/"+page+".html",
onSuccess: function(tree, elements, html) {
document.id('content').setProperty('html', html);
}
}).get();
}
</script>
Now, you'll also need to have something that checks the hash on page load to load the right content initially. Again, this is using MooTools, but use whatever onLoad method your JavaScript framework provides.
<script type="text/javascript">
document.addEvent('domready', function() {
parts = location.hash.split('=');
loadPage(parts[1]);
}
</script>
Ok, the problem is that opening an AJAX link of the form http://example.com/#xyz results in a full page being downloaded to the browser, and then the AJAX-altered content is changed once the page has loaded and checked the hash part of its URL. The user has a diconcerting experience.
You can hugely improve this by making a page that just contains the static elements - menus, etc. - and a loading GIF in the content area. This page checks its URL upon loading and dynamically fetches the content specified by the hash part. The page can have any URL you want; we'll use http://example.com/a. Links to this page (http://example.com/a#xyz) now provide a good user experience for users with scripting enabled.
However, new users won't come to the site by fetching http://example.com/a; they'll fetch http://example.com. This is fine - serve the full page, including the home page content and links that don't require scripting to work (e.g., http://example.com/xyz). A script run on loading this page should alter the href of AJAXable links to their AJAX form (http://example.com/a#xyz); thus the first link a user clicks on will result in a full page load but subsequent ones won't.
The only remaining problem is is a no-script user gets sent an AJAX link. You can add a noscript block to the AJAX page that contains a message explaining the problem and provides a link back to the homepage; you could include instructions on how to enable scripting or even how to modify the link by removing a# and pressing enter.
It's not a great answer, but you can offer a different link in the page itself; e.g., if the address bar shows /#xyz you include a link to /xyz somewhere in the page. You could also add a link or button that uses script to bookmark the page, which would again use the non-AJAX form of the link.

Resources