I'm trying what should have been a simple operation: when a user clicks a link a modal window pops up that's populated with some appropriate data in a string. Here's the HTML for the window:
<!DOCTYPE HTML>
<html>
<head>
<title>Modal Display Window</title>
</head>
<body>
<div id="modal_display_block">REPLACE THIS</div>
</body>
</html>
And this is the Javascript function that calls and populates the window:
function displayCenterBlock(data) {
DispWin = window.open("modal_window.html", "", 'toolbar=no,status=no,width=300,height=300');
DispWin.onload = function() {
DispWin.document.getElementById('modal_display_block').innerHTML = data;
}
}
This works great in every browser I've tried except Internet Explorer. In IE the innerHTML does not get rewritten by the data. Is there some IE-specific trick or tweak I need to apply to get this working in that browser?
Many thanks in advance!
ON EDIT: I've discovered that if I move the element rewrite line out of the onload function it then works fine in IE but not in other browsers. It appears my options are to use some conditional code to rewrite at once for IE and to wait for page load for all other browsers, or to abandon the rewrite element approach and just use a document.write. I get from forum searches people like to discourage document.write but that's looking pretty appealing right now.
Okay, for better or worse this code achieves the goal and appears to work cross browser, even in IE.
DispWin = window.open("", "Display", 'toolbar=no,status=no,width=300,height=300');
DispWin.document.open();
DispWin.document.write(data);
DispWin.document.close();
DispWin.focus();
I get that document.write can re-write the whole page, and that is sometimes bad, but in this case that is exactly what I want: a single small page displaying only what was passed in the data argument. I can style it inline.
Related
I am trying to get the targeted element with the pseudo-class :target after document load.
I created the following example to illustrate the problem.
<!DOCTYPE html>
<html>
<head>
<script>
document.addEventListener("DOMContentLoaded",function(){
console.log(document.querySelector(":target"));
});
</script>
</head>
<body>
<div id="test"></div>
</body>
</html>
If I load test.html, then the console outputs :
null
If I load test.html#test on Chrome and Opera, then the console outputs :
null
If I load test.html#test on Firefox and IE11, then the console outputs :
<div id="test"></div>
My questions are :
Which browsers have the correct behaviour ?
Does DOMContentLoaded is the correct event to call querySelector(":target") ?
Is there another way to get targeted element after document load ?
PS : I succeeded to fix the problem on Chrome and Opera thanks to setTimeout but It is not a good solution. Does someone has a better idea ?
EDIT : I found a similar issue with JQuery Selecting :target on document.ready()
This is a known issue with WebKit- and Blink-based browsers that has never been directly addressed. The workaround suggested by web-platform-tests is to request an animation frame, which only happens after page rendering, at which point the :target pseudo seems to match successfully:
async_test(function() {
var frame = document.createElement("iframe");
var self = this;
frame.onload = function() {
// :target doesn't work before a page rendering on some browsers. We run
// tests after an animation frame because it may be later than the first
// page rendering.
requestAnimationFrame(self.step_func_done(init.bind(self, frame)));
};
frame.src = "ParentNode-querySelector-All-content.xht#target";
document.body.appendChild(frame);
})
My testing shows that simply using onload works fine, but the author may be on to something and besides, a single call to requestAnimationFrame() costs practically nothing, so you may as well follow suit.
The following test uses onload (as opposed to DOMContentLoaded, which fires immediately after the DOM tree has been constructed but not necessarily rendered):
data:text/html,<!DOCTYPE html><script>window.onload=function(){console.log(document.querySelector(":target"));};</script><div id="test"></div>#test
The following test uses requestAnimationFrame() in conjunction with onload:
data:text/html,<!DOCTYPE html><script>window.onload=requestAnimationFrame(function(){console.log(document.querySelector(":target"));});</script><div id="test"></div>#test
It looks like Firefox has the ideal behaviour, though maybe not the correct one.
Nevertheless, as an alternative, you can use:
document.addEventListener('DOMContentLoaded', () => document.querySelector(window.location.hash));
and that will work in all browsers.
Is it possible to see all javascript function calls as a tree in any web debugger?
UPDATE
I mean debugger could remember each function call, from which other function it was done, also it could remember stack frame per each call and entire DOM snapshot.
UPDATE 2
The following page code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Trace and log all javascript functions calling tree/graph?</title>
<script type="text/javascript">
function init() {
setDiv2("This div text was changed once");
setDiv2("This div text was changed twice");
};
function setDiv2(text) {
document.getElementById("div2").innerHTML = text;
}
window.onload = init;
</script>
</head>
<body>
<h1>Trace and log all javascript functions calling tree/graph?</h1>
<p>Stack Overflow Question #20910262</p>
<div id="div1">This div will not changed</div>
<div id="div2">This div text will change</div>
<div>
<h2>The call graph should be follows</h2>
</div>
</body>
</html>
Should give the following call graph
because setDiv2() function called twice.
In profiler's top-down view it is visible as
where setDiv2() function drawn once. This is good for profiling, but this is not call graph.
So the question persists.
UPDATE 3
Moreover, users should be able to step on each tree node and see the values of all variables and the state of entire DOM tree at the moment, represented by the node.
Your need is obviously a custom profiler. Chrome JS profiler is a good handy tool. but i don't think that is correct tool for you. Also among the others Firebug or Safari profiler (webkits) won't do the job for you. So you need to develop your own custom profiler. since the others are only interested/targeted with CPU time profiling or memory usage profiling or CSS selectors.
You can modify Object.prototype.constructor. so all the global functions you have defined can have special profile method. or borrowed method via Function.prototype.bind() you can populate all the data you need from executions into a special data object. which can be like in a tree hierarchy. Here is the places to start a custom profiler.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function
and
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
Let us know if you can complete a custom profiler for javascript. it will be really useful tool for more people including me.
Yes, of course. Every browser has support to debug javascript code. You need to read about in specific browser you use. For example you can open developer tools in Mozilla Firefox by clicking Ctrl+Shift+K. In Internet Explorer you need to click F12 key. For Google Chrome Ctrl+Shift+I. After openning tools, you need to set up breakpoint at which you want to see stack trace, local variables and etc. After setting breakpoint you need to reload web-page, because when page is loaded all js is executed first time, and you can catch after loading, or make some event for catch breakpoint.
try console.trace() in your setDiv2 function , in this case you will see the both tree calls in chrome console.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Trace and log all javascript functions calling tree/graph?</title>
<script type="text/javascript">
function init() {
setDiv2("This div text was changed once");
setDiv2("This div text was changed twice");
};
function setDiv2(text) {
document.getElementById("div2").innerHTML = text;
console.trace()
}
window.onload = init;
</script>
</head>
.....
As usual, I want to alert users to unsaved changes when leaving a page. I have this test page:
<html>
<head>
<title>Testing</title>
<script language="JavaScript1.1" src="https://127.0.0.1:8443/scripts/base.js"></script>
<script language="JavaScript1.1" src="https://127.0.0.1:8443/scripts/edit.js"></script>
<script language="JavaScript1.1">window.onbeforeupload=moveAway</script>
</head>
<body onLoad="init()">
Google
</body>
</html>
The moveAway function is defined in "edit.js" like this:
function moveAway ()
return "foo";<br>
}
The event doesn't fire, or at least it just leaves the page silently (using IE8, Firefox 15, and Chrome 20). I've tried breakpointing the function in Firebug and it never gets to the breakpoint. I've tried it from the web server (an SSL server, the test version of which runs at 127.0.0.1:8443) and I've tried opening the file directly with the browser (which is why I used absolute URLs for the first two <script> tags). I've tried removing the "src=" attribute from the script tags.
On the other hand, this page has an example which does work (at least in Firefox):
https://web.archive.org/web/20211028110528/http://www.4guysfromrolla.com/demos/OnBeforeUnloadDemo1.htm
There is also a very similar example at MSDN which also works:
http://msdn.microsoft.com/en-us/library/ms536907%28VS.85%29.aspx
I really can't see the difference between what they do and what I'm doing. can anyone tell me why their code works and mine doesn't?
use jQuery bind function.. it works great for me..
see bellow
$(window).bind('beforeunload', function() {
return "Want to leave?";
});
onbeforeupload , really ? it should be onbeforeunload. Is that a spelling mistake, or is that how your actual code is ?
You have a syntax error, the function should be:
function moveAway () {
return "foo";
}
I am having problems passing javascript values between frames in chrome. In other browsers (Opera and Firefox) it works. The first frame contains the following html:
<script> variable="frame 1 value";</script>
click here
and test.html is:
<html>
<head>
<script>window.onload = function() {
div = document.getElementById("fred");
div.innerHTML="<b>" + top.frames[0].variable + "</b>";
}
</script>
</head>
<body>
<div id="fred">
hi there</div>
</body>
</html>
I have looked on this site and others, and the have seen a suggestion that because chrome pages run in different processes they cannot pass values. Is this true, and if so is there a way around it (cookies?)
Thanks,
russell
(edited) I just found another answer which says this happens only on file protocol. Like the writer of the other question, I am writing an applicaiton meant to be run off a cd, so I need to use file protocol. The version of Chrome I am using is 9.0.
ry
This has something to do with cross-site scripting which may be a security issue. Since Chrome has a very strict behavior on this, it should be impossible to achieve what you want.
Fortunately, there may be a nifty trick that you can use (if your variable is only a string):
Change the link in the first frame to test.html?foo=bar
Read window.location.href in the second frame. This will yield something like "Z:\folder\test.html?foo=bar". Now you can use string manipulation functions to extract the value of foo (in case: bar) from the href.
HTML5 Storage to the rescue! For the first frame:
<script>localStorage.setItem('variable', 'frame 1 value');</script>
click here
And for test.html:
<html><head>
<script>
window.onload = function() {
div = document.getElementById("fred");
div.innerHTML="<b>" + localStorage.getItem('variable') + "</b>";
}
</script>
</head><body>
<div id="fred">hi there</div>
</body></html>
A note of caution: IE7 and some older browsers do not support localStorage. However, you should be able to use if (typeof(localStorage) == 'undefined') {} to detect which method you need to use.
Frames are deprecated since 1997 (HTML 4.0 specification) for many reasons - so the best recommendation is do not use them.
You can also run Chrome with command line argument --disable-web-security, but it is also bad recommendation.
I'm trying to understand this conflict between
My loadingbarscript that hides my content until the page is loaded (Removed the tags from the top)
function showContent(){
//hide loading status...
document.getElementById("loading").style.display='none';
//show content
document.getElementById("content").style.display='block';
}
window.onload = function() {
showContent(); }
</head>
<body>
<script type="text/javascript">
document.write('<div id="loading"><img src="ajax-loader.gif"></div>');
</script>
<div id="content">
<script type="text/javascript">
//hide content
document.getElementById("content").style.display='none';
</script>
And 2. My livepipe scrollbar using prototype 1.6.1
Where the call is this:
<script type="text/javascript">
document.observe('dom:loaded',function(){
var scrollbar = new Control.ScrollBar('cases_tekst','scrollbar_track');
});
</script>
For some reason either one works or they other depending on the order. I had several other windows.onload functions that work with the prototype scrollbar but not this one.
Hope to understand better what is turning wrong. No errors show up with firebug.
The mistake must have something to do with the onload call because when i resize my browser window the scrollbar works.
Hope someone can explain the cause of the conflict.
Instead of using window.onload to call showContents, use prototype's Event.observe function. Like this:
Event.observe(window, "load", showContent);
For more info on this function: http://www.prototypejs.org/api/event/observe
For more info on why not to use the window.load event model, check out this site: http://www.quirksmode.org/js/introevents.html
In general, quirksmode.org is a great site for understanding this kind of thing and how they behave in various browsers. That's one of the reasons to use libraries such as prototype or jquery as it standardizes much of the browser's behavior.
I just solved a similar problem with the livepipe scrollbar. The scrollbar wouldn't appear until I resized my browser window in all browsers except firefox. It turned out it was caused by the nature of the content in the scrolling div. I had many irregularly sized images in there. When I replaced them with text or squared them all up it worked fine.