【问题标题】:DOM object only requires two clicks in Internet ExplorerDOM 对象只需要在 Internet Explorer 中单击两次
【发布时间】:2012-03-11 08:41:09
【问题描述】:

我真的在为下面的代码苦苦挣扎。我对在 Javascript 中使用 DOM 还是很陌生,而且这个脚本在 FireFox、Chrome 和 Safari 中运行完美。在 Internet Explorer 中,它需要单击两次。如果您访问 FireFox 中的链接,然后访问 Internet Explorer 中的相同链接,您会看到,如果您在 FireFox 中单击一个形状,它会立即显示颜色选项,如果您在 Internet Explorer 中执行此操作,它将不会显示颜色选项,直到您已单击形状两次或单击一个形状,然后单击另一个形状。 IE、DOM、Javascript Ninja 能否告诉我导致需要在 IE 中单击两次的脚本有什么问题?

<?php 
$swatches = $this->get_option_swatches();
?>
<script type="text/javascript">
    document.observe('dom:loaded', function() {
        try {
            var swatches = <?php echo Mage::helper('core')->jsonEncode($swatches); ?>;

            function find_swatch(key, value) {
                for (var i in swatches) {
                    if (swatches[i].key == key && swatches[i].value == value)
                        return swatches[i];
                }
                return null;
            }

            function has_swatch_key(key) {
                for (var i in swatches) {
                    if (swatches[i].key == key)
                        return true;
                }
                return false;
            }

            function create_swatches(label, select) {
                // create swatches div, and append below the <select>
                var sw = new Element('div', {'class': 'swatches-container'});
                select.up().appendChild(sw);

                // store these element to use later for recreate swatches
                select.swatchLabel = label;
                select.swatchElement = sw;

                // hide select
                select.setStyle({position: 'absolute', top: '-9999px'});

                $A(select.options).each(function(opt, i) {
                    if (opt.getAttribute('value')) {
                        var elm;
                        var key = trim(opt.innerHTML);

                        // remove price
                        if (opt.getAttribute('price')) key = trim(key.replace(/\+([^+]+)$/, ''));

                        var item = find_swatch(label, key);
                        if (item)
                            elm = new Element('img', {
                                src: '<?php echo Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA); ?>swatches/'+item.img, 
                                alt: opt.innerHTML, 
                                title: opt.innerHTML, 
                                'class': 'swatch-img'});
                        else {
                            console.debug(label, key, swatches);
                            elm = new Element('a', {'class': 'swatch-span'});
                            elm.update(opt.innerHTML);
                        }
                        elm.observe('click', function(event) {
                            select.selectedIndex = i;
                            fireEvent(select, 'change');
                            var cur = sw.down('.current');
                            if (cur) cur.removeClassName('current');
                            elm.addClassName('current');
                        });
                        sw.appendChild(elm);
                    }
                });

            }
            // Hide Second Option's Label
            function hideStuff(id) {
                if (document.getElementById(id)) {
                    document.getElementById(id).style.display = 'none';
                }
            }
            hideStuff("last-option-label");
            function showStuff(id) {
                if (document.getElementById(id)) {
                    document.getElementById(id).style.display = '';
                }
            }

            function recreate_swatches_recursive(select) {
                // remove the old swatches
                if (select.swatchElement) {
                    select.up().removeChild(select.swatchElement);
                    select.swatchElement = null;
                }

                // create again
                if (!select.disabled)
                    showStuff("last-option-label");
                    create_swatches(select.swatchLabel, select);

                // recursively recreate swatches for the next select
                if (select.nextSetting)
                    recreate_swatches_recursive(select.nextSetting);
            }

            function fireEvent(element,event){
                if (document.createEventObject){
                    // dispatch for IE
                    var evt = document.createEventObject();
                    return element.fireEvent('on'+event, evt);      
                }
                else{
                    // dispatch for firefox + others
                    var evt = document.createEvent("HTMLEvents");
                    evt.initEvent(event, true, true ); // event type,bubbling,cancelable
                    return !element.dispatchEvent(evt);
                }
            }

            function trim(str) {
                return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
            }


            $$('#product-options-wrapper dt').each(function(dt) {

                // get custom option's label
                var label = '';
                $A(dt.down('label').childNodes).each(function(node) {
                    if (node.nodeType == 3) label += node.nodeValue;
                });
                label = trim(label);

                var dd = dt.next();
                var select = dd.down('select');
                if (select && has_swatch_key(label)) {
                    create_swatches(label, select);

                    // if configurable products, recreate swatches of the next select when the current select change
                    if (select.hasClassName('super-attribute-select')) {
                        select.observe('change', function() {
                            recreate_swatches_recursive(select.nextSetting);
                        });
                    }
                }
            });
        }
        catch(e) {
            alert("Color Swatches javascript error. Please report this error to support@galathemes.com. Error:" + e.message);
        }
    });
</script>

【问题讨论】:

  • 您能否尝试将代码示例缩减为与您的问题相关的部分?
  • 嗨,Ben,没有产生错误,我不太确定问题出在哪里......这就是我放弃整个脚本的原因。就像我说的,它在 FF、Chrome 和 Safari 中运行良好,只有在 IE 中才会出现奇怪的行为。
  • 我在你的代码中发现了奇怪的部分 $$('#product-options-wrapper dt') 你为什么使用双 $ 呢?
  • 嗨 InspiredJW 这不是我的代码,但我已经盯着它看够久了,它开始感觉它是……我相信双 $ 是因为使用了原型.js。 由于浏览器不支持这一点,您必须注意仅在已扩展的元素上使用 DOM 扩展。例如,上面的示例适用于 FF 和 Opera,但在创建元素后添加 Element.extend(my_div) 以使脚本真正可靠。您可以使用美元函数作为快捷方式,如下例所示:
  • // this will error out in IE: $('someElement').parentNode.hide() // to make it cross-browser: $($('someElement').parentNode).hide() 这里引用How Prototype Extends DOM

标签: javascript internet-explorer dom prototypejs dom-events


【解决方案1】:

console.debug 已被弃用。在“function create_swatches(label, select)”里面写了"console.debug(label, key, swatches);"改成"console.log(label, key, swatches);"你可以一起删除那行代码....... thaterrorbegone

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-07
    • 1970-01-01
    相关资源
    最近更新 更多