この状況では、要素をビューポートにスクロールする必要があります。問題は、スクロール可能な要素がわからないことです。たとえば、Portraitでは本文はスクロール可能で、Landscapeでは他の要素です(さらに、スクロール可能な要素を変更する状況がさらにあります)
さて、ビューポートにスクロールする必要がある要素がある場合、最初のスクロール可能な親を見つける最良の方法は何ですか?
デモをセットアップしました こちら 。ボタンを使用すると、2つの異なる状況を切り替えることができます
<div class="outer">
<div class="inner">
<div class="content">
...
<span>Scroll me into view</span>
</div>
</div>
</div>
本文はスクロール可能または.outer
助言がありますか ?
親に見えない場合は、スクロールバーが表示されているかどうかを確認してください。
function getScrollParent(node) {
if (node == null) {
return null;
}
if (node.scrollHeight > node.clientHeight) {
return node;
} else {
return getScrollParent(node.parentNode);
}
}
これは、jQuery UI scrollParent
メソッドの純粋なJSポートであり、 cwestonの話 です。まだコンテンツがオーバーフローしていない場合、スクロールの親を見つけられない受け入れられた答えの解決策ではなく、私はこれを使いました。
私のポートとの1つの違いは、CSS overflow
プロパティに適切な値を持つ親が見つからない場合、<body>
要素を返すことです。 JQuery UI、代わりにdocument
オブジェクトを返しました。 .scrollTop
のような値は<body>
から取得できますが、document
からは取得できないため、これは奇妙です。
function getScrollParent(element, includeHidden) {
var style = getComputedStyle(element);
var excludeStaticParent = style.position === "absolute";
var overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/;
if (style.position === "fixed") return document.body;
for (var parent = element; (parent = parent.parentElement);) {
style = getComputedStyle(parent);
if (excludeStaticParent && style.position === "static") {
continue;
}
if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX)) return parent;
}
return document.body;
}
JQuery UIを使用している場合は、scrollParent
メソッドを使用できます。 [〜#〜] api [〜#〜] または source をご覧ください。
APIから:
.scrollParent()
:スクロール可能な最も近い先祖要素を取得しますこのメソッドは引数を受け入れません。このメソッドは、スクロールを許可する最も近い祖先を見つけます。つまり、
.scrollParent()
メソッドは、現在選択されている要素がスクロールする要素を見つけます。注:このメソッドは、1つの要素を含むjQueryオブジェクトでのみ機能します。
JQuery UIを使用していないがjQueryを使用している場合、次のような同様の機能を提供する独立した代替ライブラリがあります。
ほとんどの投票での答えは、スクロールバーがなくてもscrollHeight > clientHeight
がtrue
になる場合があります。
このGistソリューションを見つけました https://github.com/olahol/scrollparent.js/blob/master/scrollparent.js#L1
^ https://github.com/olahol にコードを書いた人への合計クレジット。
es6
にリファクタリングしました:
export const getScrollParent = (node) => {
const regex = /(auto|scroll)/;
const parents = (_node, ps) => {
if (_node.parentNode === null) { return ps; }
return parents(_node.parentNode, ps.concat([_node]));
};
const style = (_node, prop) => getComputedStyle(_node, null).getPropertyValue(prop);
const overflow = _node => style(_node, 'overflow') + style(_node, 'overflow-y') + style(_node, 'overflow-x');
const scroll = _node => regex.test(overflow(_node));
/* eslint-disable consistent-return */
const scrollParent = (_node) => {
if (!(_node instanceof HTMLElement || _node instanceof SVGElement)) {
return;
}
const ps = parents(_node.parentNode, []);
for (let i = 0; i < ps.length; i += 1) {
if (scroll(ps[i])) {
return ps[i];
}
}
return document.scrollingElement || document.documentElement;
};
return scrollParent(node);
/* eslint-enable consistent-return */
};
次のように使用できます。
const $yourElement = document.querySelector('.your-class-or-selector');
getScrollParent($yourElement);
Google chrome devツールを使用して、ページを部分的に下にスクロールしたら、ページを検査し、スクロールされていると思われるDOMノードを選択します。次にコンソールを引き上げます(開発ツールの[要素]タブからESCを押して)$0.scrollTop
。これにより、その要素の現在のスクロール位置が出力されます。 0でない場合、それがスクロールされている要素であることがわかります。
これが欲しいと思う。
$('button').click(function() {
$("body").addClass("body");
$('.outer').toggleClass('scroller');
check($(".content"));
});
function check(el) {
var overflowY = el.css("overflow-y");
if (overflowY == "scroll") {
alert(el.attr("class") + " has");
} else {
if(el.parent().length > 0)
check(el.parent());
else
return false;
}
}
body {
height: 450px;
overflow-y: scroll;
}
div.inner {
width: 200px;
height: 400px;
border: 1px solid #000;
}
div.outer {
width: 200px;
height: 200px;
}
div.outer.scroller {
overflow-y: scroll;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>
toggle
</button>
<div class="outer">
<div class="inner">
<div class="content">
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." adipiscing elit, sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur
sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
</div>
</div>
</div>
@Stefano Nardoの回答から私はこれを書き直します。それは私のためにうまく機能します。
function getScrollParent(node){
if(!node) return null;
else if (node.scrollTop>0) return node;
return getScrollParent(node.parentNode) || document.documentElement;
}
@ Web_Designer's answer をさらに構築
その要素にjQuery object
を渡しているときに、次のエラーが表示される場合、
Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'
次に、要素が単一の要素である場合、配列キーDom Node element
にある0
のみを渡してみてください。例えば。
getScrollParent(jQuery("#" + formid)[0])