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

时间:2017-10-13 02:50:04

标签: javascript jquery html css

我正在努力优化我的"扰流器" phpBB3上的bbcode。

现在,我有一个可行的解决方案,但是每次"扰流器"都会通过phpBB注入内联javascript。使用bbcode标签。我想调用一个常用函数,而不是每次使用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';
}

单击&#34; spoiler-btn&#34;类的锚点有一个preventDefaults,以防止点击带你到页面的顶部:

$(document).ready(function(){

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

});

我试图通过一个函数调用替换span onclick内联javascript,该函数调用通过&#39; this&#39;到外部javascript文件。我似乎无法实现这一点,所以我尝试使用jQuery捕获这个&#39;这个&#39;遍历DOM以找到&#34; div&#34;包含在&#34;剧透文本&#34; div并操纵display:none。页面上可能有多个这些扰流标签,所以我不能在&#34;扰流文本&#34;内部提供div。 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行是&#34; if&#34;检查。

jQuery已加载到网站上,我确保在正文标记关闭之前调用我的外部javascript文件。

我觉得我已经走下了兔子洞而无法看到光明。我确信这比我要做的要容易得多。

非常感谢任何帮助。谢谢!

1 个答案:

答案 0 :(得分: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将引用单击的元素,因此使用.closest().find()等DOM导航方法,您可以转到包含div,然后转到你想要操纵的元素。 .closest()比尝试链接.parent().parent()更灵活,因为它会自动上升,直到找到与指定选择器匹配的元素,因此如果您以后更改HTML结构,则JS可能不需要变化

如果.text()调用看起来令人困惑,那么jQuery会将我传递给.text()的函数作为参数调用,传递元素文本的当前值,然后返回的值变为新文本。