user2507818
user2507818

Reputation: 3047

issue with one custom ToggleClass() in jquery

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<style>
.bold {
    font-weight: bold;
}

.blue {
    color: blue;
}
</style>

<a href="javascript:void(0);" onclick="ToggleClass();">Toggle class</a>

<script type="text/javascript">
function ToggleClass()
{        
    if($(this).hasClass("bold"))
    {
        $(this).removeClass("bold");
    }
    else
    {
        $(this).addClass("bold");
    }
}
</script>

Question:

I made one function: ToggleClass, but it does not work, what is the problem?

Upvotes: 3

Views: 682

Answers (6)

Fabr&#237;cio Matt&#233;
Fabr&#237;cio Matt&#233;

Reputation: 70199

You're using an inline onclick handler. Your HTML:

onclick="ToggleClass();"

Is interpreted similarly to:

element.onclick = function(event) {
    //`this` is available inside the onclick method
    ToggleClass(); //but it is not passed to called functions automatically
}

You're just calling a function, hence the this reference is not set inside this ToggleClass execution. By "not set", I mean in the ES aspect: entering function code with an undefined this means that the this reference will point to the window object, or undefined when in strict mode.

One way to set the this reference for a function execution context is using Function.call or Function.apply:

onclick="ToggleClass.call(this, event);"

Read more about the this keyword here.

*event is not necessary with your code, but event handlers usually expect to receive an event object hence I'm passing it anyway.


However, you're already using jQuery, which sets the this reference inside event handlers and wraps the event object to make its methods cross-browser. Hence you can just add a JS hook to your element and attach listeners through jQuery:

<a href="#" class="js-toggleClass">Toggle class</a>
<script>
$('.js-toggleClass').click(function(e) {
    e.preventDefault();
    $(this).toggleClass('bold');
});
</script>

Demo

I've replaced your href="javascript:void(0)" with the jQuery Event object's preventDefault() method as JavaScript does not belong inside href attributes, and used the jQuery .toggleClass() method to simplify your logic as well.

The pros of this is the separation between structure (HTML) and behavior (JS), thus keeping your code much more organized and modularized.

Upvotes: 1

Arun P Johny
Arun P Johny

Reputation: 388436

Using jQuery the implementation should be as simple as using the .toggleClass() utility method:

<a href="#" id="toggleme">Toggle class</a>
<script type="text/javascript">
jQuery(function($)
{
    $('#toggleme').click(function()
    {
        $(this).toggleClass('bold');
    });
});
</script>

Upvotes: 1

Ja͢ck
Ja͢ck

Reputation: 173662

The reason why it doesn't work is two-fold:

No explicit binding

You're using inlined code:

<a href="javascript:void(0);" onclick="ToggleClass();">Toggle class</a>

Even though the code inside the onclick parameter is run in the right context, the function call gets invoked in the context of window, i.e. inside ToggleClass(), by default, this refers to window; it's as if ToggleClass.call(window) was written. You can bind the function to another object if you wish:

<a href="javascript:void(0);" onclick="ToggleClass.call(this);">Toggle class</a>

Using .call() you bind the current element to the function and it will work as expected.

Not enough jQuery

You're not doing things in the jQuery way.

<a href="#" class="toggle-bold">Toggle class</a>
...
<script>
jQuery(function($) {
    $('.toggle-bold').on('click', function() {
        $(this).toggleClass('bold');
        return false; // prevent navigation to #
    });
});
</script>

I've removed the href="javascript:void(0);" and the inlined code. Instead, I've added a class to target the anchor; if the link only occurs once inside the document, you may want to consider a unique identifier. The click handler is attached once the document is ready.

To prevent the browser from adding that pesky # at the end, I'm returning false from the click handler to stop event propagation.

Lastly. instead of hasClass(), addClass() and removeClass() I'm using toggleClass().

Upvotes: 2

Sonu Sindhu
Sonu Sindhu

Reputation: 1792

Send current object in toggleClass() function like this :

ToggleClass(this)

Toggle class

<script type="text/javascript">
function ToggleClass(abc)
{        
        if($(abc).hasClass("bold"))
                $(abc).removeClass("bold");
        else
                $(abc).addClass("bold");
}
</script>

i hope it will help you

Upvotes: -2

Priya Gund
Priya Gund

Reputation: 156

You are calling function ToggleClass(), but yoy are not passing parameter when calling ToggleClass() function , Pass Reference when calling ToggleClass(), otherwise buildin function exists in JQuery.

Upvotes: -2

bipen
bipen

Reputation: 36551

you need to send reference to the calling function

 ... onclick="ToggleClass(this);"...


<script type="text/javascript">
function ToggleClass(obj)
{        
    if($(obj).hasClass("bold"))
            $(obj).removeClass("bold");
    else
            $(obj).addClass("bold");
}

however i always prefer using click function rather than inline javascript

 <a href="javascript:void(0);" id="ToggleClass">Toggle class</a>

<script>
   $('#ToggleClass').click(function(){
      if($(this).hasClass("bold"))
            $(this).removeClass("bold");
    else
            $(this).addClass("bold");
  });
</script>

Upvotes: 1

Related Questions