2017-10-13 40 views
0

我想優化我的phpBB3上的「擾流板」bbcode。將內嵌javascript函數移動到外部文件並轉換爲jQuery

現在,我有一個工作解決方案,但每次使用「擾流器」bbcode標記時,內聯javascript都會被phpBB注入。我想調用一個通用函數,而不是每次使用bbcode時都添加它。

這裏是工作的內聯JavaScript:

<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」 的有一個preventDefaults它,以防止點擊帶你到頁面頂部:

$(document).ready(function(){ 

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

}); 

我試圖用一個將'this'傳遞給外部javascript文件的函數調用替換span onclick內聯javascript。我似乎無法得到那個工作,所以我嘗試使用jQuery來捕獲'this'來遍歷DOM以找到包含在「spoiler-text」div中的「div」並操縱display:none。在頁面上可以有多個這些破壞者標籤,所以我不能將div中的「spoiler-text」div賦予一個id。

在這裏,我改變了跨度的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')); 
    } 
} 

控制檯則提供了以下錯誤: bbcode.js:22 Uncaught TypeError:$(...)。parent(...)。parent(...)。hasClass(...).css不是函數

第22行是行與「如果」檢查。

在網站上加載了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>

以上使用綁定到文件來處理網頁上的所有擾流板元素的點擊次數(單,委託點擊事件處理您可以將其綁定到較低級別的容器元素,無論最低級別包含所有破壞者)。

在處理程序,this將參照點擊的元素,因此與DOM的導航方法,如.closest().find()你可以去到包含分區,然後到你想要操作的元素。 .closest()比試圖鏈接.parent().parent()更靈活,因爲它會自動上升,直到它找到匹配指定選擇器的元素,所以如果以後更改了HTML結構,則JS可能不需要更改。

如果.text()調用看起來很混亂,那麼發生的情況是jQuery調用我傳遞給.text()作爲參數的函數,將元素文本的當前值傳遞給它,然後返回所有值成爲新文本。

+0

非常感謝!我不得不將spoiler-title類中的onclick選擇器調整爲a.spoiler-btn以使其工作。 – Jedis

+0

沒問題。我使用'.spoiler-title'作爲點擊選擇器,因爲我認爲你希望能夠點擊該div內的任何地方(如果你運行我的代碼段,你可以看到工作),不一定只是在錨點上,因爲在你的原始內聯JS你有你的點擊處理程序的跨度而不是錨點。如果您只希望通過點擊錨點來完成顯示/隱藏,那麼我已經顯示的代碼可以簡化一下。您也可以嘗試使用'.slideToggle()'而不是'.toggle()'來添加一些簡單的動畫。 – nnnnnn

+0

哦,那更有意義!然而,只是點擊標題作品 - 點擊主播沒有做任何事情。我還在選擇器前添加了.postbody,因爲這是phpBB3用於發佈帖子的容器div,根據上面的建議。 – Jedis

相關問題