SitePoint Sponsor

User Tag List

Results 1 to 9 of 9
  1. #1
    SitePoint Member
    Join Date
    Apr 2011
    Posts
    23
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Background color for elements inside each other

    I was wondering how to split the elements inside each other, so that each of them has its own background color. What I'm trying to do is to highlight background of each element onmouseover. Up till now I haven't managed to do it properly - for example, I have a table cell with a hyperlink inside it. When I point to the cell - background changes, however, pointing to the hyperlink leaves the cell coloured - which is what I don't want. Look at what I'm trying to do:
    http://img825.imageshack.us/img825/4371/20613904.png

    I'm trying to use this code:

    HTML Code:
    onMouseOver="this.style.backgroundColor='yellow';" onMouseOut="this.style.backgroundColor='white';"
    Any suggestions?

  2. #2
    It's all Geek to me silver trophybronze trophy
    ralph.m's Avatar
    Join Date
    Mar 2009
    Location
    Melbourne, AU
    Posts
    24,333
    Mentioned
    463 Post(s)
    Tagged
    8 Thread(s)
    This is better done with CSS.

    Quote Originally Posted by dante7 View Post
    When I point to the cell - background changes, however, pointing to the hyperlink leaves the cell coloured - which is what I don't want.
    I'm not really clear on what you do want. Could you explain more clearly what you want to hapen 1) which you hove over the cell (but not the link) and 2) what should happen when you hver over the link.

  3. #3
    SitePoint Member
    Join Date
    Apr 2011
    Posts
    23
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I've hosted an example file (example.html) to show what I'm trying to do. Hope it'll be clear now.
    http://www.2shared.com/document/w_BuGU9N/example.html

  4. #4
    It's all Geek to me silver trophybronze trophy
    ralph.m's Avatar
    Join Date
    Mar 2009
    Location
    Melbourne, AU
    Posts
    24,333
    Mentioned
    463 Post(s)
    Tagged
    8 Thread(s)
    You can just post full page code like that right here, so let me do it to save other following your link:

    Code:
    <!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" />
    <title>Untitled Document</title>
    </head>
    
    <body>
    
    <table width="100%" border="1" height="200">
    	<tr>
        	<td><a href="#" onMouseOver="this.style.backgroundColor='yellow';" onMouseOut="this.style.backgroundColor='#FFFFFF';">Highlight a link on mouseover</a></td>
            <td onMouseOver="this.style.backgroundColor='yellow';" onMouseOut="this.style.backgroundColor='#FFFFFF';">Highlight a cell on mouseover</td>
    
    		<td onMouseOver="this.style.backgroundColor='yellow';" onMouseOut="this.style.backgroundColor='#FFFFFF';"><a href="#" onMouseOver="this.style.backgroundColor='yellow';" onMouseOut="this.style.backgroundColor='#FFFFFF';">Now highlight a cell when I hover over it -> working.<br />
    When I hover over link - highlight it, stop higlighting cell -> doesn't work</a></td>
        </tr>
    </table>
    
    </body>
    </html>
    OK, what you are trying to do here is affect a parent element on the basis of a child, which you can't really do with CSS, so you may have to stick with JS. I'll move this thread to the JS forum.

  5. #5
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by ralph.m View Post
    OK, what you are trying to do here is affect a parent element on the basis of a child, which you can't really do with CSS, so you may have to stick with JS. I'll move this thread to the JS forum.
    Thanks Ralph.

    Dante, what you can do is to remove the inline HTML attributes for the events, and move them out to where they belong as scripting code.

    We'll put an id attribute on each td, just for the purposes of testing this. We should be able to get rid of most of them by the time we finish this.

    HTML Code:
    <td id="first"><a href="#">Highlight a link on mouseover</a></td>
    <td id="second">Highlight a cell on mouseover</td>
    <td id="third"><a href="#">Now highlight a cell when I hover over it -> working.<br />...</a></td>
    At the end of the body, just before the </body> tag, is where we put the script. That allows the script to easily work with elements on the page before the page is loaded.

    HTML Code:
    <body>
        ...
        <script type="text/javascript" src="js/script.js"></script>
    </body>
    The script.js file will contain the scripting that we do.

    In that script we want to gain a reference to each of the parts you're testing there, and to set the mouseover background. Because that's a behaviour that will be common to several elements on the page, we'll use a single function to set up each element.

    Code javascript:
    function initMouseoverBackground(el, color) {
        el.onmouseover = function () {
            this.style.backgroundColor = color;
        };
        el.onmouseout = function () {
            this.style.backgroundColor = '';
        };
    }

    Notice how on mouseout we're not setting the color to white, but are clearing the backgroundColor setting? This is because javascript is creating a whole new set of CSS declarations in a style attribute on the element, so removing the backgroundColor setting from that inline style attribute allows the element to revert back to what it was before.

    Now we can use that initMouseoverBackground function to set up the mouseover behaviour for each element.

    Code javascript:
    var el = document.getElementById('first').getElementsByTagName('a')[0];
    initMouseoverBackground(el, 'yellow');
    el = document.getElementById('second');
    initMouseoverBackground(el, 'yellow');
    el = document.getElementById('third');
    initMouseoverBackground(el, 'yellow');
    var el = document.getElementById('third').getElementsByTagName('a')[0];
    initMouseoverBackground(el, 'yellow');

    That works on all but the third section link, because according to the way that mouseover works, it considers that you're also over all the parent elements of that link as well, which includes the td, tr, table and body elements. When you hover over the link, the mouseover event bubbles up from the link all the way up.

    You want only the link to be highlighted, so we should cancel the event from bubbling further up so that it doesn't trigger the hover on the td itself.
    We can do that by adding a parameter for the event (getting the event from window.event if we're on Internet Explorer) and cancelling the bubbling of the event.

    Code javascript:
    el.onmouseover = function (evt) {
        evt = evt || window.event;
        evt.cancelBubble = true;
     
        this.style.backgroundColor = color;
    };

    With that modification in place things now work as you seem to prefer.

    I'll follow this post with one that removes the multiple identifiers and sets up mouseover event for every element within the table.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  6. #6
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by paul_wilkins View Post
    I'll follow this post with one that removes the multiple identifiers and sets up mouseover event for every element within the table.
    Let's now remove the id attributes from all of those TD elements and put one on the TR element

    HTML Code:
    <tr id="first">
        <td><a href="#">Highlight a link on mouseover</a></td>
        <td>Highlight a cell on mouseover</td>
        <td><a href="#">Now highlight a cell when I hover over it -> working.<br />...</a></td>
    </tr>
    What we want here is to capture the hover event when it bubbles up to the TR element, and to highlight only the element that the mouse is hovering over.

    Here's how we can adjust the onmouseover event to achieve that. We get the target element from the event and highlight that element instead. That way when we hover over a link, it's the link that gets highlighted. If we hover instead over a table cell it's only that table cell that gets highlighted.

    Code javascript:
    el.onmouseover = function (evt) {
        evt = evt || window.event;
        var targ = evt.target || evt.srcElement;
        targ.style.backgroundColor = color;
    };

    Nearly identical code can be used in the initMouseoverBackground function for the onmouseout event too:

    Code javascript:
    el.onmouseover = function (evt) {
        evt = evt || window.event;
        var targ = evt.target || evt.srcElement;
        targ.style.backgroundColor = color;
    };

    The only problem now is that both functions are nearly identical, so we should extract that out to a separate function, so we can just make this call instead:

    Code javascript:
    el.onmouseover = colorTargetBackground(el, 'yellow');
    el.onmouseout = colorTargetBackground(el, '');

    That can be done by creating a colorTargetBackgroundfunction that returns a function (for the event) that uses the passed color.

    Code javascript:
    function colorTargetBackground(el, color) {
        return function (evt) {
            evt = evt || window.event;
            var targ = evt.target || evt.srcElement;
            targ.style.backgroundColor = color;
        };
    }

    So we're left with only two pieces of scripting code. An initMouseoverBackground function that has the setTargetBackgroundColor function with a couple of lines after it to attach it to the onmouseover and onmouseout events, and after the initMouseoverBackground function we also have a few lines to start setting things up.

    This is the full scripting code that we're left with after performing the above changes:

    Code javascript:
    function initMouseoverBackground(el, color) {
        function colorTargetBackground(el, color) {
            return function (evt) {
                evt = evt || window.event;
                var targ = evt.target || evt.srcElement;
                targ.style.backgroundColor = color;
            };
        }
     
        el.onmouseover = colorTargetBackground(el, 'yellow');
        el.onmouseout = colorTargetBackground(el, '');
    }
     
    var el = document.getElementById('first');
    initMouseoverBackground(el, 'yellow');
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  7. #7
    SitePoint Member
    Join Date
    Apr 2011
    Posts
    23
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Woow, what 2 great posts from you, Paul - really excellent - thanks! Perhaps then you could give some indications of what to do if I want each element on the page to have this ability to be highlighted - I understand it's a loop, but how to target every element - I have no idea. Maybe somehow dynamically adding onmouseover, onmouseout a function to each element with 'this' argument and color?

  8. #8
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by dante7 View Post
    Woow, what 2 great posts from you, Paul - really excellent - thanks! Perhaps then you could give some indications of what to do if I want each element on the page to have this ability to be highlighted - I understand it's a loop, but how to target every element - I have no idea.
    Instead of having the event attached to the TR element, you can have the event attached to document.body
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  9. #9
    SitePoint Member
    Join Date
    Apr 2011
    Posts
    23
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the quick replying and for all the help - works perfectly!!!


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •