PDA

View Full Version : [DHTML] The Crawl



jscheuer1
03-03-2009, 05:15 AM
1) CODE TITLE: The Crawl

2) AUTHOR NAME/NOTES: jscheuer1

3) DESCRIPTION: A highly configurable multiuse horizontal marquee script. The Crawl can go left or right, contain text or images or both. It is a continuous marquee that avoids blank space in between passes. It can optionally be mouse driven like DD's Cmotion script. OO code allows as many marquees on the page as one wants, and with no onload event, as well as built in polling for markup not already on the page, it will play nice with many other scripts. Setup is fairly simple, you just put the contents in a division with the class of marquee and a unique id, and initialize with a short script after the closing div tag for that marquee.

4) URL TO CODE: http://home.comcast.net/~jscheuer1/side/thecrawl/

ddadmin
03-03-2009, 08:34 PM
Strange name, but very nice nonetheless! It looks like you've pretty much encapsulated most of the frequently requested features in a scroller and rolled it into one. On the top of that list is the continuous, no gap sequence between the last and first slide.

On another note, it seems you've taken a liking to wrapping a function in an anonymous function to execute it immediately? :)

jscheuer1
03-04-2009, 03:50 AM
Thanks. I'm open to suggestion as to the name.

I forgot to mention that it is very cross browser as well - tested in NS 7.2 (includes presumably all FF - I tested in v3.0.6) and up on the Mozilla front, IE 5.5 (perhaps will work in IE 5) and up (including 8 - which was a pain - I hope they fix/change a number of things about that browser before actually releasing it), modern (and probably will work in earlier) Opera, Safari, and Chrome.

I'm still tweaking the script code and the demo page a bit as things strike me, but it certainly is release worthy at this point.

The main advantage in my opinion to the anonymous function wrap, and this can be achieved in other ways as well are that as a coding habit it gives you an object outside of the global scope that can be accessed from it if a single hook (as in this case) is provided. At the same time it allows you to code within it just as one can (but in my opinion much more riskily) within the global scope, with variables available to all functions. Immediate execution is a feature, but not so important in my opinion as the object space created. You can also (not used in this case) pass it objects, functions, strings etc. as arguments.

ddadmin
03-04-2009, 05:56 AM
Still retaining the "crawl" word, what about:

- Crawler
- Text and Image Crawler
- Message Crawler

Yes I noticed the anonymous function wrap in your Expando Script as well. I've never tried such an approach yet, but it does seem to have some unique benefits.

jscheuer1
03-04-2009, 06:34 AM
Text and/or Image Crawler:

I think would look good and sum it up pretty well, and the script file could then be named crawler.js. I hit on 'The Crawl' because looking at it in early development (I started with just text), it reminded me of what was called 'the crawl' seen on CNN in bygone days, and that many news/information networks feature(d) at the bottom of their screens.

I'll make the necessary changes to the demo index and script file now.

jscheuer1
03-04-2009, 03:46 PM
OK, I've made those changes. I went back to test IE 5, just out of curiosity and it doesn't support Array.push or Object.hasOwnProperty, or white-space: nowrap, so I made modifications for that, in the hopes that (I could care less about IE 5 for the PC) it might still work for the odd IE 5 Mac user. I kept the advanced features for all modern browsers, just giving a slightly different path to IE less than 5.5 and supplying an Array.push function for those IE browsers without it.

IE 5 also doesn't support the 'encameling' method I used, so I made one for it. Others still use the more efficient method.

While I was at it, I eliminated all reliance on innerHTML.

ddadmin
03-15-2009, 03:07 AM
Sorry for the delay, been fighting a cold, and just getting back to the swing of things. I've started putting together the script page on DD to feature The Crawler. It definitely is feature rich I must say. Here's a rough draft (http://www.dynamicdrive.com/dynamicindex2/crawler/) of the script page at this point.

Just some feedback at this point:

1) Potential bug: In IE7, if you view the draft page, a JS error is thrown. It seems to be based on where the marquee is added on the page. If I move the Crawler Marquee outside the table column so it's just inside the BODY tag, the error is gone.

2) This is just an observation/suggestion. I noticed if a Crawler consists of just images, the script will string them together so they appear all on one line. If there is a JS error on the page and the script doesn't run though, the page's width is stretched horizontally, potentially by a lot. This happened when I tried to add a second Crawler to the script page and the script failed in IE. I understand the logic behind stringing the content together, though I believe there are ways to do this without affecting the page's layout, even if it's temporary or when things fail.

3) A small rant: the "style" param. I think the "style" parameter could prove awkward/confusing to use for quite a few people. The double quotes syntax aside, from what I gather styles inside it affect the inner DIV of the marquee, not the marquee itself. But a lot of people don't know or understand the difference between the two. Defining a CSS border using the style param for example fails to add the border to the left/right edges- this needs to be done to the marquee DIV itself. This in turn requires that the user understand that the CSS class name for a marquee is in fact dynamic, something like:


<style type="text/css">

.marquee0{ /*read docs on class name convention used*/
border: 1px solid #CC3300;
}

</style>

This can all get rather confusing very quickly for newbies. Ideally I'd like to just remove the style param altogether, but I understand the main reason for its existence- so users can specify things like padding of the marquee content and have the script pick up on those values easily, without probing any external CSS values. But I just can't help but think there must be a more elegant way around it.

1) above is obviously the must critical issue at the moment. :)

jscheuer1
03-15-2009, 10:32 PM
If you use a table, for IE you must initialize outside (after) the table. I hadn't realized this until you pointed out the problem though (I rarely use tables for new work any more), and I can only imagine for the time being why it is this way (in IE 7 and 6 at least). I'm a bit busy though right now though this has me intrigued, so I will probably test in 8, 5, and 5.5 to see what's what with that one.

BTW. Even though the style is pretty much as you seem to understand it. It's really much simpler. Basically you have:


<div class="marquee#"> <!-- static position -->
<div> <!-- relative position -->
<div> content </div> <!-- absolute position -->
<div> content </div> <!-- absolute position -->
</div>
</div>

I only added the static positioned wrapper for IE 8. It needs to have a static wrapper with overflow hidden, otherwise it makes a a horizontal scrollbar for the page, even though the relatively positioned element also has overflow hidden - this is a bug in IE 8 RC1 that can be duplicated using only hard coded HTML markup, and has nothing to do with the script.

But, if it were not for this messiness with the table in IE - whatever that is - styling the relatively positioned container would be sufficient for styling the marquee. The static container is irrelevant really. It's just that once you put a marquee in and initialize it in a table in IE, in addition to the error it gives, even if you comment out those lines (they are for fine tuning the width), a number of the styles get lost, both those configured in initialization, and those used by the script internally.

Try these two demos, good:


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="crawler.js">
/* Text and/or Image Crawler Script ©2009 John Davenport Scheuer
as first seen in http://www.dynamicdrive.com/forums/
username: jscheuer1 - This Notice Must Remain for Legal Use
*/
</script>
</head>
<body>
<table>
<tr>
<td><div class="marquee" id="mycrawler">
Those confounded friars dully buzz that faltering jay. An appraising tongue acutely causes our courageous hogs. Their fitting submarines deftly break your approving improvisations. Her downcast taxonomies actually box up those disgusted turtles.
</div></td>
</tr>
</table>
<script type="text/javascript">
marqueeInit({
uniqueid: 'mycrawler',
style: {'width': '450px',
'background': 'lightyellow',
'border': '1px solid #CC3300',
'height': '2em',
'padding': '2px'
},
inc: 8, //speed - pixel increment for each iteration of this marquee's movement
mouse: 'cursor driven', //mouseover behavior ('pause' 'cursor driven' or false)
moveatleast: 4,
neutral: 150,
savedirection: true
});
</script>
</body>
</html>

Bad:


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="crawler.js">
/* Text and/or Image Crawler Script ©2009 John Davenport Scheuer
as first seen in http://www.dynamicdrive.com/forums/
username: jscheuer1 - This Notice Must Remain for Legal Use
*/
</script>
</head>
<body>
<table>
<tr>
<td><div class="marquee" id="mycrawler">
Those confounded friars dully buzz that faltering jay. An appraising tongue acutely causes our courageous hogs. Their fitting submarines deftly break your approving improvisations. Her downcast taxonomies actually box up those disgusted turtles.
</div><script type="text/javascript">
marqueeInit({
uniqueid: 'mycrawler',
style: {'width': '450px',
'background': 'lightyellow',
'border': '1px solid #CC3300',
'height': '2em',
'padding': '2px'
},
inc: 8, //speed - pixel increment for each iteration of this marquee's movement
mouse: 'cursor driven', //mouseover behavior ('pause' 'cursor driven' or false)
moveatleast: 4,
neutral: 150,
savedirection: true
});
</script>
</td>
</tr>
</table>
</body>
</html>

Added Later:

Also, in an unrelated matter, I've just updated the script due to another IE bug. I had named all functions, even those assigned to objects or variables. This can sometimes prove problematic in IE, even though it is valid and a good practice. The new version simply removes all such naming.

As to IE, 5.01, 5.5, 6, and 7 all have a problem with the 'bad' example above. 8 is fine with both the good and the bad, as are I'm sure all other modern browsers.

I've also added to my demo page:


Important Note: If you are using a marquee within a table, due to a table rendering bug in IE less than 8, you must initialize after the closing </table> tag.

See also:

http://home.comcast.net/~jscheuer1/side/thecrawl/table_good.htm - Good in IE with table

http://home.comcast.net/~jscheuer1/side/thecrawl/table_bad.htm - Bad in IE with table

ddadmin
03-16-2009, 05:02 AM
Thanks for the info John about the placement of the initialization code. Upon following your advice the demo on the script page now works in IE. It's also running the latest version of the .js file. Next up I'll be adding an images based demo to the script page, and see if there are other suggestions I can provide at that point.

p.s: Interestingly I haven't actually tried running the script in IE8 yet. I recently formatted my PC, so all I got at the moment is IE7.

jscheuer1
03-16-2009, 08:38 AM
OK, now I know this is just a rough draft, but you currently have two inits at the end:


<!--webbot bot="HTMLMarkup" startspan --><script type="text/javascript">
marqueeInit({
uniqueid: 'mycrawler',
style: {
'padding': '2px'
},
inc: 8, //speed - pixel increment for each iteration of this marquee's movement
mouse: 'cursor driven', //mouseover behavior ('pause' 'cursor driven' or false)
moveatleast: 4,
neutral: 150,
savedirection: true
});
</script><!--webbot bot="HTMLMarkup" endspan i-checksum="43437" --><p><!--webbot bot="HTMLMarkup" startspan --><script type="text/javascript">
marqueeInit({
uniqueid: 'mycrawler',
style: {
'padding': '2px'
},
inc: 8, //speed - pixel increment for each iteration of this marquee's movement
mouse: 'cursor driven', //mouseover behavior ('pause' 'cursor driven' or false)
moveatleast: 4,
neutral: 150,
savedirection: true
});
</script><!--webbot bot="HTMLMarkup" endspan i-checksum="43437" --></p>

</body>

</html>

But now only one marquee. Also, with the initialization outside the table, you should return to following (from my demo page, emphasis added):


After initialization each marquee will be given a class name of 'marquee#', where # is a number from 0 to whatever, indicating the order in which the marquees appear on the page. These class names may be used to style the marquee or its contents (like borders for images in the marquee), but for the marquee itself, because the script relies upon some of those styles (when present) for its calculations, it is best to use the initialization style object as outlined above.

Basically all styling of the marquee itself should be done with the initialization style object, especially width and height, borders, padding, margin - these are all used in calculating how to vertically center the content, and how to assure that the width specified matches up properly to the content (an adjustment is made to the width if it exceeds that of the content). The marquee# class may be used, as stated to style the content within the marquee, like images, also for power users it is an avenue for further customization. Generally though it need not and probably should not be used.

jscheuer1
03-17-2009, 04:37 AM
I've updated the script again. It now will delay initialization of marquees in tables until after the page is loaded in IE 7 and less. I even added a method to determine if IE 8 is in compatibility mode, so as to apply the fix in it under those circumstances as well.

As a result, no warning is required for marquees in tables.

I would also like to stress again that the use of the marquee# class to style the marquee itself is to be discouraged, the initialization style object should be used for that. The marquee# class is only for styling the content, like adding borders to images or styling other inline content (like spans or anchor links) within the marquee.

ddadmin
03-17-2009, 08:18 AM
Thanks for the updates. I'll be fixing the typos on the script page, update the .js file, and moving the init code back into the table immediately following the HTML itself.

Regarding the marquee# topic, I was under the impression it was added to the outermost DIV container of the Crawler? I'm aware that certain CSS values need to be defined inline using the style object in order for things to work, which is why in the script page, I defined "padding" as a property of the style object (since that one I reckon affects the script), but not properties such as background and border.

jscheuer1
03-17-2009, 10:59 AM
Well, you can apply background and border to the marquee# class - at your own risk. I noticed some browsers not working well with that - the text hanging a little outside the line on the right. The actual container of the marquee is the first child of the classed element, by setting the style via the style object you are styling this first child, and you will generally have a better chance of everything lining up across browsers. I think it makes things simpler for people using the script too - if you let them know that they really should only concern themselves with the style object. Any mention of using the marquee# class should be (in my opinion) as an advanced method for tweaking.

For example, if you don't like how the contents center/align themselves vertically, you may override their script generated padding-top property by:


.marquee0 div div {
padding-top: 3px!important;
}

Or if you want all of the images to have borders:


.marquee1 img {
border: 2px solid #ccc;
}

Or you could style the classed element just to reserve a larger space on the page for the marquee and/or add additional borders or padding around it, but you could also use your own wrapper for this purpose. The script already reserves the minimum required space for the marquee (its actual width and height including any margin, padding, borders, etc.), as long as you style primarily via the style object.

Those are the sorts of things I had in mind for that class, and why pretty much any use of it should be considered more of an advanced thing - an advanced user might even want to make use of it for adding additional script code in some way to a given marquee.

Think of it as a little like the Ultimate Fade-in Slide Show. You configure a few things via the script, but if you want to do something advanced, there is the master# id style hook. Only in this case you may configure a lot more via the script, because it gives you an entire style object for doing so, rather than just a few keywords like width, hight, border, etc.

ddadmin
03-18-2009, 05:50 AM
Not a problem, I'll reword things on the script page so use of the "marquee#" class is deemphasized. My original thinking was to try and make it even easier for users to define most of the styling for the Crawler (using regular CSS), but if it potentially can lead to issues, then that's obviously a more pressing issue.

Just a question- in your docs, you say that if a Crawler has no height specified using the style object, it will default to the content's height. That doesn't apply if the contents are images right? In other words, in this case, an explicit height must be defined?

jscheuer1
03-18-2009, 01:59 PM
Thanks on the style business. You're right about specifying the height with images, if it isn't specified (or alternatively if the tallest image doesn't have either a style height or height attribute accurately set), the height found by the script for marquees with un-cached images and no height specified in their style object would in most cases be incorrect. I hadn't thought of that.

But the script delays final initialization on images anyway - until they are loaded, because the actual width of the content must be determined, and because I chose not to have missing image tokens visible during loading. So I'm now thinking I could get the height then if one wasn't supplied. Relying on that would produce a less than graceful visual page load experience though. Because the height would change once the the height of the images became known to the browser, there could be jumpiness.

So, regardless of whether or not I add that feature, yes one should specify a height for image marquees.

I just updated the script again to, in the case of images being used in the marquee and no height being specified in the style object, the script will take the height from the images once loaded. This will make a page jump once the height is added to it, so really shouldn't be relied upon in most cases.

In the way of a few details on this - If a text only marquee has no height specified, it will become the offsetHeight of the marquee + 3. In the case of images, the offsetHeight of the marquee + 4. For text only marquees, this offset will be known early enough to prevent jumpiness during page load. For marquees containing images, it will not.

A side effect of this is that setting the height on the image(s) themselves will no longer override a lack of height specified in the style object. So to avoid all chance of jumpiness during page load, with images it is even now more important to specify the marquee's height in the style object. But at least now the marquee will display if it is omitted. That will make inexperienced users happier, I'm sure.

ddadmin
03-18-2009, 11:53 PM
Great. Just a heads up that the script is now live on DD (http://dynamicdrive.com/dynamicindex2/crawler/index.htm). I figured it's stable enough to be consumed publicly already while I apply additional changes/ bug fixes at the same time (if any are found).

Perhaps it might be a good idea to add a version to the script moving forward, especially if you anticipate additional changes to the script moving foward?

jscheuer1
03-19-2009, 01:15 PM
Giving it a version number would be good. I don't like .0, and it really isn't a .0 anyway, so how about v1.1?

I'll be going over the demo page in detail when I have more time. But I noticed a minor typo and misdirection. Between Steps 1 and 2:


The code above references an external .js files, which you can download below (right click/ select "Save As"): crawler.js (http://dynamicdrive.com/dynamicindex2/crawler/crawler.js)

'files' should be 'file', and 'you can download below' should be, well I'm not sure, perhaps just 'you can download'

As usual, it's a nice looking demo page.

Oh, and since you are an 'advanced user' :), you might want to add this style to the page:


.marquee1 img {
vertical-align: middle!important;
}

jscheuer1
03-20-2009, 08:41 AM
OK, in addition to the remarks in my previous post I see a few other issues with the demo page:


I'm not sure that this is true, if it is, it's just how some browsers react sometimes (like if you hit the 'back' button) - there is no cookie:


And last but not least, the script supports persistence of the last viewed position within the marquee, so returning to the page causes the marquee to resume at that position.

So I'd just get rid of it.


I think this:


The contents for the Crawler is simply defined as normal HTML on the page, encased in a DIV element with a unique ID attribute. OO code allows as many marquees on the page as one wants, and with no onload event. It doesn't get easier than that!

Should be:

The content for the Crawler is simply defined as normal HTML on the page, encased in a DIV element with a unique ID attribute. OO code allows as many marquees on the page as one wants. It doesn't get easier than that! And with no onload event, it plays well with many other scripts.


I see another typo:


All of your settings for a Crawler is specified via the parameters you enter into marqueeInit().

is should be are.

ddadmin
03-20-2009, 04:33 PM
All typos have been fixed. :)

diltony
04-13-2009, 09:57 AM
It is an outstanding script really, and works smoothly too. . .and i especially love the way
it pauses or slows down when you hover. I am still working on improving my scripting abilities, just that you guys, especially you and ddadmin seem to be light years ahead of me!