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

标签 javascript jquery html css

我正在尝试优化我在 phpBB3 上的“剧透”bbcode。

现在,我有一个可行的解决方案,但每次使用“剧透”bbcode 标签时,phpBB 都会注入(inject)内联 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>

为了阅读方便,这里重复了内联的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';
}

点击“spoiler-btn”类的 anchor 有一个preventDefaults,以防止点击将您带到页面顶部:

$(document).ready(function(){

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

});

我试图用将“this”传递给外部 javascript 文件的函数调用替换 span onclick 内联 javascript。我似乎无法让它工作,所以我尝试使用 jQuery 捕获“this”以遍历 DOM 以找到包含在“spoiler-text”div 中的“div”并操纵显示:无。页面上可以有多个剧透标签,所以我不能给“剧透文本”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 Uncaught TypeError: $(...).parent(...).parent(...).hasClass(...).css 不是函数

第 22 行是带有“if”检查的行。

jQuery 已加载到网站上,并且我确保在 body 标记结束之前调用我的外部 javascript 文件。

我觉得自己掉进了兔子洞,看不到光。我确信这比我想象的要容易得多。

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

最佳答案

.hasClass()返回一个 bool 值,所以你不能在它后面链接其他方法。这就是为什么你得到你引用的错误。

不过我会以不同的方式实现它:

$(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>

上面使用绑定(bind)到文档的单个委托(delegate)点击处理程序来处理页面上所有剧透元素的点击(您可以将它绑定(bind)到较低级别的容器元素,无论最低级别是包含所有剧透)。

在处理程序中,this 将引用被点击的元素,因此对于 DOM 导航方法,例如 .closest().find()您可以向上移动到包含的 div,然后向下移动到您想要操作的元素。 .closest() 比尝试链接 .parent().parent() 更灵活,因为它会自动上升,直到找到与指定选择器匹配的元素,因此,如果您以后更改 HTML 结构,则 JS 可能不需要更改。

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

关于javascript - 将内联 javascript 函数移动到外部文件并转换为 jQuery,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46721768/

相关文章:

javascript - 如何创建一个简单的 JavaScript 计时器?

javascript - 当我点击离开时隐藏 DIV

javascript - 如何清除文件输入元素

html - 具有最大宽度/高度且没有 CSS 的 HTML 中的响应图像

javascript - ASP.NET - HTML 页面在由 Visual Studio 启动然后在外部启动时看起来不同

javascript - 检查 jQuery 事件类型

javascript - Loop Div 的 Jquery

javascript - Jasmine 测试未检测到 jQuery 国际化常量

javascript - iFrame 内的第 3 方应用程序?

HTML/CSS 动画背景