HTML
<body>
<div class="lol">
<a class="rightArrow" href="javascriptVoid:(0);" title"Next image">
</div>
</body>
疑似コード
$(".rightArrow").click(function() {
rightArrowParents = this.dom(); //.dom(); is the pseudo function ... it should show the whole
alert(rightArrowParents);
});
警告メッセージは次のようになります。
body div.lol a.rightArrow
Javascript/jqueryでこれを取得するにはどうすればよいですか?
次のようなjQueryを使用します(イベント以外はjQueryを使用しないソリューションが続きます。それが重要な場合は、関数呼び出しが大幅に少なくなります)。
$(".rightArrow").click(function() {
var rightArrowParents = [];
$(this).parents().addBack().not('html').each(function() {
var entry = this.tagName.toLowerCase();
if (this.className) {
entry += "." + this.className.replace(/ /g, '.');
}
rightArrowParents.Push(entry);
});
alert(rightArrowParents.join(" "));
return false;
});
実際の例:
$(".rightArrow").click(function() {
var rightArrowParents = [];
$(this).parents().addBack().not('html').each(function() {
var entry = this.tagName.toLowerCase();
if (this.className) {
entry += "." + this.className.replace(/ /g, '.');
}
rightArrowParents.Push(entry);
});
alert(rightArrowParents.join(" "));
return false;
});
<div class="lol multi">
<a href="#" class="rightArrow" title="Next image">Click here</a>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
(実際の例では、複数のクラスの処理を示すために、class
のdiv
属性をlol multi
に更新しました。)
parents
を使用して、クリックされた要素の祖先を取得し、_ html
を介してnot
要素を削除します=(body
から開始したため)、ループして各親のエントリを作成し、配列にプッシュします。次に addBack
を使用してa
をセットに戻します。これにより、セットの順序も希望どおりに変更されます(parents
is特別なことですが、親に希望する順序とは逆の順序で与えますが、addBAck
はDOM順序に戻します)。次に、Array#join
を使用してスペース区切りの文字列を作成します。
エントリを作成するとき、className
に何かがある場合は、スペースを.
に置き換えて、複数のクラスを持つ要素をサポートします(<p class='foo bar'>
はclassName
= "foo bar"
なので、エントリは最終的にp.foo.bar
)になります。
完全を期すために、これはjQueryがやり過ぎである可能性がある場所の1つであり、DOMをたどるだけで簡単に実行できます。
$(".rightArrow").click(function() {
var rightArrowParents = [],
Elm,
entry;
for (Elm = this; Elm; Elm = Elm.parentNode) {
entry = Elm.tagName.toLowerCase();
if (entry === "html") {
break;
}
if (Elm.className) {
entry += "." + Elm.className.replace(/ /g, '.');
}
rightArrowParents.Push(entry);
}
rightArrowParents.reverse();
alert(rightArrowParents.join(" "));
return false;
});
実際の例:
$(".rightArrow").click(function() {
var rightArrowParents = [],
Elm,
entry;
for (Elm = this; Elm; Elm = Elm.parentNode) {
entry = Elm.tagName.toLowerCase();
if (entry === "html") {
break;
}
if (Elm.className) {
entry += "." + Elm.className.replace(/ /g, '.');
}
rightArrowParents.Push(entry);
}
rightArrowParents.reverse();
alert(rightArrowParents.join(" "));
return false;
});
<div class="lol multi">
<a href="#" class="rightArrow" title="Next image">Click here</a>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
そこでは、要素の標準 parentNode
property を繰り返し使用して、親がなくなるか、html
要素が見つかるまで、ツリーを上に向かって歩いていきます。次に、配列を反転し(必要な出力に逆向きになっているため)、結合します。
以下は、jQueryパスを返すネイティブJSバージョンです。要素のIDがある場合は、それらも追加します。これにより、配列にIDが表示された場合に最短パスを実行する機会が与えられます。
var path = getDomPath(element);
console.log(path.join(' > '));
アウトプット
body > section:eq(0) > div:eq(3) > section#content > section#firehose > div#firehoselist > article#firehose-46813651 > header > h2 > span#title-46813651
これが関数です。
function getDomPath(el) {
var stack = [];
while ( el.parentNode != null ) {
console.log(el.nodeName);
var sibCount = 0;
var sibIndex = 0;
for ( var i = 0; i < el.parentNode.childNodes.length; i++ ) {
var sib = el.parentNode.childNodes[i];
if ( sib.nodeName == el.nodeName ) {
if ( sib === el ) {
sibIndex = sibCount;
}
sibCount++;
}
}
if ( el.hasAttribute('id') && el.id != '' ) {
stack.unshift(el.nodeName.toLowerCase() + '#' + el.id);
} else if ( sibCount > 1 ) {
stack.unshift(el.nodeName.toLowerCase() + ':eq(' + sibIndex + ')');
} else {
stack.unshift(el.nodeName.toLowerCase());
}
el = el.parentNode;
}
return stack.slice(1); // removes the html element
}
CSSの標準パス(jQueryではなく)を返し、ShadowDOMを処理するネイティブJSバージョンが必要でした。このコードは、誰か他の人がそれを必要とする場合に備えて、Michael Connorの回答のマイナーアップデートです。
function getDomPath(el) {
if (!el) {
return;
}
var stack = [];
var isShadow = false;
while (el.parentNode != null) {
// console.log(el.nodeName);
var sibCount = 0;
var sibIndex = 0;
// get sibling indexes
for ( var i = 0; i < el.parentNode.childNodes.length; i++ ) {
var sib = el.parentNode.childNodes[i];
if ( sib.nodeName == el.nodeName ) {
if ( sib === el ) {
sibIndex = sibCount;
}
sibCount++;
}
}
// if ( el.hasAttribute('id') && el.id != '' ) { no id shortcuts, ids are not unique in shadowDom
// stack.unshift(el.nodeName.toLowerCase() + '#' + el.id);
// } else
var nodeName = el.nodeName.toLowerCase();
if (isShadow) {
nodeName += "::shadow";
isShadow = false;
}
if ( sibCount > 1 ) {
stack.unshift(nodeName + ':nth-of-type(' + (sibIndex + 1) + ')');
} else {
stack.unshift(nodeName);
}
el = el.parentNode;
if (el.nodeType === 11) { // for shadow dom, we
isShadow = true;
el = el.Host;
}
}
stack.splice(0,1); // removes the html element
return stack.join(' > ');
}
要素を正確に一致させるためのソリューションを次に示します。
selector(それは実際のものではないことを理解することが重要です)chrome toolsは、DOM内の要素を一意に識別しません。(たとえば、連続するspan
elements。位置付け/インデックス付け情報はありません)
$.fn.fullSelector = function () {
var path = this.parents().addBack();
var quickCss = path.get().map(function (item) {
var self = $(item),
id = item.id ? '#' + item.id : '',
clss = item.classList.length ? item.classList.toString().split(' ').map(function (c) {
return '.' + c;
}).join('') : '',
name = item.nodeName.toLowerCase(),
index = self.siblings(name).length ? ':nth-child(' + (self.index() + 1) + ')' : '';
if (name === 'html' || name === 'body') {
return name;
}
return name + index + id + clss;
}).join(' > ');
return quickCss;
};
そして、あなたはこのようにそれを使うことができます
console.log( $('some-selector').fullSelector() );
T.Jからスニペットを移動しました。小さなjQueryプラグインのクラウダー。私は彼のjQueryバージョンを使用しましたが、これは完全に不要なオーバーヘッドであると彼が言っているのは正しいですが、私はデバッグ目的でのみ使用するので気にしません。
使用法:
Html
<html>
<body>
<!-- Two spans, the first will be chosen -->
<div>
<span>Nested span</span>
</div>
<span>Simple span</span>
<!-- Pre element -->
<pre>Pre</pre>
</body>
</html>
Javascript
// result (array): ["body", "div.sampleClass"]
$('span').getDomPath(false)
// result (string): body > div.sampleClass
$('span').getDomPath()
// result (array): ["body", "div#test"]
$('pre').getDomPath(false)
// result (string): body > div#test
$('pre').getDomPath()
リポジトリ
$(".rightArrow")
.parents()
.map(function () {
var value = this.tagName.toLowerCase();
if (this.className) {
value += '.' + this.className.replace(' ', '.', 'g');
}
return value;
})
.get().reverse().join(", ");
こんにちはこの関数は、パスに表示されない現在の要素に関連するバグを解決します
今これをチェック
$j(".wrapper").click(function(event) {
selectedElement=$j(event.target);
var rightArrowParents = [];
$j(event.target).parents().not('html,body').each(function() {
var entry = this.tagName.toLowerCase();
if (this.className) {
entry += "." + this.className.replace(/ /g, '.');
}else if(this.id){
entry += "#" + this.id;
}
entry=replaceAll(entry,'..','.');
rightArrowParents.Push(entry);
});
rightArrowParents.reverse();
//if(event.target.nodeName.toLowerCase()=="a" || event.target.nodeName.toLowerCase()=="h1"){
var entry = event.target.nodeName.toLowerCase();
if (event.target.className) {
entry += "." + event.target.className.replace(/ /g, '.');
}else if(event.target.id){
entry += "#" + event.target.id;
}
rightArrowParents.Push(entry);
// }
どこ $j
= jQuery変数
クラス名の..の問題も解決します
ここに置換機能があります:
function escapeRegExp(str) {
return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}
function replaceAll(str, find, replace) {
return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}
ありがとう
var obj = $('#show-editor-button'),
path = '';
while (typeof obj.prop('tagName') != "undefined"){
if (obj.attr('class')){
path = '.'+obj.attr('class').replace(/\s/g , ".") + path;
}
if (obj.attr('id')){
path = '#'+obj.attr('id') + path;
}
path = ' ' +obj.prop('tagName').toLowerCase() + path;
obj = obj.parent();
}
console.log(path);