jqueryなしで特定のタグ名を持つ最も近い要素を見つけようとしています。[]をクリックすると、そのテーブル<th>のにアクセスでき<tbody>ます。提案?オフセットについて読んだのですが、あまり理解していませんでした。私はただ使うべきですか:
thがすでにクリックされたth要素に設定されていると仮定します
th.offsetParent.getElementsByTagName('tbody')[0]
jqueryなしで特定のタグ名を持つ最も近い要素を見つけようとしています。[]をクリックすると、そのテーブル<th>のにアクセスでき<tbody>ます。提案?オフセットについて読んだのですが、あまり理解していませんでした。私はただ使うべきですか:
thがすでにクリックされたth要素に設定されていると仮定します
th.offsetParent.getElementsByTagName('tbody')[0]
parentNode:developer.mozilla.org/en-US/docs/Web/API/Node.parentNode
el.closest('tbody')非IEブラウザ用。以下のより詳細な回答とポリフィルを参照してください。
回答:
パーティーに少し(非常に)遅れましたが、それでも。これはやるべきトリックを:
function closest(el, selector) {
var matchesFn;
// find vendor prefix
['matches','webkitMatchesSelector','mozMatchesSelector','msMatchesSelector','oMatchesSelector'].some(function(fn) {
if (typeof document.body[fn] == 'function') {
matchesFn = fn;
return true;
}
return false;
})
var parent;
// traverse parents
while (el) {
parent = el.parentElement;
if (parent && parent[matchesFn](selector)) {
return parent;
}
el = parent;
}
return null;
}
eljQuery.closest()およびElement.closest()が実行する要素もテストするようにコードを変更しました。for( var parent = el ; parent !== null && !parent[matchesFn](selector) ; parent = el.parentElement ){ el = parent; } return parent;
parent、グローバルスコープでも定義されています(!)
el.parentNode、IEでSVGをトラバースするときに実行したい場合は、これが機能しなくなります。
非常に簡単:
el.closest('tbody')
IEを除くすべてのブラウザでサポートされています。
更新:Edgeはそれもサポートするようになりました。
jQueryは必要ありません。さらに、jQueryをに置き換える$(this).closest('tbody')と$(this.closest('tbody'))、要素が見つからない場合にパフォーマンスが大幅に向上します。
IE用のポリフィル:
if (!Element.prototype.matches) Element.prototype.matches = Element.prototype.msMatchesSelector;
if (!Element.prototype.closest) Element.prototype.closest = function (selector) {
var el = this;
while (el) {
if (el.matches(selector)) {
return el;
}
el = el.parentElement;
}
};
return要素が見つからなかった場合は存在せずundefined、最も近い要素が見つからなかった場合に効果的に戻ることに注意してください。
詳細については、https://developer.mozilla.org/en-US/docs/Web/API/Element/closestを参照してください。
jQueryを使用せずにタグ名で最も近い要素を取得する方法は次のとおりです。
function getClosest(el, tag) {
// this is necessary since nodeName is always in upper case
tag = tag.toUpperCase();
do {
if (el.nodeName === tag) {
// tag name is found! let's return it. :)
return el;
}
} while (el = el.parentNode);
// not found :(
return null;
}
getClosest(th, 'tbody');
これを行うための標準化された関数が存在します:Element.closest。IE11を除くほとんどのブラウザがサポートしています(詳細はcaniuse.comによる)。MDNドキュメントはまた、あなたが、古いブラウザを対象としなければならない場合にポリフィルが含まれます。
tbody与えられた最も近い親を見つけるには、th次のことができます。
th.closest('tbody');
あなたが自分で関数を書きたい場合-これが私が思いついたものです:
function findClosestParent (startElement, fn) {
var parent = startElement.parentElement;
if (!parent) return undefined;
return fn(parent) ? parent : findClosestParent(parent, fn);
}
タグ名で最も近い親を見つけるには、次のように使用できます。
findClosestParent(x, element => return element.tagName === "SECTION");
function closest(el, sel) {
if (el != null)
return el.matches(sel) ? el
: (el.querySelector(sel)
|| closest(el.parentNode, sel));
}
このソリューションは、HTML 5仕様の最新の機能のいくつかを使用しており、古い/互換性のないブラウザー(Internet Explorerを参照)でこれを使用するには、ポリフィルが必要になります。
Element.prototype.matches = (Element.prototype.matches || Element.prototype.mozMatchesSelector
|| Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector
|| Element.prototype.webkitMatchesSelector || Element.prototype.webkitMatchesSelector);
@SalmanPKの回答を拡張するには
ノードをセレクターとして使用できるようになり、マウスオーバーなどのイベントを操作するときに便利です。
function closest(el, selector) {
if (typeof selector === 'string') {
matches = el.webkitMatchesSelector ? 'webkitMatchesSelector' : (el.msMatchesSelector ? 'msMatchesSelector' : 'matches');
while (el.parentElement) {
if (el[matches](selector)) {
return el
};
el = el.parentElement;
}
} else {
while (el.parentElement) {
if (el === selector) {
return el
};
el = el.parentElement;
}
}
return null;
}
これが私が使っている簡単な関数です:-
function closest(el, selector) {
var matches = el.webkitMatchesSelector ? 'webkitMatchesSelector' : (el.msMatchesSelector ? 'msMatchesSelector' : 'matches');
while (el.parentElement) {
if (el[matches](selector)) return el;
el = el.parentElement;
}
return null;
}
特定の祖先を見つけるために使用できるもの:
Element.closest();
この関数は、CSSセレクター文字列を引数として取ります。次に、引数で渡されたCSSセレクターに一致する現在の要素(または要素自体)の最も近い祖先を返します。祖先がない場合は戻りnullます。
const child = document.querySelector('.child');
// select the child
console.dir(child.closest('.parent').className);
// check if there is any ancestor called parent
<div class="parent">
<div></div>
<div>
<div></div>
<div class="child"></div>
</div>
</div>
クラス、ID、データ属性、またはタグを含むツリーの上位にある最も近いDOM要素を取得します。要素自体が含まれます。IE6に戻ってサポートされます。
var getClosest = function (elem, selector) {
var firstChar = selector.charAt(0);
// Get closest match
for ( ; elem && elem !== document; elem = elem.parentNode ) {
// If selector is a class
if ( firstChar === '.' ) {
if ( elem.classList.contains( selector.substr(1) ) ) {
return elem;
}
}
// If selector is an ID
if ( firstChar === '#' ) {
if ( elem.id === selector.substr(1) ) {
return elem;
}
}
// If selector is a data attribute
if ( firstChar === '[' ) {
if ( elem.hasAttribute( selector.substr(1, selector.length - 2) ) ) {
return elem;
}
}
// If selector is a tag
if ( elem.tagName.toLowerCase() === selector ) {
return elem;
}
}
return false;
};
var elem = document.querySelector('#some-element');
var closest = getClosest(elem, '.some-class');
var closestLink = getClosest(elem, 'a');
var closestExcludingElement = getClosest(elem.parentNode, '.some-class');
firstCharすべてのIF条件の代わりにスイッチを使用してみませんか?
forループを使用するのですか?
最も近い要素childNodesを見つけます。
closest:function(el, selector,userMatchFn) {
var matchesFn;
// find vendor prefix
['matches','webkitMatchesSelector','mozMatchesSelector','msMatchesSelector','oMatchesSelector'].some(function(fn) {
if (typeof document.body[fn] == 'function') {
matchesFn = fn;
return true;
}
return false;
});
function findInChilds(el){
if(!el) return false;
if(el && el[matchesFn] && el[matchesFn](selector)
&& userMatchFn(el) ) return [el];
var resultAsArr=[];
if(el.childNodes && el.childNodes.length){
for(var i=0;i< el.childNodes.length;i++)
{
var child=el.childNodes[i];
var resultForChild=findInChilds(child);
if(resultForChild instanceof Array){
for(var j=0;j<resultForChild.length;j++)
{
resultAsArr.push(resultForChild[j]);
}
}
}
}
return resultAsArr.length?resultAsArr: false;
}
var parent;
if(!userMatchFn || arguments.length==2) userMatchFn=function(){return true;}
while (el) {
parent = el.parentElement;
result=findInChilds(parent);
if (result) return result;
el = parent;
}
return null;
}
ここに。
function findNearest(el, tag) {
while( el && el.tagName && el.tagName !== tag.toUpperCase()) {
el = el.nextSibling;
} return el;
}
ツリーのさらに下にある兄弟のみが見つかります。previousSiblingを使用して反対方向に進むか、変数を使用して両方の方向をトラバースし、最初に見つかった方を返します。一般的な考え方は理解できますが、兄弟が一致しない場合にparentNodeまたは子をトラバースする場合は、jQueryを使用することもできます。その時点で、それは簡単に価値があります。
私は最も近いjqueryでキャッチする最も簡単なコードだと思います:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
$(".add").on("click", function () {
var v = $(this).closest(".division").find("input[name='roll']").val();
alert(v);
});
});
</script>
<?php
for ($i = 1; $i <= 5; $i++) {
echo'<div class = "division">'
. '<form method="POST" action="">'
. '<p><input type="number" name="roll" placeholder="Enter Roll"></p>'
. '<p><input type="button" class="add" name = "submit" value = "Click"></p>'
. '</form></div>';
}
?>
どうもありがとう。