div가 표시 될 때 작업을 트리거하는 jQuery 이벤트
내 사이트에서 jQuery를 사용하고 있으며 특정 div가 표시되면 특정 작업을 트리거하고 싶습니다.
임의의 div에 일종의 "보이지 않는"이벤트 핸들러를 첨부하고 div가 표시 될 때 특정 코드를 실행할 수 있습니까?
다음 의사 코드와 같은 것을 원합니다.
$(function() {
$('#contentDiv').isvisible(function() {
alert("do something");
});
});
contentDiv가 실제로 표시 될 때까지 alert ( "do something") 코드가 실행되지 않아야합니다.
감사.
항상 원본 .show () 메서드에 추가 할 수 있으므로 무언가를 표시 할 때마다 또는 레거시 코드로 작업해야하는 경우 이벤트를 트리거 할 필요가 없습니다.
jquery 확장명 :
jQuery(function($) {
var _oldShow = $.fn.show;
$.fn.show = function(speed, oldCallback) {
return $(this).each(function() {
var obj = $(this),
newCallback = function() {
if ($.isFunction(oldCallback)) {
oldCallback.apply(obj);
}
obj.trigger('afterShow');
};
// you can trigger a before show if you want
obj.trigger('beforeShow');
// now use the old function to show the element passing the new callback
_oldShow.apply(obj, [speed, newCallback]);
});
}
});
사용 예 :
jQuery(function($) {
$('#test')
.bind('beforeShow', function() {
alert('beforeShow');
})
.bind('afterShow', function() {
alert('afterShow');
})
.show(1000, function() {
alert('in show callback');
})
.show();
});
이렇게하면 원래 .show () 메서드의 정상적인 동작을 계속 실행하면서 beforeShow 및 afterShow를 효과적으로 수행 할 수 있습니다.
원래 .show () 메서드를 재정의 할 필요가 없도록 다른 메서드를 만들 수도 있습니다.
이 문제는 DOM 돌연변이 관찰자들에 의해 해결되고있다 . 이를 통해 관찰자 (함수)를 컨텐츠, 텍스트 또는 dom 요소의 속성 변경 이벤트에 바인딩 할 수 있습니다.
IE11 릴리스에서는 모든 주요 브라우저가이 기능을 지원합니다. http://caniuse.com/mutationobserver를 확인하십시오 .
예제 코드는 다음과 같습니다.
$(function() {
$('#show').click(function() {
$('#testdiv').show();
});
var observer = new MutationObserver(function(mutations) {
alert('Attributes changed!');
});
var target = document.querySelector('#testdiv');
observer.observe(target, {
attributes: true
});
});
<div id="testdiv" style="display:none;">hidden</div>
<button id="show">Show hidden div</button>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
이를 위해 연결할 수있는 기본 이벤트는 없지만를 사용하여 div를 표시 한 후 스크립트에서 이벤트를 트리거 할 수 있습니다. 트리거 기능
예 :
//declare event to run when div is visible
function isVisible(){
//do something
}
//hookup the event
$('#someDivId').bind('isVisible', isVisible);
//show div and trigger custom event in callback when div is visible
$('#someDivId').show('slow', function(){
$(this).trigger('isVisible');
});
jQuery의 Live Query 플러그인을 사용할 수 있습니다 . 다음과 같이 코드를 작성하십시오.
$('#contentDiv:visible').livequery(function() {
alert("do something");
});
그런 다음 contentDiv가 표시 될 때마다 "뭔가하세요"라는 경고가 나타납니다!
redsquare의 솔루션 이 정답입니다.
그러나로 IN-이론 솔루션 당신은에 의해 분류 요소를 선택하는 기능을 쓸 수 있습니다 .visibilityCheck
( 모든 눈에 보이는 요소 )과 확인 visibility
속성 값을; 그렇다면 true
뭔가를하십시오.
그 후 기능을 사용하여 setInterval()
기능을 주기적으로 수행해야합니다 . clearInterval()
성공적인 콜 아웃을 사용하여 타이머를 중지 할 수 있습니다 .
예를 들면 다음과 같습니다.
function foo() {
$('.visibilityCheck').each(function() {
if ($(this).is(':visible')){
// do something
}
});
}
window.setInterval(foo, 100);
또한 일부 성능 개선을 수행 할 수 있지만 솔루션은 기본적으로 작동하지 않습니다. 그래서...
다음 코드 ( http://maximeparmentier.com/2012/11/06/bind-show-hide-events-with-jquery/ 에서 추출 )를 사용하면을 사용할 수 있습니다 $('#someDiv').on('show', someFunc);
.
(function ($) {
$.each(['show', 'hide'], function (i, ev) {
var el = $.fn[ev];
$.fn[ev] = function () {
this.trigger(ev);
return el.apply(this, arguments);
};
});
})(jQuery);
$ .show, toggle, toggleClass, addClass 또는 removeClass를 통해 실제로 표시되는 모든 요소 (및 하위 요소)에서 이벤트를 트리거하려면 다음을 수행하십시오.
$.each(["show", "toggle", "toggleClass", "addClass", "removeClass"], function(){
var _oldFn = $.fn[this];
$.fn[this] = function(){
var hidden = this.find(":hidden").add(this.filter(":hidden"));
var result = _oldFn.apply(this, arguments);
hidden.filter(":visible").each(function(){
$(this).triggerHandler("show"); //No bubbling
});
return result;
}
});
그리고 이제 당신의 요소 :
$("#myLazyUl").bind("show", function(){
alert(this);
});
상단의 배열에 "attr"과 같은 추가하여 jQuery 함수에 재정의를 추가 할 수 있습니다.
Glenns ideea를 기반으로 한 hide / show 이벤트 트리거 : show / hide를 발생시키고 하나의 이벤트에 대해 2fire를 원하지 않기 때문에 토글 제거
$(function(){
$.each(["show","hide", "toggleClass", "addClass", "removeClass"], function(){
var _oldFn = $.fn[this];
$.fn[this] = function(){
var hidden = this.find(":hidden").add(this.filter(":hidden"));
var visible = this.find(":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;
}
});
});
나는이 같은 문제가 있었고 우리 사이트를 위해 그것을 해결하기 위해 jQuery 플러그인을 만들었습니다.
https://github.com/shaunbowe/jquery.visibilityChanged
예제를 기반으로 사용하는 방법은 다음과 같습니다.
$('#contentDiv').visibilityChanged(function(element, visible) {
alert("do something");
});
jQuery Waypoints 사용 :
$('#contentDiv').waypoint(function() {
alert('do something');
});
jQuery Waypoints 사이트의 다른 예제 .
이것을 달성하기 위해 간단한 setinterval 함수를 수행했습니다. div1 클래스의 요소가 표시되면 div2가 표시되도록 설정합니다. 좋은 방법은 아니지만 간단한 수정 방법을 알고 있습니다.
setInterval(function(){
if($('.div1').is(':visible')){
$('.div2').show();
}
else {
$('.div2').hide();
}
}, 100);
병렬 스레드 https://stackoverflow.com/a/3535028/741782에 언급 된 것처럼 jQuery appear 플러그인 을 사용해 볼 수도 있습니다
여기에 도움이 된 것은 최근 ResizeObserver 사양 polyfill입니다 .
const divEl = $('#section60');
const ro = new ResizeObserver(() => {
if (divEl.is(':visible')) {
console.log("it's visible now!");
}
});
ro.observe(divEl[0]);
크로스 브라우저 및 성능 (폴링 없음)입니다.
DOM 속성의 변화를 볼 수있는 jQuery 플러그인이 있습니다.
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
});
애니메이션이 끝난 후 여유 및 트리거 이벤트를 지원합니다! [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/
Glenns 아이디어를 기반으로 Catalint에서 hide / show 이벤트 트리거를 변경했습니다. 내 문제는 모듈 식 응용 프로그램이 있다는 것입니다. div 부모를 표시하거나 숨기는 모듈 사이를 변경합니다. 그런 다음 모듈을 숨기고 다른 모듈을 표시하면 모듈 간을 변경할 때 눈에 띄는 지연이 있습니다. 나는 때때로이 사건과 일부 특별한 어린이들에게만 불을 지피기 만하면됩니다. 그래서 나는 "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);
},
도와주세요
한 가지 방법입니다.
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); }
내 솔루션 :
; (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
}
$( 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");
});
});
이것이 가장 간단한 방식으로 작업을 수행하기를 바랍니다.
$("#myID").on('show').trigger('displayShow');
$('#myID').off('displayShow').on('displayShow', function(e) {
console.log('This event will be triggered when myID will be visible');
});
<div id="welcometo">Özhan</div>
<input type="button" name="ooo"
onclick="JavaScript:
if(document.all.welcometo.style.display=='none') {
document.all.welcometo.style.display='';
} else {
document.all.welcometo.style.display='none';
}">
이 코드 자동 제어는 조회 가시적 또는 보이지 않는 제어가 필요하지 않습니다.
'development' 카테고리의 다른 글
설치 스크립트가 오류와 함께 종료되었습니다 : 'x86_64-linux-gnu-gcc'명령이 종료 상태 1로 실패했습니다. (0) | 2020.03.15 |
---|---|
정수가 다른 두 정수 사이에 있는지 확인 (0) | 2020.03.15 |
javadoc에서 메소드 매개 변수에 대한 참조를 추가하는 방법은 무엇입니까? (0) | 2020.03.15 |
Java에서 함수 포인터를 대체하는 가장 가까운 것은 무엇입니까? (0) | 2020.03.15 |
GitHub가 SSH를 통한 HTTPS를 권장하는 이유는 무엇입니까? (0) | 2020.03.14 |