user2454455
user2454455

Reputation:

highlight all class when one of the class member is hovered

*HTML
<div id='board'>
    <div>abc<span class='curly1'>{</span></div>
    <div>'jkl'm<span class='curly2'>{</span>no<span class='curly2'>}</span></div>
    <div><span class='curly2'>}</span></div>
</div>

This is for my code editor project, i want to achieve something like a notepad++ feature, highlighting the paired braces like {}, (), [], '', "". How will you say this in css,js or using jquery?

The logic is to have something like this:

$(.curly1).hover(function(){
    //all class under curly1.css('background-color', 'red');
});

Upvotes: 1

Views: 202

Answers (4)

haoudoin
haoudoin

Reputation: 151

Here is the JSFiddle: http://jsfiddle.net/haoudoin/rzp6b/

Assuming that you are generating the curls dynamically and that you are able to keep count of the curls, I recommend using a combination of ID's and CSS Classes along with a numbering system, to give it some semantics and grouping. It will also help us with the DOM manipulation. So, here is the my recommended HTML:

    <div id='board'>
        <div>public class MyObject()<span id='open-curly1' class='curly curly1'>{</span>
        </div>
        <div>public void setKey()<span id='open-curly2' class='curly curly2'>{</span>return true;<span id='close-curly2' class='curly curly2'>}</span></div>
        <div>public void setValue()<span id='open-curly3' class='curly curly3'>{</span>return true;<span id='close-curly3' class='curly curly3'>}</span></div>
        <div><span id='close-curly1' class='curly curly1'>}</span>
        </div>
    </div>

Here is the hover class for your CSS:

    .hover {
        background-color: red;
    }

Here is the voodoo magic in jQuery:

$(document).ready(function() {
    // get the curls
    var $curls = $("#board .curly");
    console.log($curls.length);
    // get the number of match & unmatched curls (Math.ceil)
    var curlyCount = Math.ceil($curls.length / 2);
    console.log(curlyCount);
    // systematically add a hover to each pair of matched curls and the unmatched
    for (var i = 1; i <= curlyCount; i++) {
        addCurlyHover(".curly" + i);
    }
});

function addCurlyHover (curlyClass) {
    // get the closing and opening curl, because they have a common class name
    // for example: .curly1
    $(curlyClass, "#board").hover(function (event) {
        // console.log(curlyClass);
        // will look for curly spans every time,in case braces are removed or added and reference is lost
        $(curlyClass).each(function (index) {
            $(this).addClass("hover");
        });
    }, function (event) {
        // console.log(curlyClass);
        $(curlyClass).each(function (index) {
            $(this).removeClass("hover");
        });
    });
}

Upvotes: 1

federicot
federicot

Reputation: 12341

I'd recommend using a unique class for all block delimiters (e.g. delimiter) and then another attribute to store their match (e.g. data-match).

So the spans would be like:

<span class="delimiter" data-match="7">

And in the JavaScript:

$('.delimiter').hover(function () {
    var match = $(this).attr('data-match');

    $('.delimiter').each(function () {
        if ($(this).attr('data-match') === match) {
            // Do your styling here. Maybe add a class to the element.
            $(this).css('background-color', 'red');
        }
    });
});

Upvotes: 1

Clxy
Clxy

Reputation: 525

First, I think there is an error in you html.

...
   <div><span class='curly2'>}</span></div>
</div>

will be

...
   <div><span class='curly1'>}</span></div>
</div>

Please try

$(document).ready(function() {
    $("#board").on("mouseenter mouseover", "[class^=curly]", function() {
        var className = $(this).attr('class').split(" ")[0];
        $("." + className).addClass("curlyHighlight");
    });
    $("#board").on("mouseleave mouseout", "[class^=curly]", function() {
        var className = $(this).attr('class').split(" ")[0];
        $("." + className).removeClass("curlyHighlight");
    });
});

and jsfiddle.

And, My suggestion is change class to data property, looks like

<div>abc<span data-class='curly1'>{</span></div>

then change the javascript like

var className = $(this).attr('data-class');

If the curly thing are just for left and right brace. The codes would be looks like. fiddle

*HTML
<div id='board'>
    <div>
        abc<span data-class='curly1'>{</span>
        <div>
            'jkl'm<span data-class='curly1'>{</span>no<span data-class='curly2'>}</span>
        </div>
        <div>
            'jkl'm<span data-class='curly1'>{</span>
            <div>
                'jkl'm<span data-class='curly1'>{</span>no<span data-class='curly2'>}</span>
            </div>
            <span data-class='curly2'>}</span>
        </div>
        <span data-class='curly2'>}</span>
    </div>
</div>

and I changed the logic to 1. find the paired brace. 2. change their css both.

Here are the codes

*javascript
    $(document).ready(function() {
        $("#board").on("mouseenter mouseover", "[data-class^=curly]", function() {
            var nodes = $(this).add(findPair($(this)));
            nodes.addClass("curlyHighlight");
        });
        $("#board").on("mouseleave mouseout", "[data-class^=curly]", function() {
            var nodes = $(this).add(findPair($(this)));
            nodes.removeClass("curlyHighlight");
        });
    });

    function findPair(n) {

        var nextBraces = $([]);
        var brace = n.text();
        if (brace == '{') {
            nextBraces = n.nextAll("[data-class^=curly]");
        } else if (brace == '}') {
            nextBraces = n.prevAll("[data-class^=curly]");
        }

        var count = 0;
        var result = false;
        nextBraces.each(function(index, value) {
            var v = $(value);
            if (v.text() == brace) {
                count++;
            } else if (count != 0) {
                count--;
            } else {
                result = v;
                return false;
            }
        });
        return result;
    }

Upvotes: 0

AngelWarrior
AngelWarrior

Reputation: 1390

This may not be what you're looking for, but on hover on any .curly1 element, in javascript you could grab all the .curly1 elements and add another class to them, the second class would be the highlighting class. On mouseout, remove the second class from all the .curly1 elements.

Using YUI, it looks like this:

var curlyNodes = Y.all('.curly1');
curlyNodes.on('mouseenter', function(){
    curlyNodes.addClass('highlight');
});
curlyNodes.on('mouseleave', function(){
    curlyNodes.removeClass('highlight');
});

Upvotes: 0

Related Questions