2017-10-13 6 views
0

phpBB3で「スポイラー」のbbcodeを最適化しようとしています。外部ファイルへのインラインJavaScript関数の移動とjQueryへの変換

現時点では解決策がありますが、インラインJavaScriptは「スポイラー」のbbcodeタグが使用されるたびにphpBBによって挿入されます。私はbbcodeが使用されるたびにそれをインラインで追加するのではなく、共通の関数を呼び出す必要があります。読みやすくするため

<div class="spoiler"> 
    <div class="spoiler-title"> 
     <span onclick="if (this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display != '') { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = ''; this.parentNode.getElementsByTagName('a')[0].innerText = 'hide'; } else { this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'none'; this.parentNode.getElementsByTagName('a')[0].innerText = 'show'; }"> 
      <strong>{TEXT1}</strong> (<a href="#" class="spoiler-btn" title="Show hidden content">show</a>) 
     </span> 
    </div> 
    <div class="spoiler-text"> 
     <div style="display: none;"> 
      {TEXT2} 
     </div> 
    </div> 
</div> 

、インラインのonclick関数はここで繰り返される:

if (this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display != '') { 
    this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = ''; 
    this.parentNode.getElementsByTagName('a')[0].innerText = 'hide'; 
} else { 
    this.parentNode.parentNode.getElementsByTagName('div')[1].getElementsByTagName('div')[0].style.display = 'none'; 
    this.parentNode.getElementsByTagName('a')[0].innerText = 'show'; 
} 

を "スポイラー-BTN" のクラスとのアンカーをクリックすると、ここで

はインラインJavaScriptを働いていることですその上にpreventDefaultsが設定されているため、クリックがページの先頭に移動しないようにします。

$(document).ready(function(){ 

    $(".spoiler-btn").click(
     function(e) { 
     e.preventDefault(); 
     } 
    ); 

}); 

私はスパンonclick inline javascriptを、これを外部のjavascriptファイルに渡す関数呼び出しで置き換えようとしていました。私はそれを働かせるように見えませんでしたので、私はjQueryを使って "スポイラーテキスト" divに含まれている "div"を見つけてディスプレイを操作するためにDOMをトラバースするために 'this'を捕捉しようとしました。ページにはこれらのスポイラータグが複数存在することがあるので、「スポイラーテキスト」divの内側にdivを付けることはできません。

ここで私は外部関数にスパンのonclickのを変更:

onclick="spoilerToggle(this);" 

私はその後、私の外部ファイルに次のようにあります :

var spoilerToggle = function(param) { 
    if ($(this).parent('div').parent('div').hasClass('spoiler-text').css('style') == 'none') { 
     ($(this).parent('div').parent('div').hasClass('spoiler-text').removeAttr('style')); 
     ($(this).parent('div').$('a').text('hide')); 
    } else { 
     ($(this).parent('div').parent('div').hasClass('spoiler-text').css('display', 'none')); 
     ($(this).parent('div').$('a').text('show')); 
    } 
} 

コンソールは、次のエラーを与えますcssは関数ではありません。

22行目は、次のようになります。 "if"チェックを付けてください。

jQueryがサイトにロードされており、bodyタグが閉じる前に外部javascriptファイルを呼び出すようにしています。

私はウサギの穴を塞いだと感じ、光を見ることができません。私はこれを作るよりもずっと簡単だと確信しています。

ご協力いただきまして誠にありがとうございます。ありがとうございました!

答えて

1

.hasClass()はブール値を返します。したがって、後に他のメソッドを連結することはできません。だからあなたがあなたが引用したエラーを得るのです。私はそれにかかわらず、別の方法実装し

:上記

$(document).on("click", ".spoiler-title", function(e) { 
 
    e.preventDefault(); 
 
    var container = $(this).closest(".spoiler"); 
 
    container.find(".spoiler-btn").text(function(i, currentText) { 
 
    return currentText === "show" ? "hide" : "show" 
 
    }); 
 
    container.find(".spoiler-text div").toggle(); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<div class="spoiler"> 
 
    <div class="spoiler-title"> 
 
     <span> 
 
      <strong>{TEXT1}</strong> (<a href="#" class="spoiler-btn" title="Show hidden content">show</a>) 
 
     </span> 
 
    </div> 
 
    <div class="spoiler-text"> 
 
     <div style="display: none;"> 
 
      {TEXT2} 
 
     </div> 
 
    </div> 
 
</div>

は、ページ上のすべてのスポイラー要素のクリックを処理するために、文書にバインドされたシングル、委任クリックハンドラを使用しています(代わりに、すべてのスポイラーを含む最低レベルのものであれば、下位のコンテナエレメントにバインドすることができます)。あなたが含むdiv要素に上がると、その後ダウンあなたが操作したい要素にすることができるよう.closest()などのDOMナビゲーションメソッドを持つように.find()

ハンドラ内で、thisは、クリックされた要素を指します。 .closest()は、.parent().parent()をチェーンしようとするよりも柔軟性があります。これは、指定されたセレクタに一致する要素が見つかるまで自動的に上がるので、後でJSを変更する必要はありません。

.text()コールが混乱するように見える場合、jQueryは、.text()に渡された関数を引数として呼び出し、要素のテキストの現在の値を渡してから、返される値が新しいテキストになります。

+0

ありがとうございます!私はスポイラータイトルクラスからon.spoiler-btnへのonclickセレクターを調整して動作させる必要がありました。 – Jedis

+0

問題ありません。クリックセレクタに '.spoiler-title'を使用しました。なぜなら、アンカーには必ずしも必要ではなく、そのdiv内のどこかをクリックできるようにしたいと思ったからです。インラインJSあなたはアンカーではなくスパン上のクリックハンドラを持っていました。表示/非表示をアンカー自体のクリックだけで行いたい場合は、ここで示したコードを少し簡略化することができます。簡単なアニメーションを追加するには、 '.toggle()'ではなく '.slideToggle()'を試してみてください。 – nnnnnn

+0

ああ、それはさらに理にかなっています!しかし、それはタイトルの仕事をクリックしただけです - アンカーをクリックしても何もしませんでした。私はセレクタの前に.postbodyを前置していました。これは上記のあなたのアドバイスに従って、コンテナーdivのphpBB3が投稿に使用するためです。 – Jedis

関連する問題