重新排序 Magento JavaScript Includes (addJs)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7317044/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reorder Magento JavaScript Includes (addJs)
提问by Adam Moss
I'll keep this simple.... on my product pages I need to remove the prototype.js file and replace it with the latest version of prototype. So far using local.xml I have successfully replaced it using this:
我会保持这个简单.... 在我的产品页面上,我需要删除prototype.js 文件并将其替换为最新版本的prototype。到目前为止,我已经使用 local.xml 成功替换了它:
<action method="removeItem"><type>js</type><name>prototype/prototype.js</name></action>
<action method="addJs"><script>prototype/prototype-new.js</script></action>
The issue is that now prototype is loaded below everything other includes which stops it working.
问题是现在原型被加载到所有其他包括停止工作的东西之下。
Is there a way of setting the order of a JavaScript include using local.xml without having to remove and add every single file again?
有没有一种方法可以使用 local.xml 设置 JavaScript 的顺序,而不必再次删除和添加每个文件?
回答by Dmitri Sologoubenko
You can use the params element, with "data-group" HTML attribute in it, Magento will put items with "params" set after any items with no "params" set. You can use local.xml in your theme to ensure the order of these elements (I recommend to let Magento add its standard files first):
您可以使用 params 元素,其中包含“data-group”HTML 属性,Magento 会将设置了“params”的项目放在没有设置“params”的任何项目之后。您可以在主题中使用 local.xml 来确保这些元素的顺序(我建议先让 Magento 添加其标准文件):
<action method="addJs">
<script>prototype/javascript0.js</script>
<params><![CDATA[data-group="js002"]]></params>
<!-- creates first group js002 -->
</action>
<action method="addJs">
<script>prototype/javascript1.js</script>
<params><![CDATA[data-group="js002"]]></params>
<!-- appends to created group js002, after javascript0 -->
</action>
<action method="addJs">
<script>prototype/javascript2.js</script>
<params><![CDATA[data-group="js001"]]></params>
<!-- creates first group js001 -->
</action>
<action method="addJs">
<script>prototype/javascript3.js</script>
<params><![CDATA[data-group="js001"]]></params>
<!-- appends to created group js001, after javascript2 -->
</action>
<action method="addJs">
<script>prototype/javascript4.js</script>
<params><![CDATA[data-group="js002"]]></params>
<!-- appends to created group js002, after javascript1 -->
</action>
<action method="addJs">
<script>prototype/javascript5.js</script>
<!-- no params supplied, will be rendered before any groups -->
</action>
The order in which elements with "params" set are rendered in only determined by the order in which actions are executed. Items are rendered grouped by the value of "params", so once group "js001" is defined by the first action (javascript2.js), successive actions with the same group name will append to that group, etc.
设置了“params”的元素的呈现顺序仅由执行操作的顺序决定。项目按“params”的值分组呈现,因此一旦组“js001”由第一个动作(javascript2.js)定义,具有相同组名的连续动作将附加到该组等。
In the example above, the order of rendering will be:
在上面的例子中,渲染的顺序是:
- prototype/javascript5.js (no params, comes first)
- prototype/javascript0.js (first created params group "js002")
- prototype/javascript1.js (first created params group "js002")
- prototype/javascript4.js (first created params group "js002")
- prototype/javascript2.js (second created params group "js001")
- prototype/javascript3.js (second created params group "js001")
- prototype/javascript5.js(无参数,优先)
- 原型/javascript0.js(首先创建的参数组“js002”)
- 原型/javascript1.js(首先创建的参数组“js002”)
- 原型/javascript4.js(首先创建的参数组“js002”)
- 原型/javascript2.js(第二个创建的参数组“js001”)
- 原型/javascript3.js(第二个创建的参数组“js001”)
Items added using addItem addJs, addCss, etc, are threated in the same way, however they differ (and will be super-grouped accordingly) by type (see order below), with each group in super-groups internally ordered as explained above:
使用 addItem addJs、addCss 等添加的项目以相同的方式受到威胁,但是它们因类型而异(并将相应地进行超级分组)(请参阅下面的顺序),超级组中的每个组按上述方式进行内部排序:
- js
- skin_js
- js_css
- skin_css
- js
- skin_js
- js_css
- skin_css
回答by Anton S
Mage_Page_Block_Html_Head $_data; holds the array of those items so I guess you can filter it for your own good. Default methods does not allow defining order of added items.
Mage_Page_Block_Html_Head $_data; 保存这些项目的数组,所以我想你可以为自己的利益过滤它。默认方法不允许定义添加项目的顺序。
回答by Ken Koch
I realize this post is pretty old but i stumbled on it while researching this problem, so i figured why not.
我意识到这篇文章已经很旧了,但我在研究这个问题时偶然发现了它,所以我想为什么不呢。
Not sure if this is the most elegant solution, but its working sufficiently well for us.
不确定这是否是最优雅的解决方案,但它对我们来说效果很好。
I basically created a new block in my local.xml
like this:
<block type="core/template" name="prehead" template="page/html/prehead/main.phtml" />
我基本上local.xml
像这样创建了一个新块:
<block type="core/template" name="prehead" template="page/html/prehead/main.phtml" />
Then just modified my main layouts (1column.phtml and friends) to contain this:
<head>
<?php echo $this->getBlockHtml('prehead') ?>
<?php echo $this->getChildHtml('head') ?>
</head>
然后只是修改了我的主要布局(1column.phtml 和朋友)以包含以下内容:
<head>
<?php echo $this->getBlockHtml('prehead') ?>
<?php echo $this->getChildHtml('head') ?>
</head>
In main.phtml
I add my JS that I want to load first
在main.phtml
我添加我想先加载的 JS
<script type='text/javascript' src='<?php echo $this->getSkinUrl('js/require.js', array('_secure'=>true)); ?>'></script>
<script type='text/javascript' src='<?php echo $this->getSkinUrl('js/main.js', array('_secure'=>true)); ?>'></script>
<script type='text/javascript' src='<?php echo $this->getSkinUrl('js/require.js', array('_secure'=>true)); ?>'></script>
<script type='text/javascript' src='<?php echo $this->getSkinUrl('js/main.js', array('_secure'=>true)); ?>'></script>
This is convenient for us as well because it still allows us to change the main.js depending on what page we are on by doing something like this in local.xml
:
这对我们来说也很方便,因为它仍然允许我们根据我们所在的页面通过在 中执行以下操作来更改 main.js local.xml
:
<checkout_onestep_index translate="label">
<label>One Step Checkout</label>
<block type="core/template" name="prehead" template="page/html/prehead/checkout.phtml" />
</checkout_onestep_index>
<checkout_onestep_index translate="label">
<label>One Step Checkout</label>
<block type="core/template" name="prehead" template="page/html/prehead/checkout.phtml" />
</checkout_onestep_index>
Hope it helps someone who happens to stumble on this.
希望它可以帮助那些碰巧偶然发现的人。
-Ken
-肯
回答by Eric Seastrand
I think that Barny Shergold's solution is the most correct, but the comment about avoiding changing core files is correct. To have the best of both worlds, you can implement Barny's solution in a module that extends the Mage_Page_Block_Html_Head class like so:
我认为 Barny Shergold 的解决方案是最正确的,但是关于避免更改核心文件的评论是正确的。为了两全其美,您可以在扩展 Mage_Page_Block_Html_Head 类的模块中实现 Barny 的解决方案,如下所示:
Yourcompany/Layouthelper/etc/config.xml
您的公司/Layouthelper/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<Yourcompany_Layouthelper>
<version>0.0.1</version>
</Yourcompany_Layouthelper>
</modules>
<global>
<blocks>
<page>
<rewrite>
<html_head>Yourcompany_Layouthelper_Block_Html_Head</html_head>
</rewrite>
</page>
</blocks>
</global>
</config>
Yourcompany/Layouthelper/Block/Html/Head.php
Yourcompany/Layouthelper/Block/Html/Head.php
class Yourcompany_Layouthelper_Block_Html_Head extends Mage_Page_Block_Html_Head {
public function replaceItem($type, $name, $replace) {
$newArray = array();
foreach($this->_data['items'] as $key => $value) {
if($key == $type.'/'.$name) {
$newArray[$type . '/'. $replace] = array(
'type' => $type,
'name' => $replace,
'params' => $value['params'],
'if' => $value['if'],
'cond' => $value['cond']);
} else {
$newArray[$key] = $value;
}
}
$this->_data['items'] = $newArray;
return $this;
}
}
回答by Hassan Ali Shahzad
jquery conflict with Prototype in magento:
jquery 与 magento 中的 Prototype 冲突:
Simplest solution is to add at the end of your main jquery file.
最简单的解决方案是在主 jquery 文件的末尾添加。
jQuery.noConflict();
Or create your custom js file and add this line and also include this file after main js.
或者创建您的自定义 js 文件并添加此行,并在主 js 之后包含此文件。
回答by MagePsycho
Since local.xmlis loaded at last by the magento system, so the xml mentioned there are merged at last. That may be the reason that your new prototype is loaded below other scripts.
由于local.xml是magento系统最后加载的,所以这里提到的xml最后合并了。这可能是您的新原型加载在其他脚本下方的原因。
Alternatively, you can override the Mage_Page_Block_Html_Head::getCssJsHtml()method and play with it.
Thanks
或者,您可以覆盖Mage_Page_Block_Html_Head::getCssJsHtml()方法并使用它。
谢谢
回答by Barny Shergold
Ok here's my solution. First copy app\code\core\Mage\Page\Block\Html\head.php to app\code\local\Mage\Page\Block\Html\head.php
好的,这是我的解决方案。首先将 app\code\core\Mage\Page\Block\Html\head.php 复制到 app\code\local\Mage\Page\Block\Html\head.php
Then add this function to the file :
然后将此函数添加到文件中:
public function replaceItem($type, $name, $replace)
{
$newArray = array();
foreach($this->_data['items'] as $key => $value) {
if($key == $type.'/'.$name) {
$newArray[$type . '/'. $replace] = array(
'type' => $type,
'name' => $replace,
'params' => $value['params'],
'if' => $value['if'],
'cond' => $value['cond']);
} else {
$newArray[$key] = $value;
}
}
$this->_data['items'] = $newArray;
return $this;
}
Now in your .XML layout file include a line like this :
现在在您的 .XML 布局文件中包含这样一行:
<action method="replaceItem"><type>js</type><name>prototype/prototype.js</name><replace>onestepcheckout/prototype/prototype.js</replace></action>
The parameters are exactly as for removeItem BUT now the replace file will be injected into the list in the same place as the original file. It will also inherit the same param, if and cond values. Please use this code carefully as I've only just written and done basic tests on it!
参数与 removeItem 完全相同,但现在替换文件将被注入到列表中与原始文件相同的位置。它还将继承相同的参数、if 和 cond 值。请谨慎使用此代码,因为我刚刚编写并对其进行了基本测试!