Making a "sticky" CFWINDOW

This post is more than 2 years old.

Ok, I'm not really a huge fan of CFWINDOW, despite this being the second blog post in a row about them. That being said, I thought I'd recreate a trick (see PS below) with CFWINDOW that maybe some folks will find useful. The trick involves keeping CFWINDOW in a position and making it stick there as you scroll. It is probably best if you see it live:

http://www.coldfusionjedi.com/demos/stalker/wintest.cfm

Scroll down and note the CFWINDOW will adjust itself back to the original position. The code simply uses JavaScript to do the following:

  • Notice scrolls
  • When they scroll, note the position of the scroll and start an interval
  • Figure out how far 'off' the CFWINDOW is from where it should be and go 90% of the way there.
  • If the distance is less than some threshold, just set it and stop the interval

A bit silly, but fun! The complete code is here:

<cfajaximport tags="cfwindow" /> <html>

<head> <script> var origx = 50; var origy = 50; var origheight = 200; var targety = ""; var moving = false;

function init() { ColdFusion.Window.create('mywin','Windows Rules','win.cfm',{x:origx,y:origy,width:200,height:origheight,draggable:false}); window.onscroll = handleScroll; }

function handleScroll(e) { var cury = window.scrollY; var win = ColdFusion.Window.getWindowObject('mywin'); //var newy = origy+curY; //console.log('set y to '+newy) //win.moveTo(origx,newy); targety = origy+cury; if (!moving) { moving = true; heartbeat = window.setInterval('moveit()', 10); } }

function moveit() {

var win = ColdFusion.Window.getWindowObject('mywin');
var pos = win.xy;
//find out how far I'm away from target
//console.log('my targety is '+targety+' and my current y is '+pos[1])
var distance = targety - pos[1];
	
if (distance == 0) {
	window.clearInterval(heartbeat);
	moving = false;
	return;
}

//we want to go X%, unless the X% is &lt; threshhold of &, then just go there
if(distance &gt; 3 || distance &lt; -3) var tomove = Math.round(0.09 * distance);
else var tomove = distance;
var newy = pos[1]+tomove;
//console.log('my newy is '+newy)
win.moveTo(origx,newy);

} </script> </head>

<body> <h2>Header</h2> <cfoutput>#repeatString("<br/>",200)#</cfoutput> <h2>Footer</h2>

</body> </html>

<cfset ajaxOnLoad("init")>

p.s. Ok, so this effect has been done before, and probably with better JavaScript, but I think, stress think I was the first one to do it. Way back in the old days, around 96 or so, the company I worked for did a lot of custom web development for Netscape. One day we were tasked to do a company timeline for them. The timeline was a very wide graph inside a frame. The timeline tracked 3 things I think, and they wanted a little control you could click to turn on/off the lines. The problem was that as you scrolled along the timeline, you lost the little control doohicky.

I created what I called the Stalker, a bit of JS code that simply did, well, what I described above. I was pretty surprised when it actually worked. Later on I wrote an IE compatible version and eventually wrapped it into a custom tag for the Allaire ColdFusion tag gallery. Unfortunately the company I worked for back then wasn't really into the OS thing so the tag was encrypted and it belonged to them. Anyway, not trying to brag (ok, maybe I am) but I thought it was an interesting story.

Ok, another quick side story to this side story. I did some Perl work at Netscape and would, from time to time, check their intranet. They had a stats page for netscape.com. If I remember right the #s were insane, something like millions and millions of hits per day - all from folks who didn't know how to change their homepage. The Perl project is a story for another day.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Rick O posted on 1/18/2009 at 3:51 AM

You can't just apply the position:fixed CSS style?

Comment 2 by Raul Riera posted on 1/18/2009 at 4:50 AM

@Rick: That CSS isnt supported by IE6.

@Ray: And about cfwindow? has anyone been able to place it over a flash content?

Comment 3 by Raymond Camden posted on 1/18/2009 at 7:24 AM

Raul - that's just a zindex setting, right? Couldn't you set it right after creating it?

Comment 4 by Raul Riera posted on 1/18/2009 at 7:36 AM

Tried, doesnt seem to work on IE though

Comment 5 by Gary Funk posted on 1/18/2009 at 7:38 AM

It doesn't work in IE, and Ray hates IE

Comment 6 by Rick O posted on 1/19/2009 at 2:03 AM

The websites we are about to go live with were developed with the "IE6 is dead" directive. We were seriously considering a snarky "your web browser was written in 2001 ... how does that 8-track music sound?" page.

We're down to less than 5% of our userbase on IE6 and, quite frankly, the customer support cost doesn't balance out the margin on their orders. (Nor even the extra development effort to backport the little things like this.)

Maybe 2009 is the year that everyone can finally move on. Maybe.

Comment 7 by jason olmsted posted on 1/19/2009 at 9:14 PM

For flash content to be layered among, and under, html content, you need to set the wmode of the flash content to opaque. There is an article at communitymx.com that discusses this:

http://www.communitymx.com/...

Comment 8 by Andrew W posted on 1/20/2009 at 5:37 PM

Ray -

As an avid reader of your blog, I had to check out the example in my favorite browser (Opera v.9.60, personally fire fox and the stalker script isn't working. Just an FYI.

Comment 9 by Andrew W posted on 1/20/2009 at 5:38 PM

Ray -

So if I could type . . . . As an avid reader of your blog, I had to check out the example in my favorite browser (Opera v.9.60, personally fire fox and I don't get along) the stalker script isn't working. Just an FYI.

Comment 10 by Raymond Camden posted on 1/20/2009 at 7:24 PM

@Andrew: Since this was only a toy, I'm not too concerned, but I am curious as to where it fails. Feel like digging in and seeing what part doesn't work?

Comment 11 by Andrew W posted on 1/20/2009 at 9:11 PM

Ray -

I'll see if I can find some time to do so (school and work and all that jazz). Plus we are on on MX 7 at the office, so its gonna have to wait until I get home.

Comment 12 by Adrian posted on 9/17/2009 at 9:18 PM

In firebug i get a
"pos is undefined
var distance = targety - pos[1];\n"
error. At first i thought it had to do with win.xy but i tried it with my own cfwindow and its valid in my CF8 even though i didnt see it in ext docs. It gives you the x,y of the window. assuming that the getwindow worked. Firebug didnt seem to help at all. The only way i got it to work was to remove the if statements/case scenarios. Im not that great at javascript so i'll leave the rest to someone else.

Comment 13 by Jason posted on 12/13/2012 at 11:07 PM

Hi Ray,
Yeah, I know it's like 4 years later... but this demo doesn't work! =) (on IE9 and FF17) Have you changed your tune on CFWINDOW at all? I got all twisted up with a bootstrap modal and had to fall back to CFWINDOW / CF9. Works OK, if you can find it!? Center option places it off the screen on long pages. Just wondering if you have any thoughts.

Comment 14 by Raymond Camden posted on 12/14/2012 at 12:10 AM

It doesn't work because the Ext library used in 9 and 10 has been updated. I'm not sure what is used in 9, but I was able to get it working in 10 with two fixes. First:

Comment out

var pos = win.xy;

and switch to

var pos = [win.x, win.y];

(This is kind of a dumb change. I could mod other lines to just use win.x and win.y, but was just trying to keep things simple.)

Then, change

win.moveTo(origx,newy);

to

win.setPagePosition(origx, newy);

Comment 15 by Jason posted on 12/14/2012 at 1:03 PM

You rock! Works great in CF9 as well. Thank you.