3

我需要在某些其他 JavaScript 文件之后包含一个 JavaScript 文件。通常,我会使用如下语法将其包含在 XML 文件中:

<action method="addJs"><script>myfile.js</script></action>

或者

<action method="addItem"><type>js</type><name>myfile.js</name></action>

以正确的顺序,因此文件以我想要的方式包含在内。

不过,关键是,我不知道我必须包含多少次我的文件。为了更具体,我试图在 jquery*.js 文件的每个实例之后包含一个带有 jQ​​uery.noConflict() 的文件。我正在开发的网站仍在开发中,可能还会添加一些新的扩展,包括他们自己的 jquery 库(我什至可能没有意识到这一点,因为我不是唯一参与该项目的人)。

在前端渲染布局时是否有包含 js 文件的事件,或者我可以重写一些方法以达到预期的效果?

4

4 回答 4

2

在每次包含脚本 Y 之后添加包含脚本 X 的唯一方法是修改执行添加的函数。

打开app/code/core/Mage/Page/Block/Html/Head.php,修改getCssJsHtml函数。像这样:

public function getCssJsHtml()
{
    // separate items by types
    $lines  = array();
    foreach ($this->_data['items'] as $item) {
        if (!is_null($item['cond']) && !$this->getData($item['cond']) || !isset($item['name'])) {
            continue;
        }
        $if     = !empty($item['if']) ? $item['if'] : '';
        $params = !empty($item['params']) ? $item['params'] : '';
        switch ($item['type']) {
            case 'js':        // js/*.js
            case 'skin_js':   // skin/*/*.js
            case 'js_css':    // js/*.css
            case 'skin_css':  // skin/*/*.css
                $lines[$if][$item['type']][$params][$item['name']] = $item['name'];
                if(stripos($item['name'], 'jquery') !== false)$lines[$if][$item['type']][$params]['2_'.$item['name']] = $yourfilename;
                break;
            default:
                $this->_separateOtherHtmlHeadElements($lines, $if, $item['type'], $params, $item['name'], $item);
                break;
        }
    }
...

你看我已经添加了一个检查来查看正在添加的文件是否是 jquery( stripos($item['name'], 'jquery') !== false),如果是,则在它之后添加一个带有 path 的新项目$yourfilename

Magento 应该已经有能力对皮肤文件进行排序,但是 a) 依赖于每个人提供排序属性,并且 b) 从一开始就没有真正正常工作。

于 2013-06-05T11:45:29.813 回答
2

嗨,

默认情况下,Magento 不允许您这样做,为了能够以特定顺序(标题中的 css 或 javascript)添加文件,您必须自定义核心。

创建一个自定义模块,在其中重写 page/html_head 块:

<?xml version="1.0"?>
<config>
    <modules>
        <Koncz_Utility>
            <version>1.0.0</version>
        </Koncz_Utility>
    </modules>
    <global>
        <blocks>
            <class>Koncz_Utility_Block</class>
            <page>
                <rewrite>
                    <html_head>Koncz_Utility_Block_Page_Html_Head</html_head>
                </rewrite>
            </page>          
        </blocks>
    </global>
</config>

并添加 2 个自定义函数:addItemFirstaddItemAfter

class Koncz_Utility_Block_Page_Html_Head extends Mage_Page_Block_Html_Head {
/*
 * Adds a head element into the first position, usage same as for addItem ;)
 */

public function addItemFirst($type, $name, $params = null, $if = null, $cond = null) {
    if ($type === 'skin_css' && empty($params)) {
        $params = 'media="all"';
    }

    $firstElement = array();
    $firstElement[$type . '/' . $name] = array(
        'type' => $type,
        'name' => $name,
        'params' => $params,
        'if' => $if,
        'cond' => $cond,
    );

    $this->_data['items'] = array_merge($firstElement, $this->_data['items']);

    return $this;
}

/*
* Adds a custom css, or js file after the $type, if it was found! $type=js/jquery/jquery.js  <= or skin_js/path 
*/
public function addItemAfter($after, $type, $name, $params = null, $if = null, $cond = null) {
    if ($type === 'skin_css' && empty($params)) {
        $params = 'media="all"';
    }

    $firstElement = array();
    $firstElement[$type . '/' . $name] = array(
        'type' => $type,
        'name' => $name,
        'params' => $params,
        'if' => $if,
        'cond' => $cond,
    );

    if (array_key_exists($after, $this->_data['items'])) :
        // get the position 
        $pos = 1;
        foreach ($this->_data['items'] as $key => $options) :
            if ($key == $after) :
                break;
            endif;
            $pos +=1;
        endforeach;

        array_splice($this->_data['items'], $pos, 0, $firstElement);

    endif;


    return $this;
}

}

在您的 local.xml 之后,您可以使用以下内容:(这将在第一个位置添加 jquery.js,在第二个位置添加 jquery 之后的 jquery.no-conflict.js)。{{ 另外值得一提的是,您的 skin_js 文件将在 js 类型之后添加!所以使用 js 而不是 skin_js 作为基础 js 文件。

<?xml version="1.0"?>
<layout version="0.1.0">
    <default>        
        <update handle="add_jquery_elegant_way" />
    </default>
    <add_jquery_elegant_way>
        <reference name="head">
            <action method="addItemFirst"><type>js</type><script>jquery/jquery.js</script></action>
            <action method="addItemAfter">
                <after>js/jquery/jquery.js</after>
                <type>js</type>
                <script>jquery/jquery.no-conflict.js</script>
            </action>
        </reference>
    </add_jquery_elegant_way>
</layout>
于 2014-02-23T11:00:38.120 回答
1

最简单的方法是编辑 jquery*.js,并将其添加到文件末尾:

$jq=jQuery.noConflict();

那么您只需使用 $jq 来访问 jQuery 对象,并且当包含 jquery.js 时,它会自动设置为 noConflict 模式。

于 2012-09-21T08:26:37.493 回答
-1

您可以将说明手动放在 header.phtml 上。应用程序/设计/前端/您的站点/路径/模板/页面/html/header.phtml。在你包含 js 之后,你放在那里的内容会转到 html。

于 2012-09-10T15:00:27.633 回答