ページに含めるツールバーを作成しています。含まれるdivは、デフォルトでdisplay:noneになります。初期化できるように、表示されたときにリッスンするようにツールバーにイベントリスナーを配置する方法はありますか?またはそれを含むページから変数を渡す必要がありますか?
ありがとう
ページに含めるツールバーを作成しています。含まれるdivは、デフォルトでdisplay:noneになります。初期化できるように、表示されたときにリッスンするようにツールバーにイベントリスナーを配置する方法はありますか?またはそれを含むページから変数を渡す必要がありますか?
ありがとう
回答:
JavaScriptイベントはユーザーインタラクションを処理します。コードが十分に構成されている場合、可視化が変更されるのと同じ場所で初期化関数を呼び出すことができるはずです(つまりmyElement.style.display、多くの場所で変更してはならず、代わりに関数/メソッドを呼び出します)これとあなたが望むかもしれない他のもの)
今後、新しいHTML Intersection Observer APIがあなたの求めるものです。これにより、ターゲットと呼ばれる1つの要素がデバイスのビューポートまたは指定された要素と交差するたびに呼び出されるコールバックを構成できます。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
少なくとも1つの方法がありますが、あまり良い方法ではありません。次のように要素の変更をポーリングするだけです。
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が言うように、これが独自のWebページである場合は、要素を表示した後で実行する必要があるものを実行するだけです。
ただし、質問(および一般的なユースケースであるChromeまたはFirefoxの拡張機能を作成しているユーザー)に答えるために、Mutation SummaryおよびMutation Observerでは DOMの変更によってイベントをトリガーできます。
たとえばdata-widget、DOMに追加される属性を持つ要素のイベントをトリガーします。この優れた例をDavid Walshのブログから借用します。
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をサポートしていません(webkitバグ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
}