admin管理员组

文章数量:1398831

I need to include a JavaScript file after certain other JavaScript files. Normally, I would just include it in the XML file using syntax like:

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

or

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

in the correct order, so files are included the way I want.

The point is, though, I won't know how many times I have to include my file. To be more specyfic, I'm trying to include a file with jQuery.noConflict() after every instance of jquery*.js file. The website I'm working on is still under development and there might still be added some new extensions that include their own jquery library (and I might not even be aware of that as I am not the only person working on the project).

Is there any event on including js file when rendering the layout on the frontend or maybe there is some method I could rewrite to achieve the desired effect?

I need to include a JavaScript file after certain other JavaScript files. Normally, I would just include it in the XML file using syntax like:

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

or

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

in the correct order, so files are included the way I want.

The point is, though, I won't know how many times I have to include my file. To be more specyfic, I'm trying to include a file with jQuery.noConflict() after every instance of jquery*.js file. The website I'm working on is still under development and there might still be added some new extensions that include their own jquery library (and I might not even be aware of that as I am not the only person working on the project).

Is there any event on including js file when rendering the layout on the frontend or maybe there is some method I could rewrite to achieve the desired effect?

Share Improve this question edited Jul 15, 2024 at 5:46 mickmackusa 48.3k13 gold badges94 silver badges161 bronze badges Recognized by PHP Collective asked Sep 10, 2012 at 11:24 Bartosz GórskiBartosz Górski 1,16014 silver badges30 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 2

The only way to add an inclusion of script X after every inclusion of script Y, is to modify the function that does the adding.

Open app/code/core/Mage/Page/Block/Html/Head.php, and modify the function getCssJsHtml. Like this:

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

You see I've added a check to see whether the file being added is jquery (stripos($item['name'], 'jquery') !== false), and if so, add a new item right after it with the path $yourfilename.

Magento was supposed to already have the ability to sort skin files, but that a) relies on everyone supplying a sort attribute, and b) never actually worked properly in the first place.

Hy,

Magento by default is not allowing you to do that, in order to be able to add files in a specific order (css or javascript in header) you have to customize the core.

Create a custom module, where you rewrite the page/html_head block:

<?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>

and add 2 custom functions: addItemFirst and addItemAfter

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

}

After this in your local.xml you can use the following: (This will add jquery.js in the first position and jquery.no-conflict.js after jquery in 2nd position). {{ Also it worth mentioning that your skin_js files will be added after js types! }} So use js and not skin_js for the base js files.

<?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>

The simplest way would be to edit jquery*.js, and add this at the end of the file:

$jq=jQuery.noConflict();

then you would just use $jq to access the jQuery object, and when ever jquery.js is included it's automatically set to noConflict mode.

you can put the instruction manualy on header.phtml. app/design/frontend/yoursite/path/template/page/html/header.phtml. And what you put there go to html after you js include.

本文标签: javascriptMagento how to automatically add JS file after certain other JS filesStack Overflow