페이지에 포함될 도구 모음을 만들고 있습니다. 포함될 div는 기본적으로 display : none 입니다. 도구 모음에 이벤트 리스너를 배치하여 표시 될 때 수신하여 초기화 할 수있는 방법이 있습니까? 아니면 포함하는 페이지에서 변수를 전달해야합니까?
감사
페이지에 포함될 도구 모음을 만들고 있습니다. 포함될 div는 기본적으로 display : none 입니다. 도구 모음에 이벤트 리스너를 배치하여 표시 될 때 수신하여 초기화 할 수있는 방법이 있습니까? 아니면 포함하는 페이지에서 변수를 전달해야합니까?
감사
답변:
Javascript 이벤트는 사용자 상호 작용을 처리 합니다. 코드가 충분히 구성되어 있으면 가시성이 변경되는 동일한 위치에서 초기화 함수를 호출 할 수 있어야합니다 (즉 myElement.style.display, 여러 위치에서 변경해서는 안되며 대신 다음과 같은 기능 / 메소드를 호출합니다. 이것과 당신이 원하는 다른 것).
앞으로는 새로운 HTML Intersection Observer API가 여러분이 찾고있는 것입니다. 대상이라고하는 하나의 요소가 장치 뷰포트 또는 지정된 요소와 교차 할 때마다 호출되는 콜백을 구성 할 수 있습니다. 최신 버전의 Chrome, Firefox 및 Edge에서 사용할 수 있습니다. 자세한 내용은 https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API 를 참조 하십시오 .
디스플레이 관찰을위한 간단한 코드 예제 : 전환 없음 :
// Start observing visbility of element. On change, the
// the callback is called with Boolean visibility as
// argument:
respondToVisibility(element, callback) {
var options = {
root: document.documentElement
}
var observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
callback(entry.intersectionRatio > 0);
});
}, options);
observer.observe(element);
}
var targetNode = document.getElementById('elementId');
var observer = new MutationObserver(function(){
if(targetNode.style.display != 'none'){
// doSomething
}
});
observer.observe(targetNode, { attributes: true, childList: true });
조금 늦을 수도 있지만 MutationObserver를 사용하여 원하는 요소의 변경 사항을 관찰 할 수 있습니다. 변경이 발생하면 요소가 표시되는지 확인하기 만하면됩니다.
IntersectionObserver- stackoverflow.com/a/52627221/2803743
적어도 한 가지 방법이 있지만 그다지 좋은 방법은 아닙니다. 다음과 같이 변경 사항에 대해 요소를 폴링 할 수 있습니다.
var previous_style,
poll = window.setInterval(function()
{
var current_style = document.getElementById('target').style.display;
if (previous_style != current_style) {
alert('style changed');
window.clearInterval(poll);
} else {
previous_style = current_style;
}
}, 100);
DOM 표준은 또한 뮤 테이션 이벤트를 지정 하지만, 저는 그것들을 사용할 기회가 없었고, 그것들이 얼마나 잘 지원되는지 확신 할 수 없습니다. 다음과 같이 사용합니다.
target.addEventListener('DOMAttrModified', function()
{
if (e.attrName == 'style') {
alert('style changed');
}
}, false);
이 코드는 내 머릿속에서 벗어 났으므로 작동하는지 확실하지 않습니다.
가장 쉬운 해결책은 당신의 목표를 표시하는 기능에 콜백을 가지고하는 것입니다.
나는 이와 같은 문제가 있었고 우리 사이트에서 그것을 해결하기 위해 jQuery 플러그인을 만들었습니다.
https://github.com/shaunbowe/jquery.visibilityChanged
귀하의 예에 따라 사용하는 방법은 다음과 같습니다.
$('#contentDiv').visibilityChanged(function(element, visible) {
alert("do something");
});
.is(':visible')과 함께 setTimeout.
@figha가 말했듯 이 이것이 자신의 웹 페이지 라면 요소를 표시 한 후에 실행해야하는 모든 것을 실행해야합니다.
그러나 질문에 답하기 위해 (그리고 이것이 일반적인 사용 사례 인 Chrome 또는 Firefox 확장 프로그램을 만드는 모든 사람 ) Mutation Summary 및 Mutation Observer 가 DOM 변경이 이벤트를 트리거하도록 허용합니다.
예를 들어, data-widget속성이 DOM에 추가되는 요소에 대한 이벤트를 트리거합니다 . 대출 데이비드 월시의 블로그에서이 훌륭한 예를 :
var observer = new MutationObserver(function(mutations) {
// For the sake of...observation...let's output the mutation to console to see how this all works
mutations.forEach(function(mutation) {
console.log(mutation.type);
});
});
// Notify me of everything!
var observerConfig = {
attributes: true,
childList: true,
characterData: true
};
// Node, config
// In this case we'll listen to all changes to body and child nodes
var targetNode = document.body;
observer.observe(targetNode, observerConfig);
응답에는 added,removed , valueChanged그리고 더 . 등을 valueChanged포함한 모든 속성을 포함합니다 display.
이 jQuery 플러그인을 사용해 볼 수도 있습니다 : https://github.com/morr/jquery.appear
DOMAttrModified 이벤트 리스너 브라우저 지원에 대해 언급하기 만하면됩니다.
브라우저 간 지원
이러한 이벤트는 다른 브라우저에서 일관되게 구현되지 않습니다. 예를 들면 다음과 같습니다.
버전 9 이전의 IE는 변형 이벤트를 전혀 지원하지 않았으며 버전 9에서 일부를 올바르게 구현하지 않았습니다 (예 : DOMNodeInserted).
WebKit은 DOMAttrModified를 지원하지 않습니다 (웹킷 버그 8191 및 해결 방법 참조).
"변이 이름 이벤트", 즉 DOMElementNameChanged 및 DOMAttributeNameChanged는 Firefox (버전 11 기준) 및 다른 브라우저에서도 지원되지 않습니다.
출처 : https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Mutation_events
내 솔루션 :
; (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
}