Autor Zpráva
Kcko
Profil
Ahoj,
potřebuji se zbavit multibindování.

spíchnul jsem rychlý tooltip (ajaxový) na náhled produktu. Je to funkční, nicméně pokud mám odkazy s tooltipy ve více blocích, které překresluji poté ajaxem (třeba 3 různé bloky na stránce), tak se mi to začne všechno nějak multibindovat a když najedu na odkaz s toltipem, neprovede se 1 XHR, ale třeba 4. (Když vstoupím na stránku poprvé, takže kód vykoná PHP tak je to OK, problém je tedy po ajaxu, kdy vlastně dělám pro každý blok novou instanci tooltipu).

Dočasně jsem to vyřešil vypnutím nabindovaných eventů (ztučneno dole v ukázce).
Nicméně to není ideální.

Má někdo nějaký nápad jak to udělat lépe? Nějak plugin unsetnout nebo něco co umi uniká?

var AwTooltip = (function(config) {

    this.closeTooltip = function() {
        if ($tooltip)
        {
            $tooltip.hide();
            setEmptyTooltip();
            openedTooltip = null;
        }

    };

    /* --------------------------- VARIABLES + CONFIG --------------------------- */
    config = config || {};
   
    var openedTooltip = null;
    var xhr           = null;
    var $tooltip      = config.tooltipId;
    var timeout       = config.timeout || 4000;
    var gutter        = config.gutter || 15;

    var winSize = {
        w: $(window).width(),
        h: $(window).height()
    };

    var tooltipSize = {
        w: $tooltip.outerWidth(true),
        h: $tooltip.outerHeight(true)
    };

    
    /* ------------------------------ HELPERS ------------------------------ */        
    function Timer()
    {
        this.timer = null;
    }

    Timer.prototype = {
        set: function (func,timeout){

            this.timer = setTimeout(func,timeout);
        },
        clear: function(){
            
            clearTimeout(this.timer);
        }
    }

    var Timer = new Timer();


    config.element.attr('id', function(index) {
        return 'id-' + index;
    });


    var setEmptyTooltip = function() {
        $tooltip
        .height('auto')
        .html(config.emptyTooltipContent);
    };


    /* --------------------------------- EVENTS --------------------------------- */
    $tooltip.on('mouseover.tooltip mouseout.tooltip', function(e){
        Timer.clear();

        if (e.type == 'mouseout')
        {
            Timer.set(function(){
                $tooltip.fadeOut(function() {
                    openedTooltip = null;
                    setEmptyTooltip();
                });
                
            }, timeout);
        }

    });


    config.element.on('mouseover.tooltip mouseout.tooltip', function(e) {

        e.preventDefault();
        var $this = $(this);
        var id = $this[0].id;

        if (e.type == 'mouseover')
        {
            Timer.clear();
        
            if (id == openedTooltip)
                return;

            if (xhr !== null)
                xhr.abort(); 

            $tooltip.hide();
            setEmptyTooltip();
            
            var offset = $(this).offset();
            var offsetPos = {
                x: offset.left,
                y: offset.top + 30,
            }

            // prevent overlapping on the right edge
            if (offsetPos.x + tooltipSize.w >= winSize.w)
            {
                offsetPos.x = winSize.w - tooltipSize.w - gutter;   
            }
    
            $tooltip
                .css({
                    left: offsetPos.x,
                    top: offsetPos.y
                })
                .fadeIn('fast', function () {
                    
                    xhr = $.get(config.remoteUrl ||  $this.attr('data-href'));
                    xhr.then(function(response) {
                        
                        $tooltip.html('');
                        for (var snippet in response.snippets)
                        {
                            $tooltip.append(response.snippets[snippet]);        
                        }
                        $tooltip.fadeIn();
                    });

                });

            openedTooltip = id;
        }

        else
        {
            Timer.clear();
            xhr.done(function(){
                
                Timer.set(function() {
                    $tooltip.fadeOut(function() {
                        setEmptyTooltip();
                        openedTooltip = null;                           
                    });
                    
                }, timeout); 
            });
        }

    });

});

Použití vypadá takto:
        $('.blog-product-tooltip', context).off('.tooltip');
        $('#mp-tooltip').off('.tooltip');

            var tooltip  = new AwTooltip({
                remoteUrl: null,
                tooltipId: $('#mp-tooltip'),
                element: $('.blog-product-tooltip', context),
                timeout: 400,
                gutter: 15,
                emptyTooltipContent: '<div class="mp-preloader"><img src="/assets/gfx/preloader.svg" alt="" style="width: 32px;"> Načítáme produkt ...</div>',
            });


        
    
            $(document).on('click', function (e) {
                
                $target = $(e.target);
                if ($target.closest('.product-list-box').length == 0)
                {
                    tooltip.closeTooltip();
                }
                
            });

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0