Solved

Conflicting javascript

Posted on 2011-10-01
25
228 Views
Last Modified: 2012-05-12
I have a div that scrolls up and down the page with user and that's controlled using javascript.  Within that div is a table and a selected row of that table needs to blink for a few seconds when the page loads (code snippet).  But adding the second code stops the first from working.  Javascript is not my area, but it's required here, so any help to avoid this problem is needed.
 
<script type="text/javascript">
var i = 1,timer;
window.onload=function() {
timer = setInterval('blink()', 1000);
}
function blink() {
 if (i<10) {
        if (i%2 == 0) { 
              document.getElementById('blink').style.backgroundColor = '#ffff00';
         } else {
              document.getElementById('blink').style.backgroundColor = '#ff0000';
         }
 } else {
      document.getElementById('blink').style.backgroundColor = '#ffff00';
      clearInterval(timer);
  }
 i++;
}
</script>

Open in new window

0
Comment
Question by:naryan109
  • 12
  • 11
  • 2
25 Comments
 
LVL 15

Expert Comment

by:Eyal
Comment Utility
and what is the other script?
0
 

Author Comment

by:naryan109
Comment Utility
it's pretty long, that's why I didn't include it.  But here it is.  This is an include.
 
var floatingMenu =
{
    hasInner: typeof(window.innerWidth) == 'number',
    hasElement: typeof(document.documentElement) == 'object'
        && typeof(document.documentElement.clientWidth) == 'number'
};

var floatingArray =
[
];

floatingMenu.add = function(obj, options)
{
    var name;
    var menu;

    if (typeof(obj) === "string")
        name = obj;
    else
        menu = obj;
        

    if (options == undefined)
    {
        floatingArray.push( 
            {
                id: name,
                menu: menu,

                targetLeft: 0,
                targetTop: 0,

                snap: true
            });
    }
    else
    {
        floatingArray.push( 
            {
                id: name,
                menu: menu,

                targetLeft: options.targetLeft,
                targetRight: options.targetRight,
                targetTop: options.targetTop,
                targetBottom: options.targetBottom,

                centerX: options.centerX,
                centerY: options.centerY,

                prohibitXMovement: options.prohibitXMovement,
                prohibitYMovement: options.prohibitYMovement,

                snap: options.snap,
                ignoreParentDimensions: options.ignoreParentDimensions,

                scrollContainer: options.scrollContainer,
                scrollContainerId: options.scrollContainerId
            });
    }
};

floatingMenu.findSingle = function(item)
{
    if (item.id)
        item.menu = document.getElementById(item.id);

    if (item.scrollContainerId)
        item.scrollContainer = document.getElementById(item.scrollContainerId);
};

floatingMenu.move = function (item)
{
    if (!item.prohibitXMovement)
    {
        item.menu.style.left = item.nextX + 'px';
        item.menu.style.right = '';
    }

    if (!item.prohibitYMovement)
    {
        item.menu.style.top = item.nextY + 'px';
        item.menu.style.bottom = '';
    }
};

floatingMenu.scrollLeft = function(item)
{
    if (item.scrollContainer)
        return item.scrollContainer.scrollLeft;

    var w = window;

    // Find top window scroll parameters if we're IFRAMEd
    while (w != w.parent)
        w = w.parent;

    return this.hasInner
        ? w.pageXOffset  
        : this.hasElement  
          ? w.document.documentElement.scrollLeft  
          : w.document.body.scrollLeft;
};

floatingMenu.scrollTop = function(item)
{
    if (item.scrollContainer)
        return item.scrollContainer.scrollTop;

    var w = window;

    // Find top window scroll parameters if we're IFRAMEd
    while (w != w.parent)
        w = w.parent;

    return this.hasInner
        ? w.pageYOffset
        : this.hasElement
          ? w.document.documentElement.scrollTop
          : w.document.body.scrollTop;
};

floatingMenu.windowWidth = function()
{
    return this.hasElement
        ? document.documentElement.clientWidth
        : document.body.clientWidth;
};

floatingMenu.windowHeight = function()
{
    if (floatingMenu.hasElement && floatingMenu.hasInner)
    {
        // Handle Opera 8 problems
        return document.documentElement.clientHeight > window.innerHeight
            ? window.innerHeight
            : document.documentElement.clientHeight
    }
    else
    {
        return floatingMenu.hasElement
            ? document.documentElement.clientHeight
            : document.body.clientHeight;
    }
};

floatingMenu.documentHeight = function()
{
    var innerHeight = this.hasInner
        ? window.innerHeight
        : 0;

    var body = document.body,
        html = document.documentElement;

    return Math.max(
        body.scrollHeight,
        body.offsetHeight, 
        html.clientHeight,
        html.scrollHeight,
        html.offsetHeight,
        innerHeight);
};

floatingMenu.documentWidth = function()
{
    var innerWidth = this.hasInner
        ? window.innerWidth
        : 0;

    var body = document.body,
        html = document.documentElement;

    return Math.max(
        body.scrollWidth,
        body.offsetWidth, 
        html.clientWidth,
        html.scrollWidth,
        html.offsetWidth,
        innerWidth);
};

floatingMenu.calculateCornerX = function(item)
{
    var offsetWidth = item.menu.offsetWidth;

    if (item.centerX)
        return this.scrollLeft(item) + (this.windowWidth() - offsetWidth)/2;

    var result = this.scrollLeft(item) - item.parentLeft;
    if (item.targetLeft == undefined)
    {
        result += this.windowWidth() - item.targetRight - offsetWidth;
    }
    else
    {
        result += item.targetLeft;
    }
        
    if (document.body != item.menu.parentNode
        && result + offsetWidth >= item.confinedWidthReserve)
    {
        result = item.confinedWidthReserve - offsetWidth;
    }

    if (result < 0)
        result = 0;

    return result;
};

floatingMenu.calculateCornerY = function(item)
{
    var offsetHeight = item.menu.offsetHeight;

    if (item.centerY)
        return this.scrollTop(item) + (this.windowHeight() - offsetHeight)/2;

    var result = this.scrollTop(item) - item.parentTop;
    if (item.targetTop === undefined)
    {
        result += this.windowHeight() - item.targetBottom - offsetHeight;
    }
    else
    {
        result += item.targetTop;
    }

    if (document.body != item.menu.parentNode
        && result + offsetHeight >= item.confinedHeightReserve)
    {
        result = item.confinedHeightReserve - offsetHeight;
    }

    if (result < 0)
        result = 0;
        
    return result;
};

floatingMenu.computeParent = function(item)
{
    if (item.ignoreParentDimensions)
    {
        item.confinedHeightReserve = this.documentHeight();
        item.confinedWidthReserver = this.documentWidth();
        item.parentLeft = 0;  
        item.parentTop = 0;  
        return;
    }

    var parentNode = item.menu.parentNode;
    var parentOffsets = this.offsets(parentNode, item);
    item.parentLeft = parentOffsets.left;
    item.parentTop = parentOffsets.top;

    item.confinedWidthReserve = parentNode.clientWidth;

    // We could have absolutely-positioned DIV wrapped
    // inside relatively-positioned. Then parent might not
    // have any height. Try to find parent that has
    // and try to find whats left of its height for us.
    var obj = parentNode;
    while (obj.clientHeight < item.menu.offsetHeight)
    {
        obj = obj.parentNode;
    }

    var hasHeightOffsets = this.offsets(obj, item);

    item.confinedHeightReserve = obj.clientHeight
        - (parentOffsets.top - hasHeightOffsets.top);
};

floatingMenu.offsets = function(obj, item)
{
    var result =
    {
        left: 0,
        top: 0
    };

    if (obj === item.scrollContainer)
        return;

    while (obj.offsetParent && obj.offsetParent != item.scrollContainer)
    {  
        result.left += obj.offsetLeft;  
        result.top += obj.offsetTop;  
        obj = obj.offsetParent;
    }  

    if (window == window.parent)
        return result;

    // we're IFRAMEd
    var iframes = window.parent.document.body.getElementsByTagName("IFRAME");
    for (var i = 0; i < iframes.length; i++)
    {
        if (iframes[i].contentWindow != window)
           continue;

        obj = iframes[i];
        while (obj.offsetParent)  
        {  
            result.left += obj.offsetLeft;  
            result.top += obj.offsetTop;  
            obj = obj.offsetParent;
        }  
    }

    return result;
};

floatingMenu.doFloatSingle = function(item)
{
    this.findSingle(item);

    var stepX, stepY;

    this.computeParent(item);

    var cornerX = this.calculateCornerX(item);

    var stepX = (cornerX - item.nextX) * .07;
    if (Math.abs(stepX) < .5 && item.snap
        || Math.abs(cornerX - item.nextX) == 1)
    {
        stepX = cornerX - item.nextX;
    }

    var cornerY = this.calculateCornerY(item);

    var stepY = (cornerY - item.nextY) * .07;
    if (Math.abs(stepY) < .5 && item.snap
        || Math.abs(cornerY - item.nextY) == 1)
    {
        stepY = cornerY - item.nextY;
    }

    if (Math.abs(stepX) > 0 ||
        Math.abs(stepY) > 0)
    {
        item.nextX += stepX;
        item.nextY += stepY;
        this.move(item);
    }
};

floatingMenu.fixTargets = function()
{
};

floatingMenu.fixTarget = function(item)
{
};

floatingMenu.doFloat = function()
{
    this.fixTargets();
    for (var i=0; i < floatingArray.length; i++)
    {
        this.fixTarget(floatingArray[i]);
        this.doFloatSingle(floatingArray[i]);
    }
    setTimeout('floatingMenu.doFloat()', 20);
};

floatingMenu.insertEvent = function(element, listener, handler)
{
    var oldHandler = element[listener];
    element[listener] = function (e)
        {
            e = (e) ? e : window.event;
            var result = handler(e);
            return (oldHandler != undefined) 
                && (oldHandler(e) == true)
                && (result == true);
        };
};

floatingMenu.init = function()
{
    floatingMenu.fixTargets();

    for (var i=0; i < floatingArray.length; i++)
    {
        floatingMenu.initSingleMenu(floatingArray[i]);
    }

    setTimeout('floatingMenu.doFloat()', 100);
};

// Some browsers init scrollbars only after
// full document load.
floatingMenu.initSingleMenu = function(item)
{
    this.findSingle(item);
    this.computeParent(item);
    this.fixTarget(item);
    item.nextX = this.calculateCornerX(item);
    item.nextY = this.calculateCornerY(item);
    this.move(item);
};

floatingMenu.insertEvent(window, 'onload', floatingMenu.init);

Open in new window


0
 
LVL 21

Expert Comment

by:Kim Walker
Comment Utility
There's a good chance that your global variable "i" in the blink function is getting changed by another function. Try using something more unique for that incremental variable.
0
 

Author Comment

by:naryan109
Comment Utility
Doesn't seem to work.  The scolling div code still doesn't seem to work.
0
 
LVL 15

Expert Comment

by:Eyal
Comment Utility
can we get a link?
0
 

Author Comment

by:naryan109
Comment Utility
Yes, here you go.  You'll see the scrolling div on the right.  When a product is added, the new row in the table in the scrolling div will blink a couple of times to alert the user the product has been added.  At the moment the blinking code is not on the page as I need the scrolling div to work.
http://www.therawchocolateshop.com/shop.asp
0
 
LVL 21

Expert Comment

by:Kim Walker
Comment Utility
Both of these appear to be window.onload events. You may want to make the latter on a "+=" instead. "=" will overwrite any previous onload event. I believe "+=" would add an event.

The recommended method of adding event listeners is to use the "addEventListener" method which is non-destructive to other event listeners on the same object. Unfortunately, IE <8 doesn't support this method; it uses "attachEvent" instead. Example:

if (window.addEventListener) {
   obj.addEventListener('load',functiontoexecute,'false');
} else if (window.attachEvent) {
   obj.attachEvent('onload',functiontoexecute);
} else {
   obj.onload += functiontoexecute;
}

Open in new window

0
 
LVL 21

Expert Comment

by:Kim Walker
Comment Utility
Another thing I noticed is that this is not an element with id "blink" which the blink function is looking for. This would cause the blink function to produce an error which might also prevent the scroll menu function from executing.
0
 

Author Comment

by:naryan109
Comment Utility
Thanks for the ideas.  I have a couple of questions to clarify.  With regards to the id of the element in question, there is some vbscript code to name only the last created row in the table as 'blink'.  I disabled that when tinkering with ideas, but it is on again now.  I don't think that is the cause of the problem.

I'm not sure how to apply your solution i.e. making a script '+=' as opposed to just '='.  Could say which line you are referring to?

Also, as I don't normally work with javascript, the EventListener bit went over my head; I would need a little more guidance on that to implement it.  Thanks.
0
 
LVL 21

Expert Comment

by:Kim Walker
Comment Utility
On line 3 of your blink script you have:

window.onload=function() { ...

Open in new window


Then on line 372 your scrolling menu script, in the floatingMenu.insertEvent function definition, you have:

    element[listener] = function (e) ...

Open in new window


Then on line 406 of your scrolling menu script you have:

floatingMenu.insertEvent(window, 'onload', floatingMenu.init);

Open in new window


When the arguments of line 406 are inserted in the function definition on 372 that equates to:

window['onload'] = function (e) ...

Open in new window


These two routines are canceling out one another. For simplicity, I suggest changing the "=" on line 3 of your blink routine AND on line 372 of your scrolling menu routine to "+=". Then, in both cases, the new "onload" routine will be added to the window.onload event instead or replacing what's already there.
0
 

Author Comment

by:naryan109
Comment Utility
I afraid it didn't work.  If I even change just the scrolling div script to '+=' then it that script ceases to work.  If I leave the scrolling div script as it was and just change the blink script to '+=' then that too results in the scrolling div script not working.  
0
 
LVL 21

Expert Comment

by:Kim Walker
Comment Utility
1. Which script comes first?

2. There are lots of working parts of the scrolling menu. Exactly which part isn't working?

3. Can you post the broken page with both scripts included?
0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 

Author Comment

by:naryan109
Comment Utility
1. The scrolling menu script in the <HEAD>.  The blink script is just before </BODY> at the end of the page.
2.  The div itself does not move down when user scrolls down page.  I am not able to elucidate further about which part exactly as I cannot understand the script.
3. I'm not sure if it's useful, but I've uploaded this practice page http://www.therawchocolateshop.com/shop2.asp.  In the head you'll see a reference to the include file for the scrolling div called floatingbag2.js.  In both the blink script and the scrolling div, I have left the ='s as +='s, if you know what I mean.
0
 
LVL 21

Expert Comment

by:Kim Walker
Comment Utility
I looked at the page you have linked above. But I don't see the blink script and the scroll menu appears to be working.
0
 

Author Comment

by:naryan109
Comment Utility
The scrolling div is not working for me when testing on Firefox 7.0.1 or IE8 in that when I scroll down the page is does not follow me on the right hand side.  What brower are you using? The blink script is on line 3032 if you view source code.
0
 
LVL 21

Expert Comment

by:Kim Walker
Comment Utility
I'm using Firefox 3.5 and 3.6 on Macintosh and Windows. (I'm still waiting for a stable new release. I can't believe they've released 4 unstable versions in less than a year!) I've also tested it in 6.0 on Windows. All these have performed as I have expected, however...I'm assuming that the empty shopping bag is not supposed to scroll.

I have confirmed that the blink script is present on the initial version of the page with the empty shopping bag. Of course, there's nothing here to blink, so whether the script works or not is irrelevant. I've searched the source code and found the word blink only in the function definition.

However, when I add an item to the shopping cart and the page reloads, the blink script is not included in the reloaded page. I've searched again for the word "blink" in the source code and it is only found in one place which is the id of the newly added line item in the "scrolling" shopping bag.

Have you considered using local javascript to manage the shopping bag until checkout time? Submitting and reloading the page is slow and choppy. You could also use AJaX if you need to maintain the shopping cart on the server.
0
 

Author Comment

by:naryan109
Comment Utility
Ok, the shopping bag is supposed to scroll whether it's empty or not (just to confirm, by shopping bag I am referring to the box on the right titled Your Bag where the new rows are added).  I would imagine that even after you tried adding a product the shopping bag div would not scroll down, right?

The addition of the row with the id 'blink' is correct and as it should be.

I know that using javascript and AJAX would provide a smoother experience but it's currently outside the realms of my knowledge and unfortunately I'm unable to allocate the time to learning more right now.  So I'm stuck with good ol' ASP classic!
0
 
LVL 21

Expert Comment

by:Kim Walker
Comment Utility
I would imagine that even after you tried adding a product the shopping bag div would not scroll down, right?
Wrong. There is no blink script in the page with items in the shopping bag, so it DOES scroll.

The addition of the row with the id 'blink' is correct and as it should be.
Yes. But that addition is pointless without the blink script which disappears when an item is added to the shopping bag.

I'll look into the non-scrolling empty bag sometime after lunch.
0
 

Author Comment

by:naryan109
Comment Utility
Oops, I think I've spotted something: be careful of the page name after adding a product; it reloads shop.asp not shop2.asp, so you need to change that everytime you add a product.  I think that's why you think the blink script dissapears after adding a product and the div starts scrolling!  Sorry!
0
 
LVL 21

Accepted Solution

by:
Kim Walker earned 250 total points
Comment Utility
The "+=" is not working. It's concatenating the two onload functions into a malfunctioning mess. I had read once that it was possible to do this. I guess there's a limit to its usefulness.

There are two options. One is to add the blink onload function to the scrolling shopping bag function as such: Add line 4 from your blink function to the floatingmenu.init function of the scrolling shopping bag script and remove lines 3-5 of your blink script (line 1 below is actually line 382 from your scrolling shopping bag script). You will also have to move lines 6-18 of your blink script into the external javascript file that contains the floating menu functions to prevent the as yet unknown function from generating an error. This way the floatingmenu.init function will execute both the scrolling shopping bag and the blink script when the window loads.

floatingMenu.init = function()
{
    floatingMenu.fixTargets();

    for (var i=0; i < floatingArray.length; i++)
    {
        floatingMenu.initSingleMenu(floatingArray[i]);
    }

    setTimeout('floatingMenu.doFloat()', 100);
    timer = setInterval('blink()', 1000);            // activate blink function
};

Open in new window


The alternative is to replace lines 3-5 of your blink function with the following (this only works if the blink script is executed last).

if (window.attachEvent) {
   window.attachEvent('onload',function(){timer=setInterval('blink()',1000);});
} else {
   window.addEventListener('load',function(){timer=setInterval('blink()',1000);},false);
}

Open in new window


I can't test this here so if there's a problem after you make the changes, post the new file so I can see what's going on and where I've erred in my code.
0
 
LVL 21

Expert Comment

by:Kim Walker
Comment Utility
Correction: move lines 2 AND 6-8 to the external javascript file in the first option.
0
 

Author Comment

by:naryan109
Comment Utility
Looks like it's being quite stubborn - the div still won't scroll down.  The changes were made and can be viewed using the same page names.  Whether the blinking actually happens or not, we cannot see of course as the page reloads to shop.asp after product added, but that's almost secondary until the scrolling script works...

I wasn't exactly sure where to put the blink script so I put it after the init script.
0
 
LVL 21

Expert Comment

by:Kim Walker
Comment Utility
Change the "+=" on line 372 back to an "=" as follows:

    element[listener] = function (e)

Open in new window


and let's see what happens.
0
 

Author Closing Comment

by:naryan109
Comment Utility
That's it! it works in all its glorious technicolour.  I have implemented it on the main shop.asp page so you can see it working.  I know it's a bit cheesy, but it works and was needed to avoid any confusion.  At least it's not flashing yellow and green continuously at the user.

So, thank you very much, I sincerely appreciate your persistence with this and I think I've learnt a little more javascript in the process which I know I need.
0
 
LVL 21

Expert Comment

by:Kim Walker
Comment Utility
Whew! I'm glad I could help.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

The task A number given should be formatted for easy reading by separating digits into triads. Format must be made inline via JavaScript, i.e., frameworks / functions are not welcome. So let’s take a number like this “12345678.91¿ and format i…
This article discusses the difference between strict equality operator and equality operator in JavaScript. The Need: Because JavaScript performs an implicit type conversion when performing comparisons, we have to take this into account when wri…
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now