Javascript - 绕过脚本中的新元素

时间:2010-07-11 01:42:13

标签: javascript spry

我有一组标签,可以在点击时更改主面板。为了更改特定的颜色属性,我需要在HTML中插入一个额外的div。但是,当我这样做时,它会导致javascript中出错。我不是javascript专家,但我认为原因是该脚本正在调用特定顺序的元素。因此,当我向图片中添加一个新元素时,它就失去了它的轨迹。这是我的HTML。基本上ul中的所有项目始终可见,当您单击其中一项时,它会使相应的内容可见:

<div id="TabbedPanels">
<div id="TabbedPanels1" class="VTabbedPanels">
  <div class="TabbedPanelsContentGroup">
     <div class="TabbedPanelsContent">1</div>
     <div class="TabbedPanelsContent">2</div>
     <div class="TabbedPanelsContent">3</div>
  </div>
  <ul class="TabbedPanelsTabGroup">
    <li class="TabbedPanelsTab" tabindex="0">1</li>
    <li class="TabbedPanelsTab" tabindex="0">2</li>
    <li class="TabbedPanelsTab" tabindex="0">3</li>
  </ul>
</div>
</div> 

所以现在我想在theTabbedPanelsContentGroup div上滑动一个div,但就像我说的那样,它会让一切变得混乱。这是完整的js:

var Spry;
if (!Spry) Spry = {};
if (!Spry.Widget) Spry.Widget = {};

Spry.Widget.TabbedPanels = function(element, opts)
{
    this.element = this.getElement(element);
    this.defaultTab = 0; // Show the first panel by default.
    this.tabSelectedClass = "TabbedPanelsTabSelected";
    this.tabHoverClass = "TabbedPanelsTabHover";
    this.tabFocusedClass = "TabbedPanelsTabFocused";
    this.panelVisibleClass = "TabbedPanelsContentVisible";
    this.focusElement = null;
    this.hasFocus = false;
    this.currentTabIndex = 0;
    this.enableKeyboardNavigation = true;
    this.nextPanelKeyCode = Spry.Widget.TabbedPanels.KEY_RIGHT;
    this.previousPanelKeyCode = Spry.Widget.TabbedPanels.KEY_LEFT;

    Spry.Widget.TabbedPanels.setOptions(this, opts);

    // If the defaultTab is expressed as a number/index, convert
    // it to an element.

    if (typeof (this.defaultTab) == "number")
    {
        if (this.defaultTab < 0)
            this.defaultTab = 0;
        else
        {
            var count = this.getTabbedPanelCount();
            if (this.defaultTab >= count)
                this.defaultTab = (count > 1) ? (count - 1) : 0;
        }

        this.defaultTab = this.getTabs()[this.defaultTab];
    }

    // The defaultTab property is supposed to be the tab element for the tab content
    // to show by default. The caller is allowed to pass in the element itself or the
    // element's id, so we need to convert the current value to an element if necessary.

    if (this.defaultTab)
        this.defaultTab = this.getElement(this.defaultTab);

    this.attachBehaviors();
};

Spry.Widget.TabbedPanels.prototype.getElement = function(ele)
{
    if (ele && typeof ele == "string")
        return document.getElementById(ele);
    return ele;
};

Spry.Widget.TabbedPanels.prototype.getElementChildren = function(element)
{
    var children = [];
    var child = element.firstChild;
    while (child)
    {
        if (child.nodeType == 1 /* Node.ELEMENT_NODE */)
            children.push(child);
        child = child.nextSibling;
    }
    return children;
};

Spry.Widget.TabbedPanels.prototype.addClassName = function(ele, className)
{
    if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) != -1))
        return;
    ele.className += (ele.className ? " " : "") + className;
};

Spry.Widget.TabbedPanels.prototype.removeClassName = function(ele, className)
{
    if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) == -1))
        return;
    ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), "");
};

Spry.Widget.TabbedPanels.setOptions = function(obj, optionsObj, ignoreUndefinedProps)
{
    if (!optionsObj)
        return;
    for (var optionName in optionsObj)
    {
        if (ignoreUndefinedProps && optionsObj[optionName] == undefined)
            continue;
        obj[optionName] = optionsObj[optionName];
    }
};

Spry.Widget.TabbedPanels.prototype.getTabGroup = function()
{
    if (this.element)
    {
        var children = this.getElementChildren(this.element);
        if (children.length)
            return children[1];
    }
    return null;
};

Spry.Widget.TabbedPanels.prototype.getTabs = function()
{
    var tabs = [];
    var tg = this.getTabGroup();
    if (tg)
        tabs = this.getElementChildren(tg);
    return tabs;
};

Spry.Widget.TabbedPanels.prototype.getContentPanelGroup = function()
{
    if (this.element)
    {
        var children = this.getElementChildren(this.element);
        if (children.length > 1)
            return children[0];
    }
    return null;
};

Spry.Widget.TabbedPanels.prototype.getContentPanels = function()
{
    var panels = [];
    var pg = this.getContentPanelGroup();
    if (pg)
        panels = this.getElementChildren(pg);
    return panels;
};

Spry.Widget.TabbedPanels.prototype.getIndex = function(ele, arr)
{
    ele = this.getElement(ele);
    if (ele && arr && arr.length)
    {
        for (var i = 0; i < arr.length; i++)
        {
            if (ele == arr[i])
                return i;
        }
    }
    return -1;
};

Spry.Widget.TabbedPanels.prototype.getTabIndex = function(ele)
{
    var i = this.getIndex(ele, this.getTabs());
    if (i < 0)
        i = this.getIndex(ele, this.getContentPanels());
    return i;
};

Spry.Widget.TabbedPanels.prototype.getCurrentTabIndex = function()
{
    return this.currentTabIndex;
};

Spry.Widget.TabbedPanels.prototype.getTabbedPanelCount = function(ele)
{
    return Math.min(this.getTabs().length, this.getContentPanels().length);
};

Spry.Widget.TabbedPanels.addEventListener = function(element, eventType, handler, capture)
{
    try
    {
        if (element.addEventListener)
            element.addEventListener(eventType, handler, capture);
        else if (element.attachEvent)
            element.attachEvent("on" + eventType, handler);
    }
    catch (e) {}
};

Spry.Widget.TabbedPanels.prototype.cancelEvent = function(e)
{
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    if (e.stopPropagation) e.stopPropagation();
    else e.cancelBubble = true;

    return false;
};

Spry.Widget.TabbedPanels.prototype.onTabClick = function(e, tab)
{
    this.showPanel(tab);
    return this.cancelEvent(e);
};

Spry.Widget.TabbedPanels.prototype.onTabMouseOver = function(e, tab)
{
    this.addClassName(tab, this.tabHoverClass);
    return false;
};

Spry.Widget.TabbedPanels.prototype.onTabMouseOut = function(e, tab)
{
    this.removeClassName(tab, this.tabHoverClass);
    return false;
};

Spry.Widget.TabbedPanels.prototype.onTabFocus = function(e, tab)
{
    this.hasFocus = true;
    this.addClassName(tab, this.tabFocusedClass);
    return false;
};

Spry.Widget.TabbedPanels.prototype.onTabBlur = function(e, tab)
{
    this.hasFocus = false;
    this.removeClassName(tab, this.tabFocusedClass);
    return false;
};

Spry.Widget.TabbedPanels.KEY_UP = 38;
Spry.Widget.TabbedPanels.KEY_DOWN = 40;
Spry.Widget.TabbedPanels.KEY_LEFT = 37;
Spry.Widget.TabbedPanels.KEY_RIGHT = 39;



Spry.Widget.TabbedPanels.prototype.onTabKeyDown = function(e, tab)
{
    var key = e.keyCode;
    if (!this.hasFocus || (key != this.previousPanelKeyCode && key != this.nextPanelKeyCode))
        return true;

    var tabs = this.getTabs();
    for (var i =0; i < tabs.length; i++)
        if (tabs[i] == tab)
        {
            var el = false;
            if (key == this.previousPanelKeyCode && i > 0)
                el = tabs[i-1];
            else if (key == this.nextPanelKeyCode && i < tabs.length-1)
                el = tabs[i+1];

            if (el)
            {
                this.showPanel(el);
                el.focus();
                break;
            }
        }

    return this.cancelEvent(e);
};

Spry.Widget.TabbedPanels.prototype.preorderTraversal = function(root, func)
{
    var stopTraversal = false;
    if (root)
    {
        stopTraversal = func(root);
        if (root.hasChildNodes())
        {
            var child = root.firstChild;
            while (!stopTraversal && child)
            {
                stopTraversal = this.preorderTraversal(child, func);
                try { child = child.nextSibling; } catch (e) { child = null; }
            }
        }
    }
    return stopTraversal;
};

Spry.Widget.TabbedPanels.prototype.addPanelEventListeners = function(tab, panel)
{
    var self = this;
    Spry.Widget.TabbedPanels.addEventListener(tab, "click", function(e) { return self.onTabClick(e, tab); }, false);
    Spry.Widget.TabbedPanels.addEventListener(tab, "mouseover", function(e) { return self.onTabMouseOver(e, tab); }, false);
    Spry.Widget.TabbedPanels.addEventListener(tab, "mouseout", function(e) { return self.onTabMouseOut(e, tab); }, false);

    if (this.enableKeyboardNavigation)
    {
        // XXX: IE doesn't allow the setting of tabindex dynamically. This means we can't
        // rely on adding the tabindex attribute if it is missing to enable keyboard navigation
        // by default.

        // Find the first element within the tab container that has a tabindex or the first
        // anchor tag.

        var tabIndexEle = null;
        var tabAnchorEle = null;

        this.preorderTraversal(tab, function(node) {
            if (node.nodeType == 1 /* NODE.ELEMENT_NODE */)
            {
                var tabIndexAttr = tab.attributes.getNamedItem("tabindex");
                if (tabIndexAttr)
                {
                    tabIndexEle = node;
                    return true;
                }
                if (!tabAnchorEle && node.nodeName.toLowerCase() == "a")
                    tabAnchorEle = node;
            }
            return false;
        });

        if (tabIndexEle)
            this.focusElement = tabIndexEle;
        else if (tabAnchorEle)
            this.focusElement = tabAnchorEle;

        if (this.focusElement)
        {
            Spry.Widget.TabbedPanels.addEventListener(this.focusElement, "focus", function(e) { return self.onTabFocus(e, tab); }, false);
            Spry.Widget.TabbedPanels.addEventListener(this.focusElement, "blur", function(e) { return self.onTabBlur(e, tab); }, false);
            Spry.Widget.TabbedPanels.addEventListener(this.focusElement, "keydown", function(e) { return self.onTabKeyDown(e, tab); }, false);
        }
    }
};

Spry.Widget.TabbedPanels.prototype.showPanel = function(elementOrIndex)
{
    var tpIndex = -1;

    if (typeof elementOrIndex == "number")
        tpIndex = elementOrIndex;
    else // Must be the element for the tab or content panel.
        tpIndex = this.getTabIndex(elementOrIndex);

    if (!tpIndex < 0 || tpIndex >= this.getTabbedPanelCount())
        return;

    var tabs = this.getTabs();
    var panels = this.getContentPanels();

    var numTabbedPanels = Math.max(tabs.length, panels.length);

    for (var i = 0; i < numTabbedPanels; i++)
    {
        if (i != tpIndex)
        {
            if (tabs[i])
                this.removeClassName(tabs[i], this.tabSelectedClass);
            if (panels[i])
            {
                this.removeClassName(panels[i], this.panelVisibleClass);
                panels[i].style.display = "none";
            }
        }
    }

    this.addClassName(tabs[tpIndex], this.tabSelectedClass);
    this.addClassName(panels[tpIndex], this.panelVisibleClass);
    panels[tpIndex].style.display = "block";

    this.currentTabIndex = tpIndex;
};

Spry.Widget.TabbedPanels.prototype.attachBehaviors = function(element)
{
    var tabs = this.getTabs();
    var panels = this.getContentPanels();
    var panelCount = this.getTabbedPanelCount();

    for (var i = 0; i < panelCount; i++)
        this.addPanelEventListeners(tabs[i], panels[i]);

    this.showPanel(this.defaultTab);
};

我认为如果我能找出js中绕过我插入的新元素的位置,它可以工作。非常感谢。

2 个答案:

答案 0 :(得分:0)

  1. 你应该能够实现样式,比如改变一些颜色而不需要求助于额外的div。只需将一个类添加到顶部div并相应地更改您的CSS
  2. 如果您目前使用Spry.Widget.TabbedPanels('TabbedPanels')进行初始化,则将其更改为Spry.Widget.TabbedPanels('TabbedPanels1')应该可以解决问题..(如果我理解您的问题并正确编辑

答案 1 :(得分:0)

一个简单的解决方案是在每个TabbedPanelsContent元素上添加其他样式。您可以在每个标签中添加相同的子项<div>以进行样式设置。对于另一个解决方案,我还没有对此进行过测试,但是如下所示的更改可能会起作用:

Spry.Widget.TabbedPanels.prototype.getContentPanelGroup = function()
{
    if (this.element)
    {
        var children = this.getElementChildren(this.element);
        if (children.length > 1)
        {
            var subchildren = this.getElementChildren(children[0]);
            return subchildren[0];
        }
    }
    return null;
};