【问题标题】:Reorder Magento JavaScript Includes (addJs)重新排序 Magento JavaScript 包含 (addJs)
【发布时间】:2011-09-06 08:33:52
【问题描述】:

我会保持简单....在我的产品页面上,我需要删除prototype.js 文件并将其替换为最新版本的原型。到目前为止,使用 local.xml 我已经成功地用这个替换了它:

<action method="removeItem"><type>js</type><name>prototype/prototype.js</name></action>
<action method="addJs"><script>prototype/prototype-new.js</script></action>

问题在于,现在原型加载到了其他所有内容的下方,这会导致它停止工作。

有没有一种方法可以使用 local.xml 设置 JavaScript 的顺序,而无需再次删除和添加每个文件?

【问题讨论】:

    标签: javascript magento


    【解决方案1】:

    您可以使用 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>
    

    设置了“params”的元素的呈现顺序仅由执行操作的顺序决定。项目按“params”的值分组呈现,因此一旦第一个操作(javascript2.js)定义了组“js001”,具有相同组名的后续操作将附加到该组,等等。

    在上面的例子中,渲染的顺序是:

    • prototype/javascript5.js(无参数,优先)
    • prototype/javascript0.js(首先创建的参数组“js002”)
    • prototype/javascript1.js(首先创建的参数组“js002”)
    • prototype/javascript4.js(首先创建的参数组“js002”)
    • prototype/javascript2.js(第二个创建的参数组“js001”)
    • prototype/javascript3.js(第二个创建的参数组“js001”)

    使用 addItem addJs、addCss 等添加的项目以相同的方式受到威胁,但是它们按类型不同(并将相应地进行超分组)(请参见下面的顺序),超组中的每个组在内部排序为上面解释过:

    • js
    • skin_js
    • js_css
    • skin_css

    【讨论】:

    • 如果您使用“Mygento JQuery 库和插件”模块,它适用于所有 jQuery 插件,将 name-param 设置为“last”或“[plugin name]”
    • 很好的解决方案,但只能在同一个区域内工作——如果你想强制包含到所有这些的顶部或底部,你不能。至少,除非你在 &_prepareStaticAndSkinElements 的 mage/page/block/html/head 中加入 krsort($items)
    • 这可以通过 addItem 方法实现吗?我的皮肤文件夹中有 js。如果可能的话,我无法获得正确的语法 - 有什么想法吗?
    • 我不相信这有任何影响。正如@l-barker 指出的那样,它将参数添加到脚本标记中,但不使用此参数进行排序。我单步执行了代码,没有进行排序。我认为您很幸运,因为您的文件恰好包含在您想要的顺序中,但不能保证这一点。我不知道他们为什么不支持像布局一样的“after=''”和“before=''”参数。我会继续寻找解决方案。
    • @BrianVPS:它有效果(参见 Mage_Page_Block_Html_Head::getCssJsHtml() 方法的代码),但恐怕与我最初解释的不完全一样。 PHP 保持关联数组元素与添加的顺序相同(除非执行排序),但 getCssJsHtml 中的代码按 中的值对项目进行分组。请参阅新修订的解释,它应该更准确和完整。感谢您的反馈!
    【解决方案2】:

    Mage_Page_Block_Html_Head $_data;保存这些项目的数组,所以我想你可以为自己的利益过滤它。默认方法不允许定义添加项目的顺序。

    【讨论】:

      【解决方案3】:

      我意识到这篇文章已经很老了,但是我在研究这个问题时偶然发现了它,所以我想为什么不这样做。

      不确定这是否是最优雅的解决方案,但它对我们来说足够好。

      我基本上在我的local.xml 中创建了一个新块,如下所示: <block type="core/template" name="prehead" template="page/html/prehead/main.phtml" />

      然后只是修改了我的主要布局(1column.phtml 和朋友)以包含以下内容: <head> <?php echo $this->getBlockHtml('prehead') ?> <?php echo $this->getChildHtml('head') ?> </head>

      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>

      这对我们来说也很方便,因为它仍然允许我们根据我们所在的页面更改 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>

      希望它对碰巧遇到此问题的人有所帮助。

      -肯

      【讨论】:

      • 是的,这是可行的,但是当我们合并 js 时,我们如何从“prehead”中添加合并 js 文件。
      【解决方案4】:

      由于local.xml是magento系统最后加载的,所以这里提到的xml最后被合并了。这可能是您的新原型加载到其他脚本下方的原因。

      或者,您可以覆盖 Mage_Page_Block_Html_Head::getCssJsHtml() 方法并使用它。

      谢谢

      【讨论】:

        【解决方案5】:

        好的,这是我的解决方案。 先复制app\code\core\Mage\Page\Block\Html\head.php到app\code\local\Mage\Page\Block\Html\head.php

        然后将此函数添加到文件中:

        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;
        }
        

        现在在您的 .XML 布局文件中包含这样的一行:

        <action method="replaceItem"><type>js</type><name>prototype/prototype.js</name><replace>onestepcheckout/prototype/prototype.js</replace></action>
        

        参数与 removeItem 完全相同,但现在替换文件将被注入到列表中与原始文件相同的位置。它还将继承相同的参数、if 和 cond 值。请谨慎使用此代码,因为我只是在上面编写并完成了基本测试!

        【讨论】:

        • 这些变通办法的重点是避免更改核心 Magento 文件,因为这是不好的做法。
        【解决方案6】:

        我认为 Barny Shergold 的解决方案是最正确的,但是关于避免更改核心文件的评论是正确的。为了两全其美,您可以在扩展 Mage_Page_Block_Html_Head 类的模块中实现 Barny 的解决方案,如下所示:

        您的公司/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

        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;
            }
        }
        

        【讨论】:

          【解决方案7】:

          jquery 与 magento 中的 Prototype 冲突:

          最简单的解决方案是在主 jquery 文件的末尾添加。

          jQuery.noConflict();
          

          或者创建您的自定义 js 文件并添加此行,并在主 js 之后包含此文件。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-11-01
            • 2016-02-27
            • 2014-07-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多