アプリ版:「スタンプのみでお礼する」機能のリリースについて

javascriptでクリックしたエレメントの祖先のエレメントが全て同じだった場合に、
該当するもののタグ内の言葉を抜き出そうと思っているのですが、
どのようにすればすっきり書けるのかがわかりません。


例えば下の[例1]、[例2]はともに、「あ」をクリックしたときに、「あ」「い」「う」を抜き出して、「え」「お」は抜き出したくありません。


[例1]

<div class = "a">
<ul>
<li>あ</li> ←クリック
<li>い</li>
<li>う</li>
</ul>
</div>


<ul>
<li>え</li>
<li>お</li>
</ul>
***
[例2]

<div>
<span><em>あ</em></span> ←クリック
</div>

<div>
<span><em>い</em></span>
</div>

<div>
<span><em>う</em></span>
</div>

<span><em>え</em></span>

<span><em>お</em></span>

A 回答 (6件)

No.1です。

ちょっと面白そうだったので、また書いてみました。

<html>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7 …
<script type="text/javascript">
var buff="";
$(document).ready(function(){
$('body').find('*').each(function(){
if($(this).children().length != 0){return;};
$(this).click(function(){
obj = $(this);
buff="";
while(obj[0].localName != 'html'){
buff=obj[0].localName+" > "+buff;
obj=obj.parent();
}
buff=buff.substring(0,buff.length-3);
alert($(buff).text());
});
});
});
</script>
</head>
<body>
<div class = "a">
<ul><li>あ</li><li>い</li><li>う</li></ul>
</div>
<ul><li>え</li><li>お</li></ul>
<div><span><em>あ</em></span></div>
<div><span><em>い</em></span></div>
<div><span><em>う</em></span></div>
<span><em>え</em></span>
<span><em>お</em></span>
</body>
</html>

こういうことでしょうか。
    • good
    • 0

要件とはやや異なりますが、同一階層の要素ノードを抽出してみてはどうでしょうか。


http://jsfiddle.net/DAEbn/5/

ブラウザ拡張とのことだったので IE8- は動作保証外としています。
ちなみに、document.getElementsByTagName('*') は IE8- でコメントノードも拾いますので、クロスブラウザするなら要注意です。
    • good
    • 0
この回答へのお礼

すみません。皆さん、あまりにもしっかりご回答くださって驚いています。とても嬉しいです。
残念なながら、まだjsには慣れておらず、解析に時間がかかりそうなので、先にお礼の返事させて頂きます。素晴らしいサンプルをどうもありがとうございます。

じっくり解析してみたいと思います。ありがとうございます。

お礼日時:2012/02/06 13:34

#2です。



#3様の比較のアイデアが素晴らしいので、無断借用して書き直してみました。
最初に属性にセットしてしまうのは、どうも…という気がするので、その都度比較する方式はそのままです。
今回は、#2と違って、子孫要素も含めてそのままテキストを収集しちゃってます。
(その方が簡単なので…(ちょっと手抜き))

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="ja">
<head><title>sample</title>
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">

<script type="text/javascript">
<!--

(function(){

function hoge(evt){
 var t = evt.target || evt.srcElement;
 var pedigree = getPedigree(t), tn = t.tagName;
 if(tn=="HTML" || tn=="BODY") return;
 var node, nodes, i=0, re="";
 
 nodes = document.getElementsByTagName(tn);
 while(node=nodes[i++])
  if(pedigree == getPedigree(node))
   re += (re?"\n":"") + (node.textContent || node.innerText);
 if(re) alert(re);
}

function getPedigree(node){
 var nam, list = "";
 while((node=node.parentNode) && (nam=node.tagName)) list += nam + ":";
 return list;
}

/*@cc_on@*/
document./*@if(1)attachEvent('on'+@else@*/addEventListener(/*@end@*/ 'click', hoge, false);

})();

//-->
</script>
</head>
<body>

<div>
<h2>例1</h2>
<div class = "a">
<ul>
<li>あ</li>
<li>い</li>
<li>う</li>
</ul>
</div>
<ul>
<li>え</li>
<li>お</li>
</ul>
</div>

<div>
<h2>例2</h2>
<div>
<span><em>あ</em></span>
</div>
<div>
<span><em>い</em></span>
</div>
<div>
<span><em>う</em></span>
</div>
<span><em>え</em></span>
<span><em>お</em></span>
</div>
</body>
</html>
    • good
    • 0
この回答へのお礼

fujillinさん、度々有り難うございます!

お礼日時:2012/02/06 13:31

ちょっと強引ですが、こんな感じでどうでしょうか?



<html>
<head>
<script>
try{
document.addEventListener ('click',function(e){clickfunc(e)},true); //基本
}catch(e){
document.attachEvent('onclick',function(e){clickfunc(e)}); //IE
}
window.onload=function(){
var n=document.getElementsByTagName("body").item(0).getElementsByTagName("*");
for(var i=0;i<n.length;i++){
var val=n[i].nodeName;
var p=n[i].parentNode;
while(p){
val+=(val!=""?",":"")+p.nodeName;
p=p.parentNode;
}
n[i].setAttribute("parentTags",val);
}
}
function clickfunc(e){
var t = (e.srcElement || e.target);
var pt=t.getAttribute("parentTags");
var val="";
var n=document.getElementsByTagName("body")[0].getElementsByTagName("*");
for(var i=0;i<n.length;i++){
if(n[i].getAttribute("parentTags")==pt) val+=(val==""?"":",")+(n[i].textContent || n[i].innerText);
}
alert(val);
}
</script>
</head>
<body>
<div class = "a">
<ul>
<li>あ</li>
<li>い</li>
<li>う</li>
</ul>
</div>


<ul>
<li>え</li>
<li>お</li>
</ul>
<hr>
<div>
<span><em>か</em></span>
</div>

<div>
<span><em>き</em></span>
</div>

<div>
<span><em>く</em></span>
</div>

<span><em>け</em></span>

<span><em>こ</em></span>
</body>
</html>
    • good
    • 0
この回答へのお礼

すみません。皆さん、あまりにもしっかりご回答くださって驚いています。とても嬉しいです。
残念なながら、まだjsには慣れておらず、解析に時間がかかりそうなので、先にお礼の返事させて頂きます。素晴らしいサンプルをどうもありがとうございます。

じっくり解析してみたいと思います。ありがとうございます。

お礼日時:2012/02/06 13:29

どういうルールなのかよくわかってませんけれど、特に子孫要素をどうするのかとか、テキストを持たない要素をクリックした場合とか…



とりあえず、こんなふうに仮定してみました。
『祖先要素に遡って、同じタグ構成になっている兄弟、従兄弟…要素のみを抜き出し、その直接のテキストだけ取り出す。(子孫要素は無視)』
(質問者さんが判断して決めるという可能性もあるけれど…)

あまり効率は良くないかもしれませんが、質問の意味がよくわかってないのと、あくまでも考え方のサンプルということで。
意図と違う場合は、よしなに訂正してください。

(全角空白は半角に)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="ja">
<head><title>sample</title>
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">

<script type="text/javascript">
<!--
(function(check, getText){

function hoge(evt){
 var t = evt.target || evt.srcElement;
 var ancestor = [t], result = [];
 var nodes, node = t, i = 0, re = "", anc;

//祖先の洗い出し
 while((node = node.parentNode) && node.tagName) ancestor.push(node);
//対象候補要素を取得
 nodes = document.getElementsByTagName(t.tagName);
//対象を絞込み
 while(anc=nodes[i++]) if(check(anc, ancestor)) result.push(anc);

//結果の表示
 i = 0;
 while(node=result[i++]) re += getText(node);
 nodes = ancestor = result = null;

 alert(re);
}

/*@cc_on@*/
document./*@if(1)attachEvent('on'+@else@*/addEventListener(/*@end@*/ 'click', hoge, false);

})(
function(e, a){
 var j = 0;
 while(e!=a[j] && e.tagName == a[j].tagName) e = e.parentNode, j++;
 return (e && e==a[j]);
},
function(elm){
 var c = elm.firstChild, s, str = "";
 while(c){
  if(c.nodeType == 3){
   s = c.nodeValue.replace(/[\r\n]/g,"");
   if(s) str += (str?" ":"") + s;
  }
  c = c.nextSibling;
 }
 return str?str+"\n":"";
}
);

//-->
</script>
</head>
<body>

<div>
<h2>例1</h2>
<div class = "a">
<ul>
<li>あ</li>
<li>い</li>
<li>う</li>
</ul>
</div>
<ul>
<li>え</li>
<li>お</li>
<li>か<span>対象外</span>き</li>
</ul>
</div>

<div>
<h2>例2</h2>
<div>
<span><em>あ</em></span>
</div>
<div>
<span><em>い</em></span>
</div>
<div>
<span><em>う</em></span>
</div>
<span><em>え</em></span>
<span>対象外1<em>お<span>対象外</span></em>対象外2</span>
<div><em>対象外</em></div>
</div>
</body>
</html>
    • good
    • 0
この回答へのお礼

すみません。皆さん、あまりにもしっかりご回答くださって驚いています。とても嬉しいです。
残念なながら、まだjsには慣れておらず、解析に時間がかかりそうなので、先にお礼の返事させて頂きます。素晴らしいサンプルをどうもありがとうございます。

おっしゃるとおり、子孫要素をどうするかについてはそこまで詰めて考えていませんでした。もし子孫があれば、タグを取り払って中のテキストを抜く、などにするかもしれません。よく自分で考えてみます。

本当にありがとうございました!

お礼日時:2012/02/06 13:28

jqueryを使うと簡単にできますよ~


以下サンプルです


<html>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7 …
<script type="text/javascript">
var buff="";
$(document).ready(function(){
$('#ul1').each(function(){
$(this).click(function(){
buff="";
$('#ul1 li').each(function(){
buff = buff + $(this).text();
});
alert(buff);
});
});
$('#ul2').each(function(){
$(this).click(function(){
buff="";
$('#ul2 li').each(function(){
buff = buff + $(this).text();
});
alert(buff);
});
});
});
</script>
</head>
<body>
<ul id='ul1'>
<li>あ</li>
<li>い</li>
<li>う</li>
</ul>
</div>
<ul id='ul2'>
<li>え</li>
<li>お</li>
</ul>
</body>
</html>

この回答への補足

[補足]ご回答ありがとうございます。すみません。言葉足らずでした。idをふるのではなく、自動的に判別して欲しいのです
以下の例でいうと、「あ」か「い」か「う」をクリックすると、「あ」「い」「う」を取得し、
「え」か「お」をクリックすると、「え」「お」を取得する、という。

<ul>
<li>あ</li>
<li>い</li>
<li>う</li>
</ul>
</div>
<ul>
<li>え</li>
<li>お</li>
</ul>

[例2]

<div>
<span><em>あ</em></span>
</div>

<div>
<span><em>い</em></span>
</div>

<div>
<span><em>う</em></span>
</div>

<span><em>え</em></span>

<span><em>お</em></span>

何でこんなことをしたいかというと、ブラウザの拡張として利用して、自分が必要なデータを、ウェブサイト上から全て引っこ抜きたいからです。よろしくお願いいたします。

補足日時:2012/02/02 18:23
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!