【问题标题】:Target ID instead of <li>目标 ID 而不是 <li>
【发布时间】:2015-02-13 23:19:46
【问题描述】:

我正在研究 JavaScript 手风琴,不知何故我以手风琴 ID 为目标,而不是它的 &lt;li&gt;

基本上,如果有两个这样的标记,我想在下面生成两个手风琴

<div id="st-accordion" class="st-accordion">
                <ul>

                    <li>
                        <a href="#">{tag_name_nolink}</a>
                        <div class="st-content">
                           {tag_Partners Module tag}
                        </div>
                    </li>


                </ul>
            </div>

如果有两个 &lt;div id="st-accordion" class="st-accordion"&gt;.......&lt;/div&gt;,那么它应该显示两个工作手风琴,但是当 div 中有两个 &lt;li&gt; 时,它正在制作两个工作手风琴。

这里是 JS 和 Fiddles

WORKING | NOT WORKING

(function( window, $, undefined ) {

var $event = $.event, resizeTimeout;

$event.special.smartresize  = {
    setup: function() {
        $(this).bind( "resize", $event.special.smartresize.handler );
    },
    teardown: function() {
        $(this).unbind( "resize", $event.special.smartresize.handler );
    },
    handler: function( event, execAsap ) {
        // Save the context
        var context = this,
            args    = arguments;

        // set correct event type
        event.type = "smartresize";

        if ( resizeTimeout ) { clearTimeout( resizeTimeout ); }
        resizeTimeout = setTimeout(function() {
            jQuery.event.handle.apply( context, args );
        }, execAsap === "execAsap"? 0 : 100 );
    }
};

$.fn.smartresize            = function( fn ) {
    return fn ? this.bind( "smartresize", fn ) : this.trigger( "smartresize", ["execAsap"] );
};

$.Accordion                 = function( options, element ) {

    this.$el            = $( element );
    // list items
    this.$items         = this.$el.children('ul').children('li');
    // total number of items
    this.itemsCount     = this.$items.length;

    // initialize accordion
    this._init( options );

};

$.Accordion.defaults        = {
    // index of opened item. -1 means all are closed by default.
    open            : -1,
    // if set to true, only one item can be opened. Once one item is opened, any other that is opened will be closed first
    oneOpenedItem   : false,
    // speed of the open / close item animation
    speed           : 600,
    // easing of the open / close item animation
    easing          : 'easeInOutExpo',
    // speed of the scroll to action animation
    scrollSpeed     : 900,
    // easing of the scroll to action animation
    scrollEasing    : 'easeInOutExpo'
};

$.Accordion.prototype       = {
    _init               : function( options ) {

        this.options        = $.extend( true, {}, $.Accordion.defaults, options );

        // validate options
        this._validate();

        // current is the index of the opened item
        this.current        = this.options.open;

        // hide the contents so we can fade it in afterwards
        this.$items.find('div.st-content').hide();

        // save original height and top of each item    
        this._saveDimValues();

        // if we want a default opened item...
        if( this.current != -1 )
            this._toggleItem( this.$items.eq( this.current ) );

        // initialize the events
        this._initEvents();

    },
    _saveDimValues      : function() {

        this.$items.each( function() {

            var $item       = $(this);

            $item.data({
                originalHeight  : $item.find('a:first').height(),
                offsetTop       : $item.offset().top
            });

        });

    },
    // validate options
    _validate           : function() {

        // open must be between -1 and total number of items, otherwise we set it to -1
        if( this.options.open < -1 || this.options.open > this.itemsCount - 1 )
            this.options.open = -1;

    },
    _initEvents         : function() {

        var instance    = this;

        // open / close item
        this.$items.find('a:first').bind('click.accordion', function( event ) {

            var $item           = $(this).parent();

            // close any opened item if oneOpenedItem is true
            if( instance.options.oneOpenedItem && instance._isOpened() && instance.current!== $item.index() ) {

                instance._toggleItem( instance.$items.eq( instance.current ) );

            }

            // open / close item
            instance._toggleItem( $item );

            return false;

        });

        $(window).bind('smartresize.accordion', function( event ) {

            // reset orinal item values
            instance._saveDimValues();

            // reset the content's height of any item that is currently opened
            instance.$el.find('li.st-open').each( function() {

                var $this   = $(this);
                $this.css( 'height', $this.data( 'originalHeight' ) + $this.find('div.st-content').outerHeight( true ) );

            });

            // scroll to current
            if( instance._isOpened() )
            instance._scroll();

        });

    },
    // checks if there is any opened item
    _isOpened           : function() {

        return ( this.$el.find('li.st-open').length > 0 );

    },
    // open / close item
    _toggleItem         : function( $item ) {

        var $content = $item.find('div.st-content');

        ( $item.hasClass( 'st-open' ) ) 

            ? ( this.current = -1, $content.stop(true, true).fadeOut( this.options.speed ), $item.removeClass( 'st-open' ).stop().animate({
                height  : $item.data( 'originalHeight' )
            }, this.options.speed, this.options.easing ) )

            : ( this.current = $item.index(), $content.stop(true, true).fadeIn( this.options.speed ), $item.addClass( 'st-open' ).stop().animate({
                height  : $item.data( 'originalHeight' ) + $content.outerHeight( true )
            }, this.options.speed, this.options.easing ), this._scroll( this ) )

    },
    // scrolls to current item or last opened item if current is -1
    _scroll             : function( instance ) {

        var instance    = instance || this, current;

        ( instance.current !== -1 ) ? current = instance.current : current = instance.$el.find('li.st-open:last').index();

        $('html, body').stop().animate({
            scrollTop   : ( instance.options.oneOpenedItem ) ? instance.$items.eq( current ).data( 'offsetTop' ) : instance.$items.eq( current ).offset().top
        }, instance.options.scrollSpeed, instance.options.scrollEasing );

    }
};

var logError                = function( message ) {

    if ( this.console ) {

        console.error( message );

    }

};

$.fn.accordion              = function( options ) {

    if ( typeof options === 'string' ) {

        var args = Array.prototype.slice.call( arguments, 1 );

        this.each(function() {

            var instance = $.data( this, 'accordion' );

            if ( !instance ) {
                logError( "cannot call methods on accordion prior to initialization; " +
                "attempted to call method '" + options + "'" );
                return;
            }

            if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) {
                logError( "no such method '" + options + "' for accordion instance" );
                return;
            }

            instance[ options ].apply( instance, args );

        });

    } 
    else {

        this.each(function() {
            var instance = $.data( this, 'accordion' );
            if ( !instance ) {
                $.data( this, 'accordion', new $.Accordion( options, this ) );
            }
        });

    }

    return this;

};

})( window, jQuery );

有人帮忙吗?

【问题讨论】:

  • “id”属性的值在一个页面上必须是唯一的。
  • 如果有两个&lt;div id="st-accordion"&gt;有问题:)
  • ID 必须在文档上下文中是唯一的。您有无效的 HTML 标记,不要指望它可以工作
  • 您的问题是如何使用相同的 ID 两次,还是如何定位类?

标签: javascript jquery html css jquery-ui


【解决方案1】:

你有两个具有相同 ID 的元素,并且 ID 必须是唯一的,所以你所要做的就是使用 class 而不是 ID:

$(function() {

                $('.st-accordion').accordion({
                    oneOpenedItem   : true
                });

            });

这里是jsFiddle

【讨论】:

  • 是的,我知道,但是我想要相同的 ID 来生成两个不同的手风琴!
  • @YOU 你可以使用属性选择器,但是不要!!! jsfiddle.net/yhed6kn3/4 问题是:为什么要多次使用同一个 ID?因为无论如何,绝对没有理由这样做!
  • @YOU 你的意思是一个容器有两个不同的手风琴?
  • @YOU 不,您不想使用相同的 ID,因为 w3c specification
  • 在这种情况下我可以多次定位class吗?
猜你喜欢
  • 1970-01-01
  • 2013-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-18
  • 1970-01-01
  • 2011-06-17
  • 1970-01-01
相关资源
最近更新 更多