将内联javascript函数移动到外部文件并转换为jQuery

将内联javascript函数移动到外部文件并转换为jQuery,javascript,jquery,html,css,Javascript,Jquery,Html,Css,我正在尝试优化我在phpBB3上的“扰流板”代码 现在,我有一个可行的解决方案,但是每次使用“spoiler”bbcode标记时,phpBB都会注入内联javascript。我想调用一个公共函数,而不是每次使用bbcode时都内联添加它 以下是正在使用的内联javascript: <div class="spoiler"> <div class="spoiler-title"> <span onclick="if (this.parentNo

我正在尝试优化我在phpBB3上的“扰流板”代码

现在,我有一个可行的解决方案,但是每次使用“spoiler”bbcode标记时,phpBB都会注入内联javascript。我想调用一个公共函数,而不是每次使用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>
单击带有“扰流板btn”类的锚点上有一个默认值,以防止单击将您带到页面顶部:

$(document).ready(function(){

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

});
我试图用一个将“this”传递给外部javascript文件的函数调用替换span onclick内联javascript。我似乎无法实现这一点,所以我尝试使用jQuery捕获“this”遍历DOM,找到“spoiler text”div中包含的“div”,并操纵显示:none。页面上可能有多个扰流板标签,因此我无法为“扰流板文本”div中的div提供id

在这里,我将span的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未捕获的TypeError:$(…).parent(…).parent(…).hasClass(…).css不是函数

第22行是带有“如果”检查的行

jQuery在站点上加载,我确保在body标记关闭之前调用我的外部javascript文件

我觉得自己好像掉进了兔子洞,看不见光线。我相信这比我想象的要容易得多

非常感谢您的帮助。谢谢大家!

返回一个布尔值,因此不能在其后链接其他方法。这就是为什么你会得到你引用的错误

不过,我会以不同的方式实施:

$(文档)。在(“单击”,“扰流板标题”,功能(e){
e、 预防默认值();
var容器=$(此);
container.find(“.spoiler btn”).text(函数(i,currentText){
return currentText==“显示”?“隐藏”:“显示”
});
container.find(“.spoiler text div”).toggle();
});

{TEXT1}()
{TEXT2}

非常感谢!我不得不将onclick选择器从spoiler标题类调整为a.spoiler-btn以使其正常工作。没问题。我使用了
.spoiler title
作为点击选择器,因为我认为您希望能够点击该div中的任何位置(如果运行我的代码片段,您可以看到该操作),而不一定只在锚上,因为在原始的内联JS中,您的点击处理程序位于span而不是锚上。如果您只希望通过单击锚点本身来完成显示/隐藏,那么我显示的代码可以简化一点。您也可以尝试
.slideToggle()
而不是
.toggle()
,来添加一些简单的动画。哦,这更有意义!然而,这只会让点击标题起作用——点击锚没有任何作用。我还在选择器前面预先添加了.postbody,因为根据您的建议,这是phpBB3用于POST的容器div。“单击锚没有做任何事情”-这很奇怪,因为在我的演示片段中单击锚可以很好地工作。也许在你真正的项目中还有其他一些不同之处。关于container div,我指的是
$(“.postbody”)。在(“click”、“.spoiler title”、function(){…})
上,也就是说,将container div的选择器放在我获得
文档的地方(只要它引用的是JS运行时存在的静态元素,而不是稍后通过Ajax加载的元素).我将选择器更改为
.postbody.spoiler title
,然后单击标题上的任意位置,以及锚定现在效果很好。非常感谢!
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'));
    }
}