5

I created a custom button with a div that has a unique border style. I'm trying to handle 'mousedown' to toggle border colours to give the illusion of indent. Then handle 'mouseup' to toggle back to default.

The issue is when the mouse leaves the button and 'mouseup' is fired it's not handled by the div anymore. I tried intercepting 'mouseleave', I've tried adding a data attribute for when clicked (that won't update), I've tried adding a temporary class with .addClass called "imclicked" (couldn't get that to work).

I'm really struggling.

This is my code so far:

function ToggleBorder() {
    // Get Border Colours
    //-----------------------------------
    var top    = $(this).css("borderTopColor"),
        right  = $(this).css("borderRightColor"),
        bottom = $(this).css("borderBottomColor"),
        left   = $(this).css("borderLeftColor");

    // Assign new Colours
    //-----------------------------------
    $(this).css("borderTopColor", bottom);
    $(this).css("borderLeftColor", right);
    $(this).css("borderBottomColor", top);
    $(this).css("borderRightColor", left);
}

$(".main-nav-button").mousedown(ToggleBorder);

$(".main-nav-button").mouseup(ToggleBorder);

$(".main-nav-button").mouseleave(function() {
    // test for mousedown
});

What can I do to toggle back to the default border on mouseleave?

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
Lightfooted
  • 799
  • 1
  • 6
  • 13
  • Have you tried to change $(".main-nav-button").mouseup(ToggleBorder); to $(document).mouseup(ToggleBorder); and then execute toggleborder on each button you have on the page with an .each()? – nowhere Jun 30 '15 at 09:06
  • I need to find which button was clicked. If I toggle on all of the buttons, one will be default and the rest will be inverted. – Lightfooted Jun 30 '15 at 09:15

1 Answers1

2

I would use the addClass()/removeClass() approach on this one.

First, define the 'default' class and an 'active' class:

.main-nav-button {
    border: 1px solid red;
    border-color: red blue green yellow;
}
.main-nav-button.active {
    border-color: green yellow red blue;
}

Then you add this class on mousedown(), and remove it on mouseup(). Note that I also added mouseout(). It will remove the class when you leave the div with your mouse (also when mousedown is active).

$(function(){
    $(".main-nav-button")
    .mouseup(function() { $(this).removeClass('active'); })
    .mouseout(function() { $(this).removeClass('active'); })
    .mousedown(function() { $(this).addClass('active'); });
});

DEMO

$(function(){
    $(".main-nav-button")
    .mouseup(function() { $(this).removeClass('active'); })
    .mouseout(function() { $(this).removeClass('active'); })
    .mousedown(function() { $(this).addClass('active'); });
});
.main-nav-button {
    float: left;
    padding: 1em;
    border: 5px solid red;
    border-color: red blue green yellow;
}
.main-nav-button.active {
    border-color: green yellow red blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main-nav-button">Button</div>

EDIT

Based on your comment, to make it dynamicly. The only thing you need to check when the cursor leaves is if the mousedown event is triggered. To do so, I've added an active class to it.

$(function () {
    function toggle(elem) {
        var top = elem.css("borderTopColor"),
            right = elem.css("borderRightColor"),
            bottom = elem.css("borderBottomColor"),
            left = elem.css("borderLeftColor");

        elem.css("borderTopColor", bottom);
        elem.css("borderLeftColor", right);
        elem.css("borderBottomColor", top);
        elem.css("borderRightColor", left);
    }

    $(".main-nav-button")
    .mousedown(function () {
        toggle($(this));
        $(this).addClass('active');
    })
    .mouseup(function () {
        toggle($(this));
        $(this).removeClass('active');
    })
    .mouseout(function () {
        if( $(this).hasClass('active') ) {
            toggle($(this));
            $(this).removeClass('active');
        }
    });
});

$(function () {
    function toggle(elem) {
        var top = elem.css("borderTopColor"),
            right = elem.css("borderRightColor"),
            bottom = elem.css("borderBottomColor"),
            left = elem.css("borderLeftColor");

        elem.css("borderTopColor", bottom);
        elem.css("borderLeftColor", right);
        elem.css("borderBottomColor", top);
        elem.css("borderRightColor", left);
    }

    $(".main-nav-button")
    .mousedown(function () {
        toggle($(this));
        $(this).addClass('active');
    })
    .mouseup(function () {
        toggle($(this));
        $(this).removeClass('active');
    })
    .mouseout(function () {
        if( $(this).hasClass('active') ) {
            toggle($(this));
            $(this).removeClass('active');
        }
    });
});
.main-nav-button {
    float: left;
    padding: 1em;
    margin: 1em;
    border: 5px solid red;
    border-color: red blue green yellow;
}
.main-nav-button.nr2 {
    border-color: purple orange cyan black;  
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main-nav-button">Button</div>
<div class="main-nav-button nr2">Button</div>
GreyRoofPigeon
  • 17,833
  • 4
  • 36
  • 59
  • I was hoping not to create 2 different classes for each button, as the buttons and each side of the border are different colours. I would end up with 8 different css classes instead of 4 – Lightfooted Jun 30 '15 at 09:26
  • @James, this does handle the mouse leaving *"This event is sent to an element when the mouse pointer leaves the element. Any HTML element can receive this event."* [Source](https://api.jquery.com/mouseleave/). Let me rewrite the function for the dynamic – GreyRoofPigeon Jun 30 '15 at 09:29