0

我有一些具有标题属性的可折叠面板 div。当我的 jQuery 打开面板时,我希望更改标题属性,并且我想通过当前打开的面板的类来指定要更改的 div。即 this.div.class 将标题更改为“随便”。

为了使代码变得愚蠢,您可以轻松地遵循:

<div class="panelContainer">
    <div class="service">
      <div class="serviceBrief" title="Click to Read More">
        <p>Some Stuff for closed panel</p>
      </div> <!-- end serviceBrief -->
      <div class="serviceDescContainer">
        <div class="serviceDesc">
          <p>some more stuff that shows when panel is open</p>
        </div><!-- end serviceDesc -->
      </div><!-- end serviceDescContainer -->
     </div><!-- end service -->
   <div class="service">
     <div class="serviceBrief" title="Click to Read More">
       <p>Some Stuff for closed panel</p>
     </div> <!-- end serviceBrief -->
     <div class="serviceDescContainer">
       <div class="serviceDesc">
         <p>some more stuff that shows when panel is open</p>
       </div><!-- end serviceDesc -->
     </div><!-- end serviceDesc Container -->
  </div><!-- end service -->
</div> <!-- end panelContainer -->

我了解如何使用 ID 执行此操作

            $('#sampleID').attr('title', 'Click to Read More');

但我想这样做引用 div 类来更改标题属性,所以当面板打开时,标题=“点击阅读少”

我认为这会起作用:

$('.serviceBrief').attr('title', 'Click to Read Less');

确实如此,但显然它会更改 title 属性的所有实例,而不仅仅是打开的实例。我知道我错过了在 jQuery 中将其设为“this”类型的命令,但我所有的各种尝试都失败了,我终生无法在任何地方找到参考。

有人可以指出我正确的方向吗?谢谢!

$(document).ready(function() {

$('.serviceBrief').each(function(){
    $(this).append('<div class="panelOpenArrow"></div><div class="panelClosedArrow"></div>');
});

$('.serviceBrief').click(function(){
    if ($(this).parent().is('.open')) {
        $(this).closest('.service').find('.serviceDescContainer').animate({'height':'0'},500);
        $(this).closest('.service').find('.panelOpenArrow').fadeOut(500);
        $(this).closest('.service').find('.panelClosedArrow').animate({'height': '25px'});
        $(this).closest('.service').removeClass('open');
    }else{
        var newHeight = $(this).closest('.service').find('.serviceDesc').height() + 'px';
        $(this).closest('.service').find('.serviceDescContainer').animate({'height':newHeight},500);
        $(this).closest('.service').find('.panelOpenArrow').fadeIn(500);
        $(this).closest('.service').find('.panelClosedArrow').animate({'height':'0'});
        $(this).closest('.service').addClass('open');
    }
});

});
4

4 回答 4

1

为什么不这样做:

$('.serviceBrief').click(function(){
    if ($(this).parent().is('.open')) {
        $(this).attr('title', 'Click to Read Less');
        //rest of your code
于 2013-07-02T17:14:45.860 回答
1

你在钱上是对的。只需$(this)在单击事件中引用即可将属性应用于单击的元素,而不是所有.serviceBrief元素:

$('.serviceBrief').click(function(){
    if ($(this).parent().is('.open')) {
        $(this).attr( "title", "Click to Read Less");
     $(this).closest('.service').find('.serviceDescContainer').animate({'height':'0'},500);
        $(this).closest('.service').find('.panelOpenArrow').fadeOut(500);
        $(this).closest('.service').find('.panelClosedArrow').animate({'height': '25px'});
        $(this).closest('.service').removeClass('open');
    }else{
        var newHeight = $(this).closest('.service').find('.serviceDesc').height() + 'px';
        $(this).attr( "title", "Click to Read More");
        $(this).closest('.service').find('.serviceDescContainer').animate({'height':newHeight},500);
        $(this).closest('.service').find('.panelOpenArrow').fadeIn(500);
        $(this).closest('.service').find('.panelClosedArrow').animate({'height':'0'});
        $(this).closest('.service').addClass('open');
    }
});
于 2013-07-02T17:15:06.033 回答
1

您可以向处理函数传递一个e包含触发它的事件的参数。e.currentTarget属性将包含处理事件的实际元素,因此您可以将其属性更改为仅影响当前元素。

$('.serviceBrief').click(function(e){
    var objThis = $(e.currentTarget);
    var objService = objThis.parent();
    if (objService.is('.open')) {
        objService.find('.serviceDescContainer').animate({'height':'0'},500);
        objService.find('.panelOpenArrow').fadeOut(500);
        objService.find('.panelClosedArrow').animate({'height': '25px'});
        objService.removeClass('open');
        objThis.attr("title", "Click to Read More");
    }else{
        var newHeight = objService.find('.serviceDesc').height() + 'px';
        objService.find('.serviceDescContainer').animate({'height':newHeight},500);
        objService.find('.panelOpenArrow').fadeIn(500);
        objService.find('.panelClosedArrow').animate({'height':'0'});
        objService.addClass('open');
        objThis.attr("title", "Click to Read Less");
    }
});

这是一个小提琴:http: //jsfiddle.net/gtXpx/

将 DOM 查询缓存在对象中以提高性能是个好主意。

于 2013-07-02T17:20:15.930 回答
1

你可以更容易地编写这一切。我将把它缩短为“一些”,这意味着除了我将展示的内容之外还有更多内容,但希望这个细分将帮助您了解 jQuery 的真正强大之处。

例子

<script type="text/javascript">
    $(function() {  //  same as $(document).ready ... but SHORTER!
        $('.serviceBrief').each(function(i) {   //  of course i stands for the 0 based index of the elements in this object
            $(this).append( //  many different ways to (pre|ap)pend elemnts, this is my fav do to the "readability"
                $('<div />', { class: 'panelArrow panelOpenArrow' }),   //  set attributes in the {  }
                $('<div />', { class: 'panelArrow panelClosedArrow' })  //  don't forget to place comma before appending more elements
                //  keep in mind, you could continue inside here and append to what is being appended!
            )
        })  //  here I continue to "chain", no need to recall the same object
        .click(function(e) {    //  simple click event, you might also look at "delegate"ing events
            var aroOpen = $(this).children('.panelOpenArrow'),
                aroClose = $(this).children('.panelClosedArrow');
                //  i establish these variable for ease of use in next event

            //  considering the way your HTML is layed, there's really no need for all that "find"ing, it's just more code time, less action time!
            $(this).next('.serviceDescContainer').slideToggle(500, function(e) {    //  this is much the same as what you were trying to do using .animate
                if ($(this).is(':visible')) {   //  kind of like your class check, except this checks the display, opacity, and even considers height (in newer jQuery versions) for "visibility"
                    //  at this point, this first line is "unneccesary", but I left it here in case you were doing some "CSS" using that class name
                    $(this).closest('.service').addClass('open');
                    //  .stop prevents animations previously taking place, like if a user clicks this real fast
                    aroOpen.stop().fadeOut(500);
                    aroClose.stop().animate({ height: '25px' });
                }
                else {
                    $(this).closest('.service').removeClass('open');
                    aroOpen.stop().fadeIn(500);
                    aroClose.stop().animate({ height: 0 });
                }
            })
        });
    })
</script>

更多阅读

带/不带注释的示例

<script type="text/javascript">
    $(function() {
        $('.serviceBrief').each(function(i) {
            $(this).append(
                $('<div />', { class: 'panelArrow panelOpenArrow' }),
                $('<div />', { class: 'panelArrow panelClosedArrow' })
            )
        })
        .click(function(e) {
            var aroOpen = $(this).children('.panelOpenArrow'),
                aroClose = $(this).children('.panelClosedArrow');
            $(this).next('.serviceDescContainer').slideToggle(500, function(e) {
                if ($(this).is(':visible')) {
                    $(this).closest('.service').addClass('open');
                    aroOpen.stop().fadeOut(500);
                    aroClose.stop().animate({ height: '16px' });
                }
                else {
                    $(this).closest('.service').removeClass('open');
                    aroOpen.stop().fadeIn(500);
                    aroClose.stop().animate({ height: 0 });
                }
            })
        });
    })
</script>
于 2013-07-02T19:22:58.777 回答