Script doesn't run after loaded a html file into a page - javascript

i have a problem with my page.
When i click on a link on my page, it will load a external html inside a div in the page. the div with the id="div1". (AJAX)
It works perfect.
the external html-page which has been loaded includes a div with the id="rex".
My Problem is:
i have a script, which must add content in the div (with the id="rex")
i wrote the script in the external file, but it doesn't run.
probably i must write my script in the page and not in the external html-file.
here the script Number 3:
$('#rex').ready(function() {
var url="genredetail.php";
var activitydetail = sessionStorage.activitydetail;
$.getJSON(url,function(json){
$.each(json.genredetail,function(i,item){
if(item.name == activitydetail){
$('<p class="excerpt">' + item.beschreibung3 + '</p>').appendTo('#rex');
}
});
});
});
This script must run when the external file (with the div id="rex") has been loaded. But it doesn't :-(
What can i do? Is the problem that the script runs before the page get the <div id="rex">?
Thanks in advance, and sorry my bad english :-S
A picture for more clearness
the script number 1 makes the link.
when i click on a link, the script number 2, let the site load in the div1.
The script number 3 must fill the div="rex" with informations. but it doesn't run.

try onload
$('div').on("load","#rex",function() {
do something
});

Try using setInterval, so it check the element rex every 0.5 s
var myInterval = setInterval(function(){
if ($("#rex").length)
{
var url="genredetail.php";
var activitydetail = sessionStorage.activitydetail;
$.getJSON(url,function(json){
$.each(json.genredetail,function(i,item){
if(item.name == activitydetail){
$('<p class="excerpt">' + item.beschreibung3 + '</p>').appendTo('#rex');
clearInterval(myInterval);
}
}, 500);

You need to reload the script if it is already loaded. As you said you are loading the external html inside a div, does it include the external js file you are using? if not please include it.

Related

Print function only works after second click

I have this function to print a DIV.
Whenever the page is loaded and I click in a "Print" link I have, the DIV is shown to be printed without CSS.
If I close Chrome's print visualization page and click in the "Print" link again, the DIV has CSS applied.
Any ideas why?
Javascript
function printDiv(divId) {
var printDivCSSpre =
'<link href="/static/assets/vendor/sb-admin-2-1.0.7/bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">' +
'<link href="/static/assets/vendor/sb-admin-2-1.0.7/dist/css/sb-admin-2.css" rel="stylesheet">' +
'<div style="width:1000px; padding-right:20px;">';
var printDivCSSpost = '</div>';
$('body').append('<iframe id="print_frame" name="print_frame" width="0" height="0" frameborder="0" src="about:blank"></iframe>');
$("link").clone().appendTo($("#print_frame").contents().find("head"));
window.frames["print_frame"].document.body.innerHTML =
printDivCSSpre + document.getElementById(divId).innerHTML + printDivCSSpost;
window.frames["print_frame"].window.focus();
var windowInstance = window.frames["print_frame"].window;
windowInstance.print();
}
HTML
<a id="print" href="#">
<i class="fa fa-print"></i> Print
</a>
<script>
$('#print').click(function () {
printDiv('report')
})
</script>
<div id="report" class="report">
<p># Generated Table#</p>
</div>
First click:
http://imgur.com/a/Go81Y
Closing the print preview page and clicking again in print
http://imgur.com/a/SCxJF
This happens because when you call your printDiv() function, css is also written using inner HTML and in this scenario CSS is not applied during first click because you wrote CSS to the elements even when they do not exist inside DIV.
The function to work as desired has to write DIV contents first and then CSS should be applied. I would say write css after contents of DIV or load on top of your HTML page and just write DIV contents.
Hope that helps.
Every thing is right just change the sequence. In browser debugger on first click it didn't show 'print_frame' in sources section while in second click it does (I am using chrome devtool).
So load in memory frame with css attributes during onload:
var windowInstance;
$(function(){
$('body').append('<iframe id="print_frame" name="print_frame" width="0" height="0" frameborder="0" src="about:blank"></iframe>');
$("link").clone().appendTo($("#print_frame").contents().find("head"));
windowInstance = window.frames["print_frame"].window;
});
and onClick just append html
$('#print').click(function () {
var divId = 'report';
var printDivCSSpre ='<div id="printReportDiv" style="width:1000px; padding-right:20px;">';
var printDivCSSpost = '</div>';
window.frames["print_frame"].document.body.innerHTML = printDivCSSpre + document.getElementById(divId).innerHTML + printDivCSSpost;
window.frames["print_frame"].window.focus();
windowInstance.print();
});
updated jsfiddle
Try this one. The problem mainly arises because the css has not been applied to the page when the print command is initiated. setTimeout is one way to solve it as others have mentioned but it is really not possible to predict how much delay you will need. Slow internet connections will require high delays before you fire the print statement. The following code, however, only fires the print event after the css has been properly applied to the iframe.
$('#print').click(function () {
if($("#print_frame").length == 0) {
$('#report').after('<iframe id="print_frame" name="print_frame" width="0" height="0" frameborder="0" src="about:blank"></iframe>');
}
var $head = $("#print_frame").contents().find("head");
// for now for ease I will just empty head
// ideally you would want to check if this is not empty
// append css only if empty
$head.empty();
$.ajax({
url : "https://dl.dropboxusercontent.com/u/7760475/reports.css",
dataType: "text",
success : function (reports) {
// grab css and apply its content to the iframe document
$head.append('<style>'+reports+'</style>');
$.ajax({
url : "https://dl.dropboxusercontent.com/u/7760475/bootstrap.css",
dataType: "text",
success : function (bootstrap) {
// grab another css and apply its content to the iframe document
// there may be better ways to load both css files at once but this works fine too
$head.append('<style>'+bootstrap+'</style>');
// css has been applied
// clone your div and print
var $body = $("#print_frame").contents().find('body');
// empty for ease
// but later append content only if empty
$body.empty();
$("#report").clone().appendTo($body);
$('#print_frame').get(0).contentWindow.print();
}
});
}
});
});
Use inline CSS instead.
Reason: When we PRINT or save as PDF if fails to fetch external css Files, So we have to use Inline css.
edited your file please see: jsfiddle.net/ytzcwykz/18/
As other people mentioned it is hard to see your problem without seeing the working example of a problem, but just guessing from the code:
Browser is not able to load the CSS before your print() call.
Browser is not able to render the CSS before your print() call.
Keeping that in mind changing your JS function that way might do the trick
function printDiv(divId) {
$("link").clone().appendTo($("#print_frame").contents().find("head"));
window.frames["print_frame"].document.body.innerHTML =
printDivCSSpre + document.getElementById(divId).innerHTML + printDivCSSpost;
window.frames["print_frame"].window.focus();
var windowInstance = window.frames["print_frame"].window;
setTimeout(function() {
windowInstance.print();
}, 0);
}
The idea behind this function is to let browser execute it's code after we added changed the HTML/CSS code in the window - see Why is setTimeout(fn, 0) sometimes useful?
WARNING: this approach is not tested for your particular problem, and it might also not work because we escape/leave the mouse-click call-stack, calling print() method might be not possible out of user-interaction stack.
UPDATE: after looking in the posted jsfiddle - my assumption was correct, the browser needs some time to load and render the CSS, that is why calling the print() right after changing iframe contents doesn't give the desired result. There are 3.5 ways to solve that:
Use events to identify when iframe's document and window has finished loading and rendering. I tried two approaches, and failed so far, need to read docs more carefully about when document and window are behiving during the loading sequence:
we can do that from outside of iframe, i.e. listen to events of iframe element and it's children
we can do that from inside of iframe, i.e. add little javascript snippet inside which will send a message to the parent window when loading is done.
Consider forming the print result different, how about print style-sheets? I.e. add one more style sheet with print-media query to the parent doc and just call print on it?
Consider forming an iframe which is already loaded and ready to be printed, but replace just the table contents inside it.
As others mentioned, The problem here is that the CSS files used are external resources and browser takes time to download and cache it locally. Once it is cached, it would serve faster and that's why it works fine from the second click.
As Anton mentioned, setTimeout is the key here! You may probably increase the timeout seconds to make that work. I tried setting it to 500ms and that worked,
setTimeout(function(){windowInstance.print();},500);

Run an java script after controller has been loaded in CodeIgniter

I'm creating a Java Script widget for the site based on CodeIgniter. The site using templates and Blade library. I need to load my java script right after the page has been loaded. I have added it into template scripts.blade.php:
<script src="{{apps_url('assets/my_widget/js/my_widget.js')}}"></script>
Unfortunately, it seems, what my script was executed before controller has been loaded and therefore the script can not find required SVG object:
(function() {
var container = d3.select(".myContainer");
alert("container: " + container);
})();
This alert show what container is null even if the myContainer object actually exists on the page and was recognized by CSS. The d3 library has been loaded properly and there is no errors in the Firefox console.
Is there a way to execute this script right after the object has been loaded?
use
$(document).ready(function() {
(function() {
var container = d3.select(".myContainer");
alert("container: " + container);
})();
});

Rerun Javascript in dynamically filled iframe

On a page i try to fill an empty <iframe id="myFrame"></iframe> with the HTML code of an ajax result. That works well, except script tags in the code are not being executet, so i have to readd them to the iframe's page:
$.post('page.php', function(code) {
$("#myFrame").contents().find("html").get(0).innerHTML = code;
$("#myFrame").contents().find("script").each(function() {
$old_script = $(this);
$frame = document.getElementById("myFrame");
$new_script = $frame.contentWindow.document.createElement("script");
$new_script.type = "text/javascript";
$new_script.src = $old_script.attr("src");
$old_script.remove();
$frame.contentWindow.document.head.appendChild($new_script);
});
});
That works basically, but the document seems to load the Javascript files in a different order. There are 3 js files to load: jquery.min.js, a jquery plugin and a main.js file to control the bahavior inside the iframe:
// main.js:
$(document).ready(function() {
alert("frame document loaded");
// call the jquery plugins etc...
});
The page alerts me "frame document loaded", but cannot execute the jquery plugins. Double-checked the script paths, but they're right. Seems that the jquery.min.js and main.js are loaded before the plugin files.
How could i achieve to load the javascript files one by one as specified originally in the code returned by the ajax request?
EDIT: Forgot to say that sometimes everything works well and the javascript seems to be loaded correctly. On reload it breaks again.

JavaScript not executing on Ajax loaded content (no jQuery)

I am having an issue where I am loading ajax HTML content into an element on my page using JavaScript, and trying to execute JavaScript within the loaded content, which is not working.
I am not (and cannot) use jQuery on this project.
The JavaScript I am using to load the ajax content look like:
var loadedobjects = "";
var rootDomain = "http://" + window.location.hostname;
function ajaxPage(url, containerId){
var pageRequest = false;
pageRequest = new XMLHttpRequest();
pageRequest.onreadystatechange = function(){
loadpage(pageRequest, containerId);
}
preventCache = (url.indexOf("?")!=-1)? "&"+new Date().getTime() : "?"+new Date().getTime();
pageRequest.open('GET', url+preventCache, true);
pageRequest.send(null);
}
function loadpage(pageRequest, containerId){
if (pageRequest.readyState == 4 && (pageRequest.status==200 || window.location.href.indexOf("http") == -1)){
document.getElementById(containerId).innerHTML = pageRequest.responseText;
}
}
As you can see, I am passing a URL (of an HTML page) to the function ajaxPage()
The ajaxPage() function is being called in a separate .js file, like so:
ajaxPage('test.html', 'ajax-wrapper');
Which is working, test.html is being loaded in the element with id 'ajax-wrapper', but no JavaScript in the test.html page is working.
Here is what the test.html page looks like (just plain HTML):
<div class="t-page-title">
View Thread
</div>
<script>
alert('hello');
</script>
Even a simple alert('hello'); on the loaded HTML is not firing. The page is not being cached, so that is not the issue. I would know what to do if I was using jQuery, but I am a bit stumped with finding a JavaScript only solution. Any suggestions?
When you use innerHTML, the tags get copied to the destination element, but scripts are not executed. You need an additional eval step to execute the scripts.
jQuery has a function for that called globalEval, without jQuery you'll need to write your own.
[Update] Here is a variation with an iframe that might help address your issue: http://jsfiddle.net/JCpgY/
In your case:
ifr.src="javascript:'"+pageRequest.responseText+"'";
The standard behavior with a div: http://jsfiddle.net/JCpgY/1/

How Can I Apply CSS to an iFrame Using OK_loadit Function?

I am attempting to apply CSS to a document that I'm loading into an iFrame. I am using the OK_loadit function as follows:
function OK_loadit(url,layerObjNS, width) {
if (document.layers){
document.layers[layerObjNS].load(url, width);
} else{
if (window.frames.length > -1){
window.frames[layerObjNS].location.href = url;
}
The document I am loading into the iFrame is a php Seresnipity blog page.
The blog page's CSS needs to be set to "background= #000000", so that it can be viewed from links in the RSS feed with a black background. That's already done.
But when the blog page is rendered in it's iFrame on my website (which is located on the same domain as the blog), it's CSS needs to be set to "background= transparent".
Is there any way to modify the OK_loadit script above in such a way that I can reset the background parameter of the page accordingly when it's loaded into the iFrame, or do I need to use a different script altogether?
Either way, I'd really appreciate it if someone here could hook me up with what I need.
Thanks!
James
[edit]
deleted previous answer
[/edit]
sorry, I re-read your question and realized that the solution is easier than I had thought.
in the url that you're passing to this page just add ?tran to the url string..
so...
"myPage.php?tran"
then in the php page add this...
<script>
document.onload = function(){
if(self.location.query.indexOf("?tran") == 0)
document.bgColor = "transparent"
}
</script>
I think that should work.

Categories

Resources