Событие jQuery для запуска действия, когда div становится видимым - PullRequest
292 голосов
/ 04 августа 2009

Я использую jQuery на своем сайте, и я хотел бы вызвать определенные действия, когда определенный div становится видимым.

Можно ли присоединить какой-то "видимый" обработчик событий к произвольным элементам div и запускать определенный код, когда элемент div становится видимым?

Я бы хотел что-то вроде следующего псевдокода:

$(function() {
  $('#contentDiv').isvisible(function() {
    alert("do something");
  });
});

Код предупреждения («сделать что-то») не должен запускаться до тех пор, пока contentDiv фактически не станет видимым.

Спасибо.

Ответы [ 21 ]

2 голосов
/ 05 июня 2014

Вы также можете попробовать jQuery появляются плагин , как указано в параллельном потоке https://stackoverflow.com/a/3535028/741782

1 голос
/ 24 апреля 2018

Я сделал простую функцию setinterval для достижения этой цели. Если элемент с классом div1 видим, он устанавливает div2 как видимый. Я знаю не хороший метод, но простое исправление.

setInterval(function(){
  if($('.div1').is(':visible')){
    $('.div2').show();
  }
  else {
    $('.div2').hide();
  }      
}, 100);
1 голос
/ 11 августа 2017

Что мне помогло, так это недавний ResizeObserver spec polyfill :

const divEl = $('#section60');

const ro = new ResizeObserver(() => {
    if (divEl.is(':visible')) {
        console.log("it's visible now!");
    }
});
ro.observe(divEl[0]);

Обратите внимание, что это кроссбраузер и производительность (без опроса).

1 голос
/ 08 декабря 2016

Это поддержка замедления и запуска события после завершения анимации! [протестировано на jQuery 2.2.4]

(function ($) {
    $.each(['show', 'hide', 'fadeOut', 'fadeIn'], function (i, ev) {
        var el = $.fn[ev];
        $.fn[ev] = function () {
            var result = el.apply(this, arguments);
            var _self=this;
            result.promise().done(function () {
                _self.triggerHandler(ev, [result]);
                //console.log(_self);
            });
            return result;
        };
    });
})(jQuery);

Вдохновленный http://viralpatel.net/blogs/jquery-trigger-custom-event-show-hide-element/

1 голос
/ 20 января 2014

Доступен плагин jQuery для отслеживания изменений в атрибутах DOM,

https://github.com/darcyclarke/jQuery-Watch-Plugin

Плагин упаковывает все, что вам нужно сделать, это привязать MutationObserver

Затем вы можете использовать его для просмотра div, используя:

$("#selector").watch('css', function() {
    console.log("Visibility: " + this.style.display == 'none'?'hidden':'shown'));
    //or any random events
});
0 голосов
/ 09 марта 2017

Надеюсь, что это сделает работу самым простым способом:

$("#myID").on('show').trigger('displayShow');

$('#myID').off('displayShow').on('displayShow', function(e) {
    console.log('This event will be triggered when myID will be visible');
});
0 голосов
/ 28 декабря 2016
$( window ).scroll(function(e,i) {
    win_top = $( window ).scrollTop();
    win_bottom = $( window ).height() + win_top;
    //console.log( win_top,win_bottom );
    $('.onvisible').each(function()
    {
        t = $(this).offset().top;
        b = t + $(this).height();
        if( t > win_top && b < win_bottom )
            alert("do something");
    });
});
0 голосов
/ 24 апреля 2014

мое решение:

; (function ($) {
$.each([ "toggle", "show", "hide" ], function( i, name ) {
    var cssFn = $.fn[ name ];
    $.fn[ name ] = function( speed, easing, callback ) {
        if(speed == null || typeof speed === "boolean"){
            var ret=cssFn.apply( this, arguments )
            $.fn.triggerVisibleEvent.apply(this,arguments)
            return ret
        }else{
            var that=this
            var new_callback=function(){
                callback.call(this)
                $.fn.triggerVisibleEvent.apply(that,arguments)
            }
            var ret=this.animate( genFx( name, true ), speed, easing, new_callback )
            return ret
        }
    };
});

$.fn.triggerVisibleEvent=function(){
    this.each(function(){
        if($(this).is(':visible')){
            $(this).trigger('visible')
            $(this).find('[data-trigger-visible-event]').triggerVisibleEvent()
        }
    })
}
})(jQuery);

пример использования:

if(!$info_center.is(':visible')){
    $info_center.attr('data-trigger-visible-event','true').one('visible',processMoreLessButton)
}else{
    processMoreLessButton()
}

function processMoreLessButton(){
//some logic
}
0 голосов
/ 20 марта 2014

Один из способов сделать это.
Работает только с изменениями видимости, которые вносятся изменениями класса css, но может быть расширен и для отслеживания изменений атрибутов.

var observer = new MutationObserver(function(mutations) {
        var clone = $(mutations[0].target).clone();
        clone.removeClass();
                for(var i = 0; i < mutations.length; i++){
                    clone.addClass(mutations[i].oldValue);
        }
        $(document.body).append(clone);
        var cloneVisibility = $(clone).is(":visible");
        $(clone).remove();
        if (cloneVisibility != $(mutations[0].target).is(":visible")){
            var visibilityChangedEvent = document.createEvent('Event');
            visibilityChangedEvent.initEvent('visibilityChanged', true, true);
            mutations[0].target.dispatchEvent(visibilityChangedEvent);
        }
});

var targets = $('.ui-collapsible-content');
$.each(targets, function(i,target){
        target.addEventListener('visibilityChanged',VisbilityChanedEventHandler});
        target.addEventListener('DOMNodeRemovedFromDocument',VisbilityChanedEventHandler });
        observer.observe(target, { attributes: true, attributeFilter : ['class'], childList: false, attributeOldValue: true });
    });

function VisbilityChanedEventHandler(e){console.log('Kaboom babe'); console.log(e.target); }
0 голосов
/ 12 июля 2013

Я изменил триггер события скрытия / показа из Catalint, основываясь на идее Гленса. Моя проблема была в том, что у меня есть модульное приложение. Я переключаюсь между модулями, показывающими и скрывающими родителей. Затем, когда я прячу модуль и показываю другой, с его методом у меня появляется видимая задержка при переключении между модулями. Мне нужно только иногда освещать это событие, а у некоторых особенных детей. Поэтому я решил уведомить только детей с классом «displayObserver»

$.each(["show", "hide", "toggleClass", "addClass", "removeClass"], function () {
    var _oldFn = $.fn[this];
    $.fn[this] = function () {
        var hidden = this.find(".displayObserver:hidden").add(this.filter(":hidden"));
        var visible = this.find(".displayObserver:visible").add(this.filter(":visible"));
        var result = _oldFn.apply(this, arguments);
        hidden.filter(":visible").each(function () {
            $(this).triggerHandler("show");
        }); 
        visible.filter(":hidden").each(function () {
            $(this).triggerHandler("hide");
        });
        return result;
    }
});

Затем, когда ребенок хочет прослушать событие «show» или «hide», я должен добавить ему класс «displayObserver», а когда он не хочет продолжать его слушать, я удаляю его класс

bindDisplayEvent: function () {
   $("#child1").addClass("displayObserver");
   $("#child1").off("show", this.onParentShow);
   $("#child1").on("show", this.onParentShow);
},

bindDisplayEvent: function () {
   $("#child1").removeClass("displayObserver");
   $("#child1").off("show", this.onParentShow);
},

Желаю помощи

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...