2017-10-13 83 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

相关问题