【问题标题】:Rails 4 jQuery conflicts with javascriptRails 4 jQuery 与 javascript 冲突
【发布时间】:2016-08-12 14:29:23
【问题描述】:

我正在尝试在 Rails 4 中制作应用程序。

我在挣扎。我正在尝试合并一个引导主题,但我遇到了供应商 javascripts 和其余代码的问题。

我认为问题可能与在我的 application.js 中使用 jQuery,然后使用以“$”符号开头的供应商 .js 文件有关:

$.circleProgress = {

我刚刚读到这个:https://learn.jquery.com/using-jquery-core/avoid-conflicts-other-libraries/

我的问题是我不知道如何进行更改以确保代码安全。

我是否需要搜索供应商文件中的每个“$”,或者如何在 jQuery 上放置一个安全的包装器——尤其是通过 gem 合并的地方。

有没有人遇到过这些问题并想出了解决办法?我很想得到一些帮助。

应用程序.js

//= require jquery
//= require bootstrap-sprockets
//= require jquery_ujs
//= require html.sortable
//= require disqus_rails
//= require moment
//= require bootstrap-datetimepicker
//= require pickers
//= require main
//= require hammer.min
//= require jquery.animate-enhanced.min
//= require jquery.countTo
//= require jquery.easing.1.3
//= require jquery.fitvids
//= require jquery.magnific-popup.min
//= require jquery.parallax-1.1.3
//= require jquery.properload
//= require jquery.shuffle.modernizr.min
//= require jquery.sudoSlider.min
//= require jquery.superslides.min
//= require masonry.pkgd.min
//= require rotaterator
//= require smoothscrolljs
//= require waypoints.min
//= require wow.min
//= require gmaps/google
//= require chosen-jquery
//= require cocoon
//= require imagesloaded.pkgd.min
//= require isotope.pkgd.min
//= require jquery.counterup.min
//= require jquery.pjax
//= require custom.js
//= require slider
//= require underscore
//= require dependent-fields
//= require_tree .
//= require bootstrap-slider


$(document).ready(function() {
    DependentFields.bind()
});

相关问题:Rails 4 - incorporating vendor assets

观察

我注意到控制台错误日志显示我的 app/assets/javascripts 文件夹中的 .js 文件存在问题。

它们是该文件夹中唯一的其他文件(除了 application.js)。我的 application.js 有“require_tree”,因此它们将被编译。但我认为这些文件中的某些内容可能与(可能)在 application.js 中包含 jQuery 相冲突?

日志显示:

Uncaught SyntaxError: Identifier 'findGoodContent' has already been declared
circle-progress.self-f67ec54c54a06da27d11cda862036a058792eadc8ef982df2e7c0a1682536c31.js:9 Uncaught TypeError: Cannot set property 'circleProgress' of undefined
conversations.self-832ece2867c1701a5202459ab73ecd6432da2a6c833d8822d37025845a0aefcc.js:10 Uncaught TypeError: $ is not a function
organisations.self-6547f734e3a69b76176dfe5bb194e428c0bc560ad3fb69811dce9c7f8ccb9f4d.js:2 Uncaught TypeError: $ is not a function
http://localhost:3000/assets/%3C%=%20asset_path('random.jpg')%20%%3E Failed to load resource: the server responded with a status of 400 (Bad Request)
http://localhost:3000/profiles/assets/images/grayscale.svg#greyscale Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:3000/assets/vendor/assets/fonts/Simple-Line-Icons.woff Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:3000/profiles/assets/custom/images/preloader.gif Failed to load resource: the server responded with a status of 404 (Not Found)
chrome-extension://mkjojgglmmcghgaiknnpgjgldgaocjfd/content/contentScripts/kwift.CHROME.min.js:1384 Uncaught SyntaxError: Identifier 'findGoodContent' has already been declared
http://localhost:3000/assets/flaticon.woff Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:3000/assets/vendor/assets/fonts/Simple-Line-Icons.ttf Failed to load resource: the server responded with a status of 404 (Not Found)
http://localhost:3000/assets/flaticon.ttf Failed to load resource: the server responded with a status of 404 (Not Found)
main.self-5888479bd3eb03114ce5776dd32cfadf84f1d3a4335043513f8b1606d3ab5f4a.js:316 Uncaught TypeError: dp(...).multipleFilterMasonry is not a function

每个被识别为错误的 js 文件夹都保存为 app/assets/javascripts 中的 .js 文件。

我是否可能需要使用不同的文件名(.js.erb / js.coffee)?使这项工作。或者,我是否需要在这些文件的内容周围放置脚本标签?

例如,第一个文件打开时:

$.circleProgress = {
    // Default options (you may override them)
    defaults: {
        /**
         * This is the only required option. It should be from 0.0 to 1.0
         * @type {float}
         */
        value: 0,

更新

我认为我的问题的一部分与保存在 app/assets/javascripts 中的文件有关,扩展名为“.js”。它们中的每一个都在控制台错误列表中显示为:

kwift.CHROME.min.js:1271Uncaught SyntaxError: Identifier 'findGoodContent' has already been declared
circle-progress.self-f67ec54….js?body=1:9 Uncaught TypeError: Cannot set property 'circleProgress' of undefined(anonymous function) @ circle-progress.self-f67ec54….js?body=1:9
conversations.self-832ece2….js?body=1:10 Uncaught TypeError: $ is not a function(anonymous function) @ conversations.self-832ece2….js?body=1:10
organisations.self-6547f73….js?body=1:2 Uncaught TypeError: $ is not a function(anonymous function) @ organisations.self-6547f73….js?body=1:2(anonymous function) @ organisations.self-6547f73….js?body=1:6
projects.self-9c019ba….js?body=1:1 Uncaught TypeError: $ is not a function(anonymous function) @ projects.self-9c019ba….js?body=1:1
main.self-5888479….js?body=1:316 Uncaught TypeError: dp(...).multipleFilterMasonry is not a functionwindow.onload @ main.self-5888479….js?body=1:316
kwift.CHROME.min.js:1271 Uncaught SyntaxError: Identifier 'findGoodContent' has already been declared

【问题讨论】:

  • 您的浏览器控制台对此有何看法?
  • 未捕获的类型错误:无法设置未定义的属性“circleProgress”
  • 在 safari 中,错误消息是:TypeError: undefined is not an object (evalating '$') (anonymous function)circle-progress.self-f67ec54c54a06da27d11cda862036a058792eadc8ef982df2e7c0a1682536c31.js:8
  • 能不能发一下application.js,估计是js导入顺序的问题。
  • 已添加 - 我还添加了指向我遇到的问题的链接

标签: javascript jquery ruby-on-rails ruby twitter-bootstrap


【解决方案1】:

听起来您有很多清理工作要做。这是您的第一个 Rails 应用程序吗?如果是这样,我很好奇为什么你已经有这么多 JS 文件。我会将您的列表减少到几个,解决仍然存在的问题,然后慢慢开始添加内容并解决问题。这将是我的一般策略。对于每个错误,请慢慢来,并仔细检查您是否真的了解原因,然后再到处乱砍以寻求修复。

以下是针对我看到的特定错误的一些提示:

这一行将包含app/assets/javascripts 中的所有.js 文件:

//= require_tree .

问题是您已经在上面一一包含了它们。所以他们被包括在内两次。这就是为什么你会收到像'findGoodContent' has already been declared 这样的警告。我知道使用require_tree 有点好(虽然我不喜欢它),所以如果你想保留它,请考虑将所有第 3 方 JS 文件移出app/assets/javascripts 并移入vendor/assets/javascripts。你仍然可以在你的application.jsrequire 他们,但他们不会被require_tree 重复。

grayscale.svgflaticon.woff 以及其他图像/字体资产的 404 错误是因为您在 app/assets(或 vendor/assets)中没有这些文件。或者如果你这样做了,你应该确保你的 JS/CSS 文件和视图文件使用<%= asset_path "grayscale.svg" %> 引用它们,这样当 Rails 破坏它们的路径时,你仍然可以从正确的位置加载它们。阅读image_url and friends 并确保您了解它们的工作原理。默认情况下,Asset Pipeline 在开发中提供未损坏的名称,在生产中提供损坏的名称,因此在您将其全部上线之前,一切都可能正常运行!

此外,如果您在 CSS 文件或 JS 文件中包含 <%= foo %> 标签,那么您需要在该文件中添加 .erb 扩展名,以便 Rails 知道处理这些标签。这就是您尝试加载此内容时遇到 404 错误的原因:

http://localhost:3000/assets/%3C%=%20asset_path('random.jpg')%20%%3E

在你的一个文件中,可能是一个 CSS 文件,你正在做这样的事情:

background-image: url("<%= asset_path('random.jpg') %>");

但文件需要.erb 扩展名:blah.css.erbblah.scss.erb 或其他。

$ is not a function 之类的错误意味着这些文件依赖于 jQuery,但没有定义 jQuery $ 对象。如果您使用 noConflict,正如 cmets 中有人建议的那样,您应该停止,因为您确实希望 $ 成为 jQuery 对象。

祝你好运!如果您感到不知所措,我真的会从尽可能多地删除 JS require 行开始,并一次解决一个错误。

另外,我会重新排序 require 行,以便依赖项位于顶部(例如 jquery),而依赖它们的东西则较低。

还有一件事,不是真正的错误:我会避免将已经缩小的文件(如hammer.min.js)放入您的存储库。资产管道知道如何缩小。所以签入未缩小版,这样如果非要读源码就可以了。

【讨论】:

  • 嗨 Paul - 不,我没有在我的 application.js 中包含我的 app/assets/javascripts 文件夹中的文件(除了需要树)。您看到的列表只是带有引导主题的供应商/javascripts 的文件(它们都存储在我的供应商资产文件夹中)。 “findgoodcontent”错误来自 chrome 插件。该错误不会显示在 safari 或 firefox 代码检查器中。感谢您提供有关缩小文件的提示。不幸的是,引导主题只提供了缩小的文件,所以我有点坚持。
  • 目前错误列表是我在帖子的更新标题下复制的列表。除了“find goodcontent”错误之外,这些文件的共同点是它们都存储在我的 app/assets/javascripts 文件夹中,并且都保存为“.js”扩展名并且不包含“无冲突”语言。我除此之外无法弄清楚。
  • 你的这部分答案包含一个线索:像 $ is not a function 这样的错误意味着这些文件依赖于 jQuery,但没有定义 jQuery $ 对象。如果您使用 noConflict,正如 cmets 中有人建议的那样,您应该停止,因为您确实希望 $ 成为 jQuery 对象。
  • 问题是,按照这篇文章中的建议:stackoverflow.com/questions/36853833/…,我添加了没有冲突的语言。它摆脱了控制台错误,但隐藏/显示功能本身不起作用。
  • “问题是你已经在上面一个接一个地包含了它们。所以它们被包含了两次。” - 错了,他们有一个内置的保护。即使您明确指定文件两次,链轮也会忽略第二个包含。
【解决方案2】:

我把这篇文章作为工作上的工作发布。

解决方案很复杂,但如果它有助于其他人了解问题所在:

  1. 一些 gem 需要 jQuery 特性。这可能与在 application.js 中一般包含 jQuery 发生冲突——我编写了一些特定的代码来管理特定的冲突。

  2. 在application.js中,需要按顺序列出所有的需求,这样依赖就在依赖它们的js文件下面。很难知道哪个文件取决于什么。我一个人永远也想不通

  3. 我的 rake assets:precompile 调用将已编译的资产放入公用文件夹中。我覆盖了它,因为它会导致与其他调用发生冲突(尤其是在更新文件时)。

对于任何试图学习的人来说,这个答案没有真正的帮助。我自己并没有完全学会如何解决这些问题,但我确实找到了一位工作专家,他能够提供帮助,让我可以继续前进。

恐怕这是博客教程无法解决的混乱问题之一。

【讨论】:

    【解决方案3】:

    不知道为什么没有人发布这个,但是 jQuery 中的 $.something 只是 jQuery.something 的简写。

    禁用此功能的功能已融入 jQuery

    https://api.jquery.com/jquery.noconflict/

    这是他们文档中的一个例子

    jQuery.noConflict();
    // Do something with jQuery
    jQuery( "div p" ).hide();
    // Do something with another library's $()
    $( "content" ).style.display = "none";
    

    本质上,在您的手卷代码中使用“jQuery”与“$”比更改继承的库要容易得多。话虽如此,您应该向有问题的库提交问题以修复此功能,类似于 jQuery 的做法,因为 jQuery 非常流行。

    祝你好运!

    【讨论】:

    • 嗨 - 我试过了,但问题是其他 JS 插件也需要 $,所以我不能使用 noConflict。还是谢谢你的建议
    • noConflict 应该移除 jQuery 对 $... 的绑定,因此对于启用 noConflict 的 jQuery 代码,您必须使用“jQuery”显式调用它。而不是“$”。如果它不起作用,您可能需要在加载其他库之前调用 jQuery noConflict。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-03
    • 1970-01-01
    • 1970-01-01
    • 2019-06-26
    • 2014-02-21
    • 1970-01-01
    相关资源
    最近更新 更多