I am calling the parent function like window.parent.functionname(); from the child page. How can i call the window.child.function() from the parent page to child page.
Any help is appreciated.
Give your iFrame an id and try
document.getElementById("iFrameId").contentWindow.functionname()
This works even when you have multiple iFrames in the same page irrespective of their order.
Do you have an iframe?
Do something like that:
window.frames[0].contentDocument.functionname();
Parent page
var windowRef = null;
function openChildWindow() {
if ((windowRef != null) && (windowRef.closed == false)) {
if (windowRef.closed == false) windowRef.close();
windowRef = null;
}
var windowUrl = 'ChildPage.aspx';
var windowId = 'NewWindow_' + new Date().getTime();
var windowFeatures = 'channelmode=no,directories=no,fullscreen=no,' + 'location=no,dependent=yes,menubar=no,resizable=no,scrollbars=yes,' + 'status=no,toolbar=no,titlebar=no,' + 'left=0,top=0,width=400px,height=200px';
windowRef = window.open(windowUrl, windowId, windowFeatures);
windowRef.focus();
// Need to call on a delay to allow
// the child window to fully load...
window.setTimeout(callChildWindowFunction(), 1000);
}
function callChildWindowFunction() {
if ((windowRef != null) && (windowRef.closed == false)) windowRef.childWindowFunction();
}
Child Page
function childWindowFunction() {
alert('Hello from childWindowFunction()');
}
var win = null;
function openAndCall(id){
if (win!=null && win.closed==false){
win.close();
}
win = window.open("/somePage");
win.onload = function(){
win.callSome(id);
};
}
Related
I have a published captivate html file that is loaded into an iframe of another html. I cannot communicate between the two, not even with localStorage. Can anyone tell me what I'm missing?
Parent html
var everythingLoaded = setInterval(function () {
if (/loaded|complete/.test(document.readyState)) {
clearInterval(everythingLoaded);
init();
}
}, 10);
function init() {
ScormProcessInitialize();
var studentID = ScormProcessGetValue("cmi.core.student_id");
var student_name = ScormProcessGetValue ("cmi.core.student_name");
var nameArraya = student_name.split(" ");
var nameArrayb = nameArraya[1].split(",");
var studentNumber = nameArrayb[0];
ScormProcessSetValue("cmi.core.lesson_status", "incomplete");
localStorage.setItem("_studentNumber", studentNumber);
alert("Student Number: " + studentNumber + " Student Mame: " + student_name);
setTimeout(function () {
document.getElementById("iFrame_a").innerHTML = "<iframe name='iframe_1' id='frame_1' src='//somepath.com/sandbox/somecourse/index.html' frameborder='0' width='1000px' height='605px'></iframe>";
}, 250);
}
function sendComplete() {
alert("Send from index start!");
ScormProcessSetValue("cmi.core.lesson_status", "completed");
alert("send status: Completed");
}
window.onbeforeunload = function (){
cpInfoCurrentSlide = localStorage.getItem("_cpInfoCurrentSlide")
alert(cpInfoCurrentSlide);
if(cpInfoCurrentSlide >= 40)
{
alert("onbeforeunload called: " + cpInfoCurrentSlide )
ScormProcessSetValue("cmi.core.lesson_status", "completed");
}
}
iframe code snippet
localStorage.setItem("_cpInfoCurrentSlide", cpInfoCurrentSlide);
I believe your problem is with onbeforeunload. As I remember captivate packages clobber any functions associated with onbeforeunload in the parent frame when they load.
Try this instead, override your SCORM api setvalue method:
var oldLMSSetValue = window.API.LMSSetValue;
window.API.LMSSetValue = function(key, value){
if(key === 'cmi.core.lesson_status' && value === 'completed'){
//do your stuff here
cpInfoCurrentSlide = localStorage.getItem("_cpInfoCurrentSlide")
alert(cpInfoCurrentSlide);
}
//call the original scorm api function so that it runs as expected.
oldLMSSetValue(key,value);
};
edit: this code would go in the parent window, not the iframe.
I have this javascript code attached that puts some content into a popup window and then tries to print it:
$(".print_friendly_popup").click(function() {
var target = $(this).data('print-target');
var left = (screen.width/2)-(500/2);
var top = (screen.height/2)-(500/2);
var win = window.open("", "test", "width=500,height=500 top=" + top + ", left=" + left);
if(target == 'review') {
win.document.write($('#print_friendly_review').html());
} else if(target == 'essay') {
win.document.write($('#print_friendly_essay').html());
}
win.print();
win.close();
});
The problem is sometimes the call to win.document.write takes too long and the window tries to print a blank screen. How do I wait for window.document to be written to before firing print?
So how about this: create some sort of "checker" to see if the window has the content in it, for example:
var checkForContent = function () {
setTimeout(function () {
var content = win.document.querySelector('body').innerHTML
if (content.length) {
win.print()
win.close()
} else {
checkForContent()
}
}, 200)
}
This way you're politely waiting for the content to render before printing.
Try
win.onload = function(e){
//..... your codes
}
I'm currently working on counting the number of opened tabs on my application. but my problem is it seems that my script won't detect events onload. Here is my code.
I'm using HTML5 web storage and native js. I'm not using jQuery to understand more on native js.
(function(w) {
function Tabz(win, key) {
this.name = '';
this.storageKey = key;
if(win.name != '')
this.name = win.name;
else {
var windowArr = JSON.parse(localStorage.getItem(key)) || [];
this.name = "tabz_"+ windowArr.length;
win.name = this.name;
windowArr.push(this.name);
localStorage.setItem(this.storageKey, JSON.stringify(windowArr) );
}
}
Tabz.prototype.getStorage = function() {
return localStorage.getItem(this.storageKey);
}
Tabz.prototype.removeWindow = function() {
//remove window function here
}
var newWindow = new Tabz(w, 'counter');
window.load = function() {
var count = JSON.parse(newWindow.getStorage()).length;
alert(count!); // this wont execute so that I can check the count.
}
})(window);
Your issue is on this line:
window.load = function() {
This will add a load property to the window, not add an event listener. I think you are looking for onload.
window.onload = function() {
Incidentally, using event properties is considered bad-practice. Using addEventListener would be better.
window.addEventListener("load", function(){
//Do stuff...
});
I am using the ajaxify.js plugin https://github.com/browserstate/ajaxify to load content dynamically.
I have a number of click functions that I bind on document ready, but have to additionally put those functions inside of my ajax load function to re-bind the click events to the newly added content. I had tried using a single set of live functions previously but they didn't work.
Anyway I have the following code twice, once inside of a document.ready(function(){ }) and once again inside of ajaxify.js after the content loads.
I know it's superfluous, but I'm not sure of how to go about writing the functions just once so I can "include" them elsewhere. How can I optimize these functions so I can consolidate them and use them over again in an efficient manner?
Thank you!
var $filterclear = $('.filters .filter-clear'),
filtercount = $filterclear.length,
$searchedfor = $('.searched-for'),
is_search = $searchedfor.length;
$filterclear.bind('click', function(){
var $me = $(this);
if(filtercount == 3) {
$('.clear-all.filter-clear').addClass('filter-out').fadeOut('fast');
$(this).addClass('filter-out').fadeOut('fast');
} else {
$(this).addClass('filter-out').fadeOut('fast');
}
if($me.hasClass('clear-all') || filtercount == 1) {
$filterclear.addClass('filter-out').fadeOut('fast');
if(is_search !== 0) {
$('.filters').fadeOut();
}
}
});
$('.tag.remove-term').bind('click', function(){
var $me = $(this),
mytext = $me.text(),
$myfilter = $('.filters .filter-clear:contains("'+ mytext +'")');
if(filtercount == 3) {
$('.clear-all.filter-clear').addClass('filter-out').fadeOut('fast');
$myfilter.addClass('filter-out').fadeOut('fast');
} else {
$myfilter.addClass('filter-out').fadeOut('fast');
}
});
$searchedfor.find('.filter-clear').bind('click',function(){
$searchedfor.fadeOut();
});
Defining a new function should work (I didn't test it):
var $filterclear = $('.filters .filter-clear'),
filtercount = $filterclear.length,
$searchedfor = $('.searched-for'),
is_search = $searchedfor.length;
var doSomething($myfilter) {
if(filtercount == 3) {
$('.clear-all.filter-clear').addClass('filter-out').fadeOut('fast');
}
$myfilter.addClass('filter-out').fadeOut('fast');
};
$filterclear.bind('click', function() {
var $me = $(this);
doSomething($me);
if($me.hasClass('clear-all') || filtercount == 1) {
$filterclear.addClass('filter-out').fadeOut('fast');
if(is_search !== 0) {
$('.filters').fadeOut();
}
}
});
$('.tag.remove-term').bind('click', function(){
var $me = $(this),
mytext = $me.text(),
$myfilter = $('.filters .filter-clear:contains("'+ mytext +'")');
doSomething($me);
});
$searchedfor.find('.filter-clear').bind('click',function(){
$searchedfor.fadeOut();
});
This code is being used on a Chrome Extension.
When I call the "showOrHideYT()" function, I get a
"Uncaught ReferenceError: showOrHideYT is not defined | (anonymous
function) | onclick"
This code will search for youtube links in a page, and it will add a button (it's really a div with an event) next to the link to show the iframe with the embedded video, pretty much like Reddit Enhancement Suite. Consider the code, per se, incomplete. I just want to know what am i missing when i call the "showOrHideYT(frameZES12345)" function.
if needed, i can provide manifest.json.
Thanks
function showOrHideYT(id)
{
var YTvidWidth = 420;
var YTvidHeight = 315;
frameYT=getElementById(id);
console.log(frameYT.style.visibility);
if (frameYT.style.visibility == "hidden")
{
frameYT.style.width = YTvidWidth+"px";
frameYT.style.height = YTvidHeight+"px";
frameYT.style.visibility = "visible";
}
if (frameYT.style.visibility == "visible")
{
frameYT.style.width = "0px";
frameYT.style.height = "0px";
frameYT.style.visibility = "hidden";
}
};
// DOM utility functions
function insertAfter( referenceNode, newNode ) {
if ((typeof(referenceNode) == 'undefined') || (referenceNode == null)) {
console.log(arguments.callee.caller);
} else if ((typeof(referenceNode.parentNode) != 'undefined') && (typeof(referenceNode.nextSibling) != 'undefined')) {
if (referenceNode.parentNode == null) {
console.log(arguments.callee.caller);
} else {
referenceNode.parentNode.insertBefore( newNode, referenceNode.nextSibling );
}
}
};
function createElementWithID(elementType, id, classname) {
obj = document.createElement(elementType);
if (id != null) {
obj.setAttribute('id', id);
}
if ((typeof(classname) != 'undefined') && (classname != '')) {
obj.setAttribute('class', classname);
}
return obj;
};
///////////////////////////////////////
$(document).ready(function() {
var vidWidth = 420;
var vidHeight = 315;
var linksSemID = document.getElementsByTagName("a") ;
for (var i = 0; i < linksSemID.length; i++){
if (/id=$/.test(linksSemID[i].href)) links[i].href += "1";
}
i=0;
var youTubeRegExp = /(?:v=)([\w\-]+)/g;
var forEach = Array.prototype.forEach;
var linkArray = document.getElementsByTagName('a');
forEach.call(linkArray, function(link){
linkArray.id="zes" + i++;
var linkTarget = link.getAttribute('href');
if (linkTarget!=null)
{
if (linkTarget.search(youTubeRegExp) !=-1)
{
console.log (linkTarget);
idVideo=linkTarget.match(/(?:v=)([\w\-]+)/g);
//idVideo = idVideo.replace("v=", "");
//add buton
botaoMais = document.createElement('DIV');
botaoMais.setAttribute('class','expando-button collapsed video');
botaoMais.setAttribute('onclick','showOrHideYT(frameZES'+ i +')');
insertAfter(link, botaoMais);
//add iframe
ifrm = document.createElement('IFRAME');
ifrm.setAttribute('src', 'http://www.youtube.com/embed/'+ idVideo);
ifrm.style.width = '0px';
ifrm.style.height = '0px';
ifrm.style.frameborder='0px';
ifrm.style.visibility = 'hidden';
ifrm.setAttribute('id', 'frameZES' + i);
insertAfter(link, ifrm);
}
}
});
});
When you use setAttribute with a string, the event will be executed in the context of the page. The functions which are defined in a Content script are executed in a sandboxed scope. So, you have to pass a function reference, instead of a string:
Replace:
botaoMais.setAttribute('onclick','showOrHideYT(frameZES'+ i +')');
With:
botaoMais.addEventListener('click', (function(i) {
return function() {
showOrHideYT("frameZES"+ i);
};
})(i));
Explanation of code:
(function(i) { ..})(i) is used to preserve the value of i for each event.
Inside this self-invoking function, another function is returned, used as an event listener to click.
I see that you are using jQuery in your code. I personally think if we are using a library like jQuery, then we should not mix the native javascript code and jQuery code.
You can use jQuery bind to bind your the functions you need to call on dom ready.
Read below to know more.
suppose you want to call a javascript function on a button click, Here is the HTML for the same.
<div id="clickme">
<input id= "clickmebutton" type="button" value = "clickme" />
</div>
suppose "test" is the function you need to call, here is the code for test function.
function test() {
alert("hello");
}
you now need to bind the test function on the button click.
$(document).ready(function() {
$("#clickmebutton").bind("click", function(){
// do what ever you want to do here
test();
});
});