4

I'm trying to use jQery mCustomscrollbar plugin in a VF page. I have the following code -

    <script type="text/javascript">
      $j = jQuery.noConflict();
    </script>
    <script type="text/javascript" value="{!URLFOR($Resource.myPage, 'jquery.mCustomScrollbar.concat.min.js')}"></script>
    <apex:stylesheet value="{!URLFOR($Resource.myPage, 'main.css')}"/>
    <script type="text/javascript">
        $j(document).ready(function()
        {
            $j(".news-content div.scroll").mCustomScrollbar({
                scrollInertia:400,
                mouseWheelPixels:40
            });
        });
    </script>

But the scrollbar is not working and I see the following error in my javascript console -

Uncaught TypeError: Object [object Object] has no method 'mCustomScrollbar'

Do I need to change anything in the plugin js file?

1
  • 1
    It doesn't show in your code, but is the jquery script tag above the noconflict script block?
    – drakored
    Feb 1, 2014 at 6:23

1 Answer 1

4

The "value" attribute is not valid for a <script> tag; you're thinking of the Visualforce <apex:includeScript> tag. Choose one or the other; if you use the HTML tag then the attribute you want is "src". That's why you get the error; your script is not getting loaded, and thus "mCustomScrollbar" is not written into jQuery.fn (the [object Object] cited in your error is actually a jQuery result set object, which can't find a "mCustomScrollbar" property in its inherited jQuery.fn prototype if that script file didn't load).

The use of jQuery.fn.noConflict, and avoiding usage of the global "$" reference are both good practices -- however these should not be necessary under most circumstances, even in Visualforce pages. One exception is when you use apex's tab component, which unfortunately imports an old Prototype script that also wants the global "$" symbol.

5
  • 1
    Good catch, I didn't notice that when I answered. Also worth noting the script itself is poorly written and won't work with noConflict if the OP does end up using it without some modification.
    – drakored
    Feb 1, 2014 at 6:42
  • I just now viewed the script too, and while I agree the code is far from beautiful (to be fair I've written scads of code FAR worse than this in my time), it does properly protect the global "$" symbol through use of a wrapper closure.
    – mulveling
    Feb 1, 2014 at 6:54
  • @mulveling - You and I must be reading it differently then. If noConflict is run $ no longer points to the object now known as $j (in his context) and jQuery. So calling $ inside this plugin will do nothing. That was my point, not that it was going to overwrite $, but that it is a jQuery plugin and hence needs to be able to find the actual jQuery object rather than prototype or whatever else might be using the $ variable.
    – drakored
    Feb 3, 2014 at 17:59
  • 1
    @drakored - That is what the "(function($){ /* plugin code */ })(jQuery)" wrapper does -- it uses the global jQuery symbol, which is still valid after a noConflict(), and binds its value to the formal parameter "$", which is visible only to the plugin code -- so in there, using "$" is ok because it's not binding to the global "$", but to an outer argument that is defined.
    – mulveling
    Feb 3, 2014 at 18:12
  • @mulveling - Ahh I understand now. This is still a pattern that confuses me a bit. Thanks for the explanation!
    – drakored
    Feb 3, 2014 at 18:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .