0

I have this jQuery code that I wrote to load a plugin I've been developing.

I'm fairly new to this so this question might seem a little basic but I just can't get my head around how to clean up this code? Is there a way to reduce this into something a little lighter?

Basically 'a' shows the div (target) and .mv, .sb & .sl are all classes of 'a' tags. Depending on which link is click will depend on what displays (the spot_id changes the data loaded from the plugin).

The code works fine but I'm sure there's an easier way to write this. Thanks in advance!

$('a').click(function () {
    $(this).attr("href");
});

$('.mv').click(function () {
    $(this).surfplugin({
        spot_id: 1
    });
});

$('.sb').click(function () {
    $(this).surfplugin({
        spot_id: 2
    });
});

$('.sl').click(function () {
    $(this).surfplugin({
        spot_id: 3
    });
});

HTML:

    <ul class="nav">
                <li class="mavericks">
                    <a href="#display" class="mv">Mavericks</a>
                </li>
                <li class="santa-barbara">
                    <a href="#display" class="sb">Santa Barbara</a>
                </li>
                <li>
                    <a href="#display" class="sl">Steamer Lane</a>
                </li>
            </ul>
        <div class="content">
            <section id="display" class="beach"></section>
        </div>
LT86
  • 635
  • 2
  • 15
  • 29

6 Answers6

9

Use [data-*] attributes to store the data you're passing to the plugin, and use .data() to access the autocasted value of the [data-*] attribute. It's possible that you may want to use .attr() in some instances to prevent autocasting.

I will assume the following HTML as it wasn't provided:

HTML:
<a href="..." class="mv" data-spot-id="1">...</a>
<a href="..." class="sb" data-spot-id="2">...</a>
<a href="..." class="sl" data-spot-id="3">...</a>
JS:
$('[data-spot-id]').on('click', function () {
    $(this).surfplugin({
        spot_id: $(this).data('spotId')
    });
});

Alternatively, if you have more configuration options to pass to surfplugin, you could have the [data-*] attribute contain JSON:

HTML:
<a href="..." data-surfplugin='{"spot_id":1,"foo":"bar baz"}'>...</a>
JS:
$('[data-surfplugin]').on('click', function () {
    $(this).surfplugin($(this).data('surfplugin'));
});
Community
  • 1
  • 1
zzzzBov
  • 174,988
  • 54
  • 320
  • 367
0

The usefulness of this is debatable, as you've only three callbacks, but you can use a simple mapping of elements to "spot id"s:

var spots = [];
spot[1] = '.mv';
spot[2] = '.sb';
spot[3] = '.s1';

for (var i = 0; i < spot && spot[i]; ++i) {
  (function (i) {
    $(spots[i]).click(function () {
      $(this).surfplugin({ spot_id: i });
    });
  })(i);
}
user229044
  • 232,980
  • 40
  • 330
  • 338
0

You could use an html5 data-attribute to reduce the code to something like this;

$('.mv,.sl,.sb').click(function () {
    $(this).surfplugin({
        spot_id: $(this).attr('data-spot_id');
    });
});
GrahamB
  • 589
  • 1
  • 6
  • 19
0

Try this:

var selectors = ['.mv', '.sb', '.sl'];
$(selectors.join(', ')).on('click', function() {
    $(this).surfplugin({
        spot_id: selectors.indexOf('.'+this.getAttribute('class')) + 1 
    })
});
Vadim
  • 8,701
  • 4
  • 43
  • 50
0

What about... (work when only single class)

$(document).on('click','.mv, .sb, .sl',function () {
    var class = $(this).attr('class');
    var list = ['mv','sb','sl'];
    var i = $.inArray(class,list);
        i = i!==-1?i+1:false;
    if(i) {
        $(this).surfplugin({spot_id:i});
    }
});
l2aelba
  • 21,591
  • 22
  • 102
  • 138
0

Another twisted suggestion :

$('.mv,.sb,.sl').click(function () {
    var $el = $(this),
        re = /(^|\s)(mv|sb|sl)(\s|$)/,
        cls = $el.attr('class').match(re)[2],
        map = { mv: 1, sb: 2, sl: 3 };
    $el.surfplugin({
        spot_id: map[cls]
    });
});