Combining multiple jQuery functions

Is there a way to combine all of this to reduce the amount of js? This is just an example of some jquery dialogs I have on my site, there are a few more. Thanks.

//initiate Search refinement dialog here
$("#chooseMoreCnt, #chooseMoreCat, #chooseMorePr").dialog({
    bgiframe: true,
    autoOpen: false,
    width: 500,
    modal: true,
    open: function(type, data) {
        $(this).parent().appendTo(jQuery("form:first"));
    }
});

//trigger country dialog
$('a.chooseMoreCnt').click(function() {
    $('#chooseMoreCnt').dialog('open');
    return false;
});

//trigger category dialog
$('a.chooseMoreCat').click(function() {
    $('#chooseMoreCat').dialog('open');
    return false;
});

//trigger price dialog
$('a.chooseMorePr').click(function() {
    $('#chooseMorePr').dialog('open');
    return false;
});

      

+2


a source to share


4 answers


If your links point to the IDs of the dialog elements, and if you add a meta-class choose

to each of them, you can combine the last three calls with:

$('a.choose').click(function() {
    $(this.hash).dialog('open');
    return false;
});

      

The HTML for one of these links is the most semantically correct and even works with JS disabled (assuming there are dialogs):

<a href="#chooseMoreCat" class="choose">Choose more categories</a>

      

Explanation of the part this.hash

:

  • this

    in the context of an event handling function, jQuery is always the element on which the event occurred. In our case, this is a clicked link. Note that this is a DOM node and not a jQuery element.

  • this.hash

    : DOM nodes corresponding to HTML elements <a/>

    have certain special properties that allow you to access the target they are bound to. The property hash

    is everything after the character #

    (and including) in the URL. In our case, if the link points to elements that should become dialog boxes, it looks like a string "#chooseMoreCnt"

    .

  • $(this.hash)

    is a jQuery function called, for example "#chooseMoreCnt"

    , that will pick the appropriate one div

    .

To initialize the dialog, I would go for classes too:



$(".choose_dialog").dialog({
    bgiframe: true,
    autoOpen: false,
    width: 500,
    modal: true,
    open: function(type, data) {
        $(this).parent().appendTo(jQuery("form:first"));
    }
});

      

Yes, it means changing the markup, but it also gives you freedom

  • add any number of dialog boxes

  • add any number of openers to any dialog

  • style all dialogs and dialog links consistently with minimal CSS

without touching Javascript anymore.

If dialogs are triggered differently (as pointed out in the comments), you can go to that part using the CuSS approach $.each()

and read the corresponding width inside the function from an object defined elsewhere:

var dialog_widths = {'chooseMoreCat': 400, 'chooseMorePr': 300, /*...*/ };

      

+7


a source


Here's what I would like to suggest. Provide a common DialogContent (say) class for all sections and initialize them using:

$(".dialogContent").dialog({
    bgiframe: true,
    autoOpen: false,
    width: 500,
    modal: true,
    open: function(type, data) {
        $(this).parent().appendTo(jQuery("form:first"));
    }
});

      



And of course use Boldewyn's solution for the click event (better to use live () IMHO if the situation is dynamically generated). This way you take care of all initializations and click events with less code.

NTN

0


a source


ok, it's a bit tricky to minimize. do you have more than three dialogues? If so, you can do something like this:

var dialogs=["chooseMorePr","chooseMoreCat","chooseMoreCnt"];
$.each(dialogs,function(i,v){
    $('a.'+v).click(function(){$('#'+v).dialog('open');});
});

      

-1


a source


To optimize performance, you should use live when connecting to multiple items. Below is my approach to the problem. The solution is dynamic (add as many dialogs as you want) and very fast.

Remember to change #anyParentOfTheLinks to the parent div, or in the worst case, remove it, and jQuery will use the document instead.

var dialogues = ['#chooseMoreCnt', '#chooseMoreCat', '#chooseMorePr'];

$(dialogues.toString()).dialog({
    // ...
});

$('a', '#anyParentOfTheLinks').live('click', function(){
    // Cache for performance
    var $this = $(this), len = dialogues.length;

    for(var i = 0; i < len; i++)
        if($this.is('.' + dialogues[i].substr(1))) {
            $this.dialog('open');
            break;
        }

    return false;
});

      

-1


a source







All Articles