Getting screen size to use in CSS - javascript

<style>
<script>
var screenW = 640, screenH = 480;
if (parseInt(navigator.appVersion)>3) {
screenW = screen.width;
screenH = screen.height;
}
else if (navigator.appName == "Netscape"
&& parseInt(navigator.appVersion)==3
&& navigator.javaEnabled()
)
{
var jToolkit = java.awt.Toolkit.getDefaultToolkit();
var jScreenSize = jToolkit.getScreenSize();
screenW = jScreenSize.width;
screenH = jScreenSize.height;
}
document.write(
".wrap, html {font-family: 'PT Sans', sans-serif; width:"+screenW+"px;height:"+screenH+"px;}"
)
</script>
</style>
This script is meant to add the user's screen size into the height and width parameters of this short CSS piece, which I have included internally, lacking a method of doing it with an external style sheet.
I'll be happy to learn a new and more efficient method of doing this. My official question, however, is will this script work?
http://www.javascripter.net/faq/screensi.htm is the page location that I grabbed this from!

I did this using XHTML (if it works in XHTML it works in HTML, but 99.9% of the time not vice-versa) so you know you're getting a quality example here.
First off you don't make a script element the child of a style element.
Secondly never ever put a script element inside of the body element unless you want to accrue serious damage to getting things to work down the road.
Never use document.write as it's not XHTML compatible or innerHTML as it treats code as text strings instead of code, meaning when you try to change something dumped in to the DOM it may or may not work because you may be referring to code or you may be referring to text that simply looks like code.
Save the following as example.xhtml and then open in Firefox. I recommend using Firebug's inspector to look at the DOM so you can see that the link element referring to the style sheet with the screen_height and screen_width can be confirmed at your end. Feel free to ask me any (sane) questions.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Example</title>
<script type="application/javascript">
//<![CDATA[
function load_css()
{
var l = document.createElement('link');
l.setAttribute('href','themes/example/style.css?screen_height='+encodeURIComponent(screen.height)+'&screen_width='+encodeURIComponent(screen.width));
l.setAttribute('rel','stylesheet');
l.setAttribute('title','example');
l.setAttribute('type','text/css');
document.getElementsByTagName('head')[0].appendChild(l);
}
window.onload = function()
{
load_css();
}
//]]>
</script>
</head>

Related

After an onpaste event in a contentEditable node, how can I iterate through all the pasted nodes? (especially in older versions of IE)

I'm modifying an HTML editor. On pasting, I need to manipulate some of the pasted HTML to adjust the attributes of the pasted nodes to identify them as duplicates.
I can intercept the paste when the user enters control + V, but it doesn't seem possible to redirect the paste when the user goes through the browser's context menu. I'm using the onpaste event in this case, getting the initial range and then using timeouts, when the range changes, I want to try to get all the nodes. How can I do this?
If I keep a reference to the TextRange object, the offsetWidth changes after the paste. I can call select() on the range and it selects exactly what was pasted. However, the offsetLeft doesn't seem to be correct, which I think is because the DOM changed. I'm trying to solve this for (older) IEs first because they're definitely the trickiest and for now, I need to support them.
Here's simplified sample code (the 500ms timeout is arbitrary):
inner.htm:
<!DOCTYPE html>
<html>
<head>
</head>
<body topMargin="1" leftMargin="1" contentEditable="true" onblur="">
<div>First section PASTE</div>
<div>HERE Second section</div>
<div>This is <div>COPY</div>ME text</div>
</body>
</html>
outer.htm:
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript'>
function getIfrmDoc() {
var ifrm = document.getElementById('ifrmain');
return ifrm.contentDocument || ifrm.contentWindow.document;
}
window.onload = function () {
var doc = getIfrmDoc();
doc.body.onpaste = function (e) {
var rng = doc.selection.createRange();
setTimeout(function () {
handlePastedData(rng);
}, 500);
}
}
function handlePastedData(initRange) {
// What can I do here?
initRange.select();
//alert(initRange.offsetWidth);
}
</script>
</head>
<body>
<iframe id="ifrmain" src="inner.htm" style="width: 100%; height: 450px;"></iframe>
</body>
</html>
So if you open outer.htm, and then copy a couple characters from anywhere, pasting it before the word "PASTE", it will give an offsetLeft of 1 even there are a few words before it.
In handlePastedData, how can I iterate through all the pasted nodes? I've tried to adapt various solutions from various other questions but haven't found anything that will work for this scenario.
Thanks!

div not rendered in internet explorer 9

Hi I have a custom js autocomplete component using AJAX that uses a div containing a table to show matching values.
When using it in IE9 with DOCTYPE declaration the div does not appear.
The strange think is that if I have another instance of the component in tha page everything works fine (I have those components in a table and add new rows dinamically; if the table is empty at the beginning I have the problem, otherwise I can add new rows containing new instances of the component and everything works fine).
The code work fine in firefox and chrome.
It works fine in ie9 too if I specify
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<meta http-equiv="X-UA-Compatible" content="IE=8" />
I have debugged and the javascript setting the div visible is executed to no avil:
this.resultTable.innerHTML=responseText;
this.resultTable.style.top=getY(this.editField)+22;
this.resultTable.style.left=getX(this.editField);
this.resultTable.style.zIndex="1";
this.resultTable.style.visibility='visible';
If I resize the windows the div magically appears.
Thanks in advance for you reply.
EDIT:
I have found a solution (thank to epascarello hint).
I have added
window.resizeBy(1,1);
window.resizeBy(-1,-1);
this solved almost because my page is in an iframe 100% w/h; the only remaining issue was that maximizing and restoring browser windows resulted in unecessary srollbars appearing in the iframe; I solved it adding
getFrameForDocument(document).style.width='100%';
getFrameForDocument(document).style.height='100%';
where getFrameForDocument was found at Getting a reference to the parent IFRAME and is
function getFrameForDocument(document) {
var w= document.defaultView || document.parentWindow;
var frames= w.parent.document.getElementsByTagName('iframe');
for (var i= frames.length; i-->0;) {
var frame= frames[i];
try {
var d= frame.contentDocument || frame.contentWindow.document;
if (d===document)
return frame;
} catch(e) {}
}
}

XPath Bug in Google Chrome?

I need to access a XML document I created with JavaScript via XPath. If I load an XML file from a server (via XMLHttpRequest) it works fine, but if I use the XML document reference from the local created XML document Chrome didn't show anything, while Firefox did what I expected.
Here a bit of example code:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<script type="text/javascript">
var xml = document.implementation.createDocument("", "", null);
var root = xml.createElement("root");
var level1 = xml.createElement("L1");
var level2 = xml.createElement("L2");
L2txt = xml.createTextNode("here is L2");
level2.appendChild(L2txt);
level1.appendChild(level2);
var level2 = xml.createElement("L2");
level2.setAttribute("id", "myId");
L2txt = xml.createTextNode("here is L2 with id");
level2.appendChild(L2txt);
level1.appendChild(level2);
root.appendChild(level1);
path="//L2[#id='myId']";
var nodes=xml.evaluate(path, root, null, XPathResult.ANY_TYPE, null);
var result=nodes.iterateNext();
while (result) {
document.write(result.textContent);
document.write("<br />");
result=nodes.iterateNext();
}
</script>
</body>
</html>
the Code should output "here is L2 with id".
I use FF 9.0.1 and Chrome 16.0.912.75 m the development tools don't show any error or hint.
Now I don't realy know, is it a bug in Chrome or an 'extra' feature in Firefox. And - most importent - how could I bring Chrome round to act like Firefox. Or do you have another idea how to use XPath on local created XML documents?!
Thanks in advance
I see you have a small problem in your example code.
The root element is never added to the XML document (the xml variable).
Therefore the XPath search cannot work since the xml document object has no root element and therefore no content to search. Try adding :
xml.appendChild(root);
After this:
var root = xml.createElement("root");
That fixes the issue for me in Chrome.

Chrome jumping caret bug with removeChild

Can someone please shed some light on this problem in Chrome? The removeChild() function makes the caret jump to the end of the div. Anyone got a workaround?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
var caretX = 0
function keypress(event){
insertAtCaret('<span id="caretpos"></span>');
var caretpos = document.getElementById('caretpos')
//caretX = getX(caretpos) //finds the X position of the element
removeNode(caretpos)
return(true)
}
//Functions used:
function insertAtCaret(text,replaceContents) {
if(!text){return(false);}
if(replaceContents==null){replaceContents=false;}
if(!replaceContents){//collapse selection:
var sel = document.getSelection()
sel.collapseToStart()
}
return(document.execCommand('insertHTML', false, text))
};
function removeNode(el){
el.parentNode.removeChild(el);
}
</script>
</head>
<body contentEditable="true" onkeypress="return(keypress(event))">
<div>Type some content somewhere here > < and watch what happens in chrome</div>
</body>
</html>
Update:
I'm actually trying to get the pixel location of the user's caret by inserting a dummy element, finding its position and then removing it. That said, the problem is a fundamental one in chrome, manipulating the DOM in this way causes the caret to jump to the end of the element
Exactly what should happen to the caret after calling document.execCommand('insertHTML') is undefined, but I agree that Chrome's behaviour is unhelpful. You could get round it by using the insertNode() method of Range to add your dummy element:
var sel = window.getSelection();
sel.collapseToStart();
var span = document.createElement("span");
var range = sel.getRangeAt(0);
range.insertNode(span);
// Get the position here...
span.parentNode.removeChild(span);
An alternative approach to the whole thing is to use Range's getBoundingClientRect() method in browsers that support it. See my answer here:
Coordinates of selected text in browser page
Finally, I've been writing a module to do this for my Rangy library. It's not quite finisihed but there's a demo here: http://rangy.googlecode.com/svn/trunk/demos/position.html

Javascript onload event to resize image help

This might be a simple one for you guys, im learning Javascript and have hit a problem. I am trying to have the script resize a particular image on the page when onload is called like so:
<script type="text/javascript">
function resizeSampleImage()
{
document.getElementById("sampleImage").style.height = (document.body.clientWidth) * 0.2;
}
</script>
...
<body onload = "resizeSampleImage();" >
...
<img id="sampleImage" src="Images/BP snip.jpg" alt="BuildingPeople.uk.com" />
apologies, forgot to mention that is doesn't work! after loading the page in multiple browsers the image stays it native size and the error consoles say they fail to parsing value for height. Declaration dropped.
I have tried lots of different ways but cannot seem to get it to work.
(document.body.clientWidth) * 0.2 will give you an integer. The CSS height property accepts a length.
Add some units.
There is a live example at http://jsbin.com/uyihe4
You can see the zoom effect when loading. I have only changed the
document.getElementById("sampleImage").style.height
to
document.getElementById("sampleImage").height
Well, your problem is that the images may not be ready when you apply the styles to them.
Use this function instead (note it takes a DOM object):
var imgLoader = function(domImg) {
var imgObj = new Image();
imgObj.onload = function()
{
// apply styles
domImg.style.height = "100px";
}
imgObj.src = domImg.src;
}
Though I haven't figure out the problem. But the following code snippet works for me (Tested in Chrome 8.0 and IE9.0Beta).
<html>
<head>
<title>test</title>
<script type="text/javascript">
function resizeSampleImage()
{
document.getElementById("sampleImage").style.height = (document.body.clientWidth) * 0.5;
}
</script>
</head>
<body onload="resizeSampleImage();">
<img id="sampleImage" src="http://news.mydrivers.com/Img/20101217/S03405153.jpg">
</body>
</html>

Categories