Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
Full disclosure - I posted this in the Web Design & Development small questions thread, but came to the conclusion that it's really more Javascript and I will be more likely to get help with it here. Hence I'm reposting it.

My website implements a board game via PHP. A user can view a game in progress by visiting a URL that looks like mywebsite.com/board.php?GameID=1234. Although the site is essentially set up to enable a play-by-email kind of experience, it might happen that some users would like to play in real time, or close to real time. Because the page generated when visiting the URL is static, they can only see what the real current state of the game is by refreshing the page. This is inconvenient, and it means more work for my website too if people are constantly refreshing pages, so I rigged up a hack to slightly reduce the problem. To each game there corresponds a number saying how many moves have been made in the game. So it starts off at zero and is incremented whenever someone makes a move. If a user loads a page corresponding to a game in progress, then a Javascript runs such that every five seconds the page checks with the website to see if the number of moves made is bigger. If it is then it turns the page background a different colour, so as to alert the user without interrupting any activity the user is performing on the page.

My <body> tag looks like this:

<body onLoad="IntervalID = setInterval ('ajaxFunction()', 5000);" onUnload="clearInterval(IntervalID);">

For completeness, here is ajaxFunction: (This was taken from the page from a game that at the time had had 95 moves made, hence the "95")

code:
function ajaxFunction() {
    /* Attribution: This JavaScript code is based on code
       taken from w3schools.com */
    var xmlHttp;
    try { xmlHttp=new XMLHttpRequest(); }
    catch (e) {
        try {
            xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
        }
        catch (e) {
            return false;
        }
    }
    xmlHttp.onreadystatechange=function() {
        if ( xmlHttp.readyState == 4 ) {
            if ( xmlHttp.responseText != "95" ) {
                document.bgColor = "#BFDFFF";
                clearInterval(IntervalID);
            }
        }
    };
    xmlHttp.open("GET","newmoves.php?GameID=1234",true)
    xmlHttp.send(null);
}
My question: I noticed that occasionally when one leaves the page, the page background will change colour (despite the fact that when one comes back, no new moves have been made). I deduce that this is because the every-five-second function happens to be running at just that time. I attempted to tackle this by adding to the <body> tag (as given above) the following:

onUnload="clearInterval(IntervalID);"

This does not solve the problem. The page still changes colour sometimes when one leaves. What should I do to stop this?

Adbot
ADBOT LOVES YOU

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Lumpy posted:

Perhaps make your code > 94? It's possible the ajax return happens when it's false on unload, and since false is not the string 95, you get a background change. This is my pre-coffee first guess, so it's probably wrong. I'll look again in an hour when I wake up.

Thanks for the suggestion, I'll try making this change.

Of course it's one of those funny things that since I can't make it happen on demand, there's no way of knowing whether it worked unless several weeks go by with no "false positives".

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
What Lumpy said prompted me to carry out the following test: I loaded up a typical board page, then disconnected my computer from its network connection. I then waited a while to see if the page would change colour; then clicked an arbitrary hyperlink on the page so as to exit. By doing this I was consistently able to cause the background colour change to trigger (always upon clicking the hyperlink).

I then changed the code as follows:

code:
function ajaxFunction() {
...
    xmlHttp.onreadystatechange = function() {
        if ( xmlHttp.readyState == 4 ) {
            var p = parseInt(xmlHttp.responseText);
            if ( !p ) { return false; }
            if ( p != 95 ) {
                document.bgColor = "#BFDFFF";
                clearInterval(IntervalID);
            }
        }
    };
...
}
(continuing from the above example where the key value was 95)

I then repeated the test after making this change. The background colour no longer changes on exiting the page. I conclude that the change had the desired effect. Thanks both.

I am puzzled by one thing; in my test (of the old code) I only saw the colour change on clicking a hyperlink. I had thought what might happen would be that it would change colour anywhere between 0 and 5 seconds after disconnecting my computer, but this is not the case.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
One of my pages has a setInterval that gets called in the onload property of the <body> tag:

<body onLoad="IntervalID = setInterval ('ajaxFunction()', 20000)">

As you can see this is supposed to go off every 20 seconds. The purpose of ajaxFunction() is to check on the contents of a small .txt file on the site to see if they have changed, and if they have changed, to notify the user by changing the page background colour. I have determined that it works as expected. However, I noticed while using the Firebug "Net/XHR" tab that the function appears to get called less frequently than specified. It seemed to happen about every two minutes or thereabouts, instead of every 20 seconds.

Then I closed Firefox and started it up again, as my browsing session had been going on for a while, and timed the delay another time. This time it was about 35-45 seconds.

If you are logged out when you visit the page, then the delay is set as 180,000 milliseconds instead of 20,000. I visited the page logged out and timed the delay between requests again, and found it was about 9 minutes.

This is weird, why might my interval be so much longer than I specified?

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

KARMA! posted:

It looks as though I was looking in the wrong Firebug tab - it appears reliably in the "Console" tab at the correct intervals. Not sure why the "Net" tab is tardy, but there you go.

Thanks for the pointers, I changed my syntax slightly to be more standardised.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
This page appears the way I expect it to in Firefox and in Opera. But if you mouse over the black and blue lines in Firefox, you will notice they expand in size. In Opera, this doesn't work, although other javascript events fire as expected; for example, clicking one of the square black-and-white images causes all of those images to go transparent. How come Opera doesn't like my onmouseover effects? (I looked in Tools>Advanced>Error Console, but there was nothing there.)

The page does not display correctly in IE, but I think this is an issue with SVG Web.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

rt4 posted:

Actually, that SVG mouseover is not working for me in Firefox 3.6 on Linux either.
That's irritating.

On reading your post, I went and updated Firefox to the latest version, but I still find that the onmouseover effect is working.

I don't suppose you have firebug installed? If you have, does it say anything?

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
I've been fiddling with this for a bit, and the only conclusion I can come to is: Opera doesn't seem to support the "onmouseover" property, or at least, not if it's a property of an element of an SVG image that was added after page load using JavaScript. I tried changing the code that adds the onmouseover property from

dummysheath.setAttribute('onmouseover','document.defaultView.parent.railmouseover('+i+')');

to

dummysheath.setAttribute('onmouseover','alert("Hi")');

and it still didn't work; yet I can use the exact same code (either of those two lines) to add the "onclick" attribute to my new element, and it will behave like it should. Also, if I assign the functionality I wanted for the "onmouseover" event to the onclick element instead, then the expected behaviour is exhibited when I click; so there is no fault (according to Opera) with the code that is being run, it's just that Opera refuses to notice the onmouseover event.

To reiterate: I have this page http://orderofthehammer.com/svgtest.htm

The behaviours it should show are:

1) When you move the mouse close to one of the blue or black lines on the image, the line width should increase.
2) When you move the mouse away, the line should go back to its original width.
3) When you click one of the lines, it should display an alert() box saying "You clicked blah"
4) When you click one of the square black-and-white images on the page, all of the square black-and-white images should go translucent. If you click again, they should go back to being opaque.

At the moment, Firefox (running on my machine) exhibits all 4 behaviours. Opera exhibits only 3 and 4. Chrome exhibits all four behaviours, but it also exhibits a fifth (undesirable) behaviour: it detects the onclick event even outside the clipping path of images (so you can click on certain parts of the image that ought to have no effect, and it will behave as though you clicked on one of the black-and-white images.)

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Plorkyeran posted:

The mouseover event works correctly for the blue (but not the black) lines for me with Opera 10.50. The click event works for both types of lines.
I was messing around with it a bit more just now, trying some different things in the js code for the black lines, which is probably why it didn't work for the black lines.

I just went and made sure I have the latest version of Opera, and my version was outdated so I updated it, but it still isn't working - I wish I knew why it is working inconsistently across different machines.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
OK, this gets increasingly bizarre. I have found that if I add to the SVG file itself (the source file, which had been empty but for a few <g> elements) the following:
code:
<path d="M900 100 L700 100"
      id="shcanal99"
      onmouseover="document.defaultView.parent.canalmouseover(99)"
      />

...

<path d="M900 100 L700 100"
      id="canal99"
      onmouseover="document.defaultView.parent.canalmouseover(99)"
      onclick="document.defaultView.parent.canalclicked(99)"
      onmouseout="document.defaultView.parent.canalmouseout(99)"
      />
then not only will the onmouseover/onmouseout properties work for that element, they will also work for every other element (the ones I am adding using JavaScript). If I comment out the above lines, then it goes back to the way it was before, with none of the onmouseover/onmouseout stuff working. This has to be a bug in Opera, I see no other explanation for it.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Hammerite posted:

...

then not only will the onmouseover/onmouseout properties work for that element, they will also work for every other element (the ones I am adding using JavaScript). If I comment out the above lines, then it goes back to the way it was before, with none of the onmouseover/onmouseout stuff working. This has to be a bug in Opera, I see no other explanation for it.
... and if I put in only one of those elements, and give it an onmouseover property but not an onmouseout property, then onmouseover events work on all elements, but onmouseout events don't work on any. :2bong:

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
I have some code which works in Firefox, Opera and Chrome. However, I use setAttributeNS all over the place, and IE doesn't "do" that. How can I modify my code to get IE to work with it?

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Nigglypuff posted:

Are you calling setAttributeNS on DOM nodes from the page itself, or external XML nodes? I don't think it's possible to reimplement the method on nodes that don't already support it, but you might be able to work around the need to use it. Post some code!!!!! :bubblewoop:

I am using JavaScript to create, style and add DOM nodes to an SVG image in the page. (Yes, I am aware that IE versions 8 and lower do not support SVG; I am using the SVG Web alpha.) The following is the code that includes the SVG file in the page:

code:
<!--[if IE]>
<object src="blanksvg.svg" classid="image/svg+xml" id="boardSVG" width="960" height="1100"></object>
<![endif]-->
<![if !IE]>
<object data="blanksvg.svg" type="image/svg+xml" id="boardSVG" width="960" height="1100"></object>
<![endif]>
Here is the <body> tag for the page:

code:
<body onLoad="buildboard();">
The function buildboard() is in an external .js file. Here it is:

code:
function buildboard() {
    determinelocationvisibility();
    if ( numbgpictures ) { addpictures(); }
    addlocationnames();
    if ( numvirtualconnections && displayvirtualconnections ) {
        addvirtualconnections();
    }
    if ( railphase ) {
        if ( displaycanals ) { addlinks(false); }
        addlinks(true);
    } else {
        if ( displayrails ) { addlinks(true); }
        addlinks(false);
    }
    addindustryspaces();
    if ( nummoneysymbols ) {
        addmoneysymbols();
    }
}
The integer numbgpictures is equal to 1. The function addpictures() is in the same file as buildboard(). Here it is:

code:
function addpictures() {
    var thegroup = document.getElementById('boardSVG').contentDocument.getElementById('backgroundpicturesgroup');
    var dummyelt;
    var i;
    for (i=0;i<numbgpictures;i++) {
        if ( ( prettyboard && pictureexistspretty[i] ) ||
             ( !prettyboard && pictureexistscompact[i] )
             ) {
            dummyelt = document.createElementNS(svgns,'image');
            dummyelt.setAttributeNS(xlinkns,
                                    'href',
                                    'http://brass.orderofthehammer.com/gfx/' + backgroundpicturefilenames[i]
                                    );
            if ( prettyboard ) {
                dummyelt.setAttribute('x',bgpxpositionspretty[i]);
                dummyelt.setAttribute('y',bgpypositionspretty[i]);
            } else {
                dummyelt.setAttribute('x',bgpxpositions[i]);
                dummyelt.setAttribute('y',bgpypositions[i]);
            }
            dummyelt.setAttribute('width',bgpwidths[i]);
            dummyelt.setAttribute('height',bgpheights[i]);
            thegroup.appendChild(dummyelt);
        }
    }
}
IE stops trying at the line where dummyelt.setAttributeNS is called. (It does not seem to have any problem with createElementNS.) The following appears in the console under "Scripts":

IE posted:

LOG: Error while firing onload: Object doesn't support this property or method

You can see this page here.

Hammerite fucked around with this message at 22:41 on Mar 21, 2010

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Nigglypuff posted:

How about replacing this line:

... with this?
I tried changing the function to each of the following:

code:
function addpictures() {
    var thesvg = document.getElementById('boardSVG').contentDocument;
    var thegroup = thesvg.getElementById('backgroundpicturesgroup');
    var dummyelt;
    var i;
    for (i=0;i<numbgpictures;i++) {
        if ( ( prettyboard && pictureexistspretty[i] ) ||
             ( !prettyboard && pictureexistscompact[i] )
             ) {
            dummyelt = thesvg.createElementNS(svgns,'image');
            dummyelt.setAttributeNS(xlinkns,
                                    'href',
                                    'http://brass.orderofthehammer.com/gfx/' + backgroundpicturefilenames[i]
                                    );
            if ( prettyboard ) {
        // after this point the same as before
code:
function addpictures() {
    var thesvg = document.getElementById('boardSVG').contentDocument;
    var thegroup = thesvg.getElementById('backgroundpicturesgroup');
    var dummyelt;
    var i;
    for (i=0;i<numbgpictures;i++) {
        if ( ( prettyboard && pictureexistspretty[i] ) ||
             ( !prettyboard && pictureexistscompact[i] )
             ) {
            dummyelt = thesvg.createElementNS(svgns,'image');
dummyelt.setAttribute('href','http://brass.orderofthehammer.com/gfx/' + backgroundpicturefilenames[i]);
/*            dummyelt.setAttributeNS(xlinkns,
                                    'href',
                                    'http://brass.orderofthehammer.com/gfx/' + backgroundpicturefilenames[i]
                                    );
*/            if ( prettyboard ) {
        // after this point the same as before
In the first case, the behaviour of IE is not changed, nor is that of Firefox.

In the second case, neither IE nor Firefox throws an error, but the picture does not display. Looking in Firebug shows that the image element exists and has the "href" attribute, but with a null namespace.

If in the second case I change the first argument of setAttribute from 'href' to 'xmlns:href', Firefox still doesn't show anything, but in IE the "Object doesn't support this property or method" message comes back.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
I also tried the following:
code:
function addpictures() {
    var thesvg = document.getElementById('boardSVG').contentDocument;
    var thegroup = thesvg.getElementById('backgroundpicturesgroup');
    var dummyelt;
var dummyattr;
    var i;
    for (i=0;i<numbgpictures;i++) {
        if ( ( prettyboard && pictureexistspretty[i] ) ||
             ( !prettyboard && pictureexistscompact[i] )
             ) {
            dummyelt = thesvg.createElementNS(svgns,'image');
dummyattr = thesvg.createAttributeNS(xlinkns,'href');
dummyattr.nodeValue = 'http://brass.orderofthehammer.com/gfx/' + backgroundpicturefilenames[i];
/*            dummyelt.setAttributeNS(xlinkns,
                                    'href',
                                    'http://brass.orderofthehammer.com/gfx/' + backgroundpicturefilenames[i]
                                    );
*/            if ( prettyboard ) {
                dummyelt.setAttribute('x',bgpxpositionspretty[i]);
                dummyelt.setAttribute('y',bgpypositionspretty[i]);
            } else {
                dummyelt.setAttribute('x',bgpxpositions[i]);
                dummyelt.setAttribute('y',bgpypositions[i]);
            }
            dummyelt.setAttribute('width',bgpwidths[i]);
            dummyelt.setAttribute('height',bgpheights[i]);
            thegroup.appendChild(dummyelt);
dummyelt.setAttributeNodeNS(dummyattr);
        }
    }
}
Again, this works in Firefox but IE chokes on createAttributeNS().

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
"Version: 8.0.6001.18882"

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
I have a long string that is a mixture of digits and the uppercase letters A through J. I want to replace every occurence of 'A' with '0|', every occurence of 'B' with '1|', ..., and every occurence of 'J' with '9|'. I looked for how to do this on the internet, but the answers I found all said that the only way to replace every occurence of a substring was to use regular expressions and supply the 'g' modifier. Is that really correct? Do I really have to do
code:
mystring = mystring.replace(/A/g,'0|');
mystring = mystring.replace(/B/g,'1|');
...
mystring = mystring.replace(/J/g,'9|');
or is there a smarter way?

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
Thanks both of you. I've used barbarianbob's solution, since the cross-browser usability is an advantage. I'm glad there's a one-line solution, it's nice to be able to just "drop it in".

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

dark_panda posted:

JSLint is your friend, even if it hates you. It's picky and opinionated and will probably hate most of the JavaScript it sees, but it's also an invaluable tool for JavaScript development.

http://www.jslint.com/

Thanks for this link, I have added it to my favourites, even though some of the things it complains about are a bit bizarre (it doesn't like window.close() even though I checked "assume a browser"?)

Adbot
ADBOT LOVES YOU

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
OK, this is a really dumb and simple question that I should be able to find the answer to on Google. Unfortunately it's one of those things where when you google it all you can find are discussions of a different problem relating to the same keywords.

I have a JSON file (a JSON schema) I'm writing by hand. The following line is in there (sorry for tables):

code:
"pattern": "^([012] ?/ ?2)|([0-3] ?/ ? 3)|([0-4] ?/ ?4)|([0-6] ?/ ?6)|([0-8] ?/ ?8)|(([0-9]|1[012]) ?/ ?12)$"
I want to write this on two lines so it doesn't scroll off to the right in my editor. How do I do this in JSON? (I could use JSON schema's "oneOf" keyword to split this into two separate regular expressions, but it seems like a hack around the language, or whatever JSON is if "language" isn't the right word.) I Google but I can only find stuff about creating strings that have actual line breaks in them, which isn't what I want, I just want to write a string, that doesn't have a line break in it, on two lines.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply