【问题标题】:Adding a class transversely with JQuery based on click event基于点击事件的jQuery横向添加类
【发布时间】:2016-01-08 16:05:51
【问题描述】:

背景

我正在构建一个通知下拉菜单,用于显示通知何时已读或未读。用户可以通过单击图标将通知标记为“已读”,从而将其变为复选标记和工具提示,该选项更改为使其未读。因此,如果未读,则图标为黄色,工具提示显示“标记为已读”。如果用户单击它以使其已读,则图标将切换为复选标记,变为绿色,并且工具提示会更改文本以将其标记为未读。所有这些都正常工作,但是,li 左侧还有另一个图标,当用户单击我上面解释的图标时,我想将其切换为背景绿色。

我尝试了什么?

我尝试使用.parent().siblings().find() 和其他方法,因为我几乎可以肯定它们将是我的解决方案,但不幸的是,我要么得到了所有的切换,要么没有全部,或者正确的图标停止工作,等等。我显然没有正确构建我的函数参数。

我在中间的 li 上硬编码了 bg-success 类,以向您展示我想要实现的目标。

所以,如果有人可以在单击它自己的li 中的“已读/未读”图标时通过添加bg-success 类来帮助我将那个doggone 左图标的背景变为绿色,我将不胜感激。

这是我的CODEPEN

这也是我的代码:

HTML

<div class="container">
    <header>
        <ul class="nav navbar-nav navbar-right">
            <li class="dropdown open">
                <a href="javascript:;" data-toggle="dropdown" class="dropdown-toggle has-notify" data-click="toggle-notify">
                    <i class="fa fa-bell"></i>
                </a>
                <ul class="dropdown-menu dropdown-notification pull-right">
                    <li class="dropdown-header">Notifications (5)</li>
                    <li class="notification-item">
                        <a href="javascript:;">
                            <div class="media"><i class="fa fa-exclamation-triangle"></i></div>
                            <div class="message"><p class="desc">Server down on 1/24/2016.</p></div>
                            <div class="option" data-toggle="tooltip" data-title="Mark as Read" data-click="set-message-status" data-status="unread" data-container="body"><i class="fa fa-circle-o"></i></div>
                        </a>
                    </li>
                    <li class="notification-item">
                        <a href="javascript:;">
                            <div class="media bg-success"><i class="fa fa-thumb-tack"></i></div>
                            <div class="message"><p class="desc">Approve documents in outbox.</p></div>
                            <div class="option read" data-toggle="tooltip" data-title="Mark as Unread" data-click="set-message-status" data-status="read" data-container="body"><i class="fa fa-circle-o"></i></div>
                        </a>
                    </li>
                    <li class="notification-item">
                        <a href="javascript:;">
                            <div class="media"><i class="fa fa-calendar-plus-o"></i></div>
                            <div class="message"><p class="desc">New event posted.</p></div>
                            <div class="option" data-toggle="tooltip" data-title="Mark as Read" data-click="set-message-status" data-status="read" data-container="body"><i class="fa fa-circle-o"></i></div>
                        </a>
                    </li>
                </ul>
            </li>
        </ul>
    </header>
</div>

CSS

.navbar-nav .open .dropdown-menu {
    position: absolute;
    background: #000;
    border: 1px solid;
    -webkit-box-shadow: 0 3px 8px rgba(0,0,0,0.25);
    box-shadow: 0 3px 8px rgba(0,0,0,0.25);
}
.navbar .dropdown-menu.pull-right {
    right: 0;
    left: auto;
}
.navbar .dropdown-menu {
    max-width: 360px;
    left: 0;
}

.navbar-nav .open .dropdown-menu .dropdown-header {
    padding: 5px 20px 8px;
    border-bottom: 1px solid rgba(248,151,29,0.77);
    color: rgba(248,151,29,0.77);
    font-size: 15px;
    font-weight: 100;
    letter-spacing: 1px;
    text-transform: uppercase;
    font-family: "ABeeZee",sans-serif;
}
.dropdown-menu>li.dropdown-header {
    padding: 5px 20px 8px;
    border-bottom: 1px solid #bbb;
}

.dropdown-notification>li.notification-item {
    position: relative;
}

.navbar-nav .open .dropdown-notification>li.notification-item>a {
    padding: 15px 20px;
}
.dropdown-notification>li.notification-item a {
    padding: 15px 20px;
}
.dropdown-menu>li>a {
    font-size: 12px;
    padding: 5px 20px;
    color: #bbb;
}

.dropdown-menu>li>a:hover, .dropdown-menu>li>a:focus {
    background: #101113;
    color: #bbb;
}

.dropdown-notification>li.notification-item a:before, 
.dropdown-notification>li.notification-item a:after {
    content: '';
    display: table;
    clear: both;
}

.dropdown-notification>li.notification-item .media {
    float: left;
    width: 40px;
    height: 40px;
    overflow: hidden;
    text-align: center;
    line-height: 40px;
    -webkit-border-radius: 50%;
    -moz-border-radius: 50%;
    -ms-border-radius: 50%;
    border-radius: 50%;
    background: #ccc;
    color: #000;
}

.dropdown-notification>li.notification-item .media i {
    font-size: 15px;
}

.dropdown-notification>li.notification-item .media+.message {
    margin-left: 50px;
}
.dropdown-notification>li.notification-item .message {
    padding-right: 20px;
}

.dropdown-notification>li.notification-item .desc {
    font-size: 12px;
    font-weight: 300;
    margin-bottom: 3px;
    color: #8f8f8f;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
p {
    color: #bbb;
}
.dropdown-notification>li.notification-item .option {
    position: absolute;
    right: 10px;
    top: 10px;
    padding: 5px 10px;
    font-size: 12px;
}
.dropdown-notification>li.notification-item .option .fa:before {
    color: #F8971D;
}

.dropdown-notification>li.notification-item .option.read .fa:before {
    content: '\f058';
    color: #47a877;
}

.bg-success {
    background: #47a877 !important;
}

JQUERY

$('[data-click="set-message-status"]').on('click', function (e) {
        e.stopPropagation();
        e.preventDefault();

        var status = $(this).attr('data-status');
        var tooltipText = 'Mark as Read';
        if (status == 'read') {
            $(this).removeClass('read');
            //$('.notification-item').find('.media').removeClass('bg-success');
            $(this).attr('data-status', 'unread');
            //$('.notification-item').find('.media').attr('data-status', 'unread');
        } else {
            $(this).addClass('read');
            //$('.notification-item').find('.media').addClass('bg-success');
            $(this).attr('data-status', 'read');
            //$('.notification-item').find('.media').attr('data-status', 'read');
            tooltipText = 'Mark as Unread';
        }
        $(this).tooltip('hide').attr('data-original-title', tooltipText).tooltip('fixTitle');
    });

谢谢!

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    使用$(this).parents('a').find('.media') 定位单击图标“已读/未读”的media 类,并使用addClass()/removeClass() 方法添加/删除类:

    $(this).parents('a').find('.media').addClass('bg-success'); //add class
    //And 
    $(this).parents('a').find('.media').removeClass('bg-success'); //remove class
    

    希望这会有所帮助。


    片段

    $('[data-click="set-message-status"]').on('click', function (e) {
        e.stopPropagation();
        e.preventDefault();
    
        var status = $(this).attr('data-status');
        var tooltipText = 'Mark as Read';
        if (status == 'read') {
            $(this).removeClass('read');
            //$('.notification-item').find('.media').removeClass('bg-success');
            $(this).attr('data-status', 'unread');
            //$('.notification-item').find('.media').attr('data-status', 'unread');
            $(this).parents('a').find('.media').removeClass('bg-success');
        } else {
            $(this).addClass('read');
            //$('.notification-item').find('.media').addClass('bg-success');
            $(this).attr('data-status', 'read');
            //$('.notification-item').find('.media').attr('data-status', 'read');
            
            $(this).parents('a').find('.media').addClass('bg-success');
            
            tooltipText = 'Mark as Unread';
        }
        $(this).tooltip('hide').attr('data-original-title', tooltipText).tooltip('fixTitle');
    });
    	.navbar-nav .open .dropdown-menu {
    		position: absolute;
    		background: #000;
    		border: 1px solid;
    		-webkit-box-shadow: 0 3px 8px rgba(0,0,0,0.25);
    		box-shadow: 0 3px 8px rgba(0,0,0,0.25);
    	}
    	.navbar .dropdown-menu.pull-right {
    		right: 0;
    		left: auto;
    	}
    	.navbar .dropdown-menu {
    		max-width: 360px;
    		left: 0;
    	}
    
    	.navbar-nav .open .dropdown-menu .dropdown-header {
    		padding: 5px 20px 8px;
    		border-bottom: 1px solid rgba(248,151,29,0.77);
    		color: rgba(248,151,29,0.77);
    		font-size: 15px;
    		font-weight: 100;
    		letter-spacing: 1px;
    		text-transform: uppercase;
    		font-family: "ABeeZee",sans-serif;
    	}
    	.dropdown-menu>li.dropdown-header {
    		padding: 5px 20px 8px;
    		border-bottom: 1px solid #bbb;
    	}
    
    	.dropdown-notification>li.notification-item {
    		position: relative;
    	}
    
    	.navbar-nav .open .dropdown-notification>li.notification-item>a {
    		padding: 15px 20px;
    	}
    	.dropdown-notification>li.notification-item a {
    		padding: 15px 20px;
    	}
    	.dropdown-menu>li>a {
    		font-size: 12px;
    		padding: 5px 20px;
    		color: #bbb;
    	}
    
    	.dropdown-menu>li>a:hover, .dropdown-menu>li>a:focus {
    		background: #101113;
    		color: #bbb;
    	}
    
    	.dropdown-notification>li.notification-item a:before, 
    	.dropdown-notification>li.notification-item a:after {
    		content: '';
    		display: table;
    		clear: both;
    	}
    
    	.dropdown-notification>li.notification-item .media {
    		float: left;
    		width: 40px;
    		height: 40px;
    		overflow: hidden;
    		text-align: center;
    		line-height: 40px;
    		-webkit-border-radius: 50%;
    		-moz-border-radius: 50%;
    		-ms-border-radius: 50%;
    		border-radius: 50%;
    		background: #ccc;
    		color: #000;
    	}
    
    	.dropdown-notification>li.notification-item .media i {
    		font-size: 15px;
    	}
    
    	.dropdown-notification>li.notification-item .media+.message {
    		margin-left: 50px;
    	}
    	.dropdown-notification>li.notification-item .message {
    		padding-right: 20px;
    	}
    
    	.dropdown-notification>li.notification-item .desc {
    		font-size: 12px;
    		font-weight: 300;
    		margin-bottom: 3px;
    		color: #8f8f8f;
    		white-space: nowrap;
    		overflow: hidden;
    		text-overflow: ellipsis;
    	}
    	p {
    		color: #bbb;
    	}
    	.dropdown-notification>li.notification-item .option {
    		position: absolute;
    		right: 10px;
    		top: 10px;
    		padding: 5px 10px;
    		font-size: 12px;
    	}
    	.dropdown-notification>li.notification-item .option .fa:before {
    		color: #F8971D;
    	}
    
    	.dropdown-notification>li.notification-item .option.read .fa:before {
    		content: '\f058';
    		color: #47a877;
    	}
    
    	.bg-success {
    		background: #47a877 !important;
    	}
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet"/>
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
    
    <div class="container">
      <header>
        <ul class="nav navbar-nav navbar-right">
          <li class="dropdown open">
            <a href="javascript:;" data-toggle="dropdown" class="dropdown-toggle has-notify" data-click="toggle-notify">
              <i class="fa fa-bell"></i>
            </a>
            <ul class="dropdown-menu dropdown-notification pull-right">
              <li class="dropdown-header">Notifications (5)</li>
              <li class="notification-item">
                <a href="javascript:;">
                  <div class="media"><i class="fa fa-exclamation-triangle"></i></div>
                  <div class="message"><p class="desc">Server down on 1/24/2016.</p></div>
                  <div class="option" data-toggle="tooltip" data-title="Mark as Read" data-click="set-message-status" data-status="unread" data-container="body"><i class="fa fa-circle-o"></i></div>
                </a>
              </li>
              <li class="notification-item">
                <a href="javascript:;">
                  <div class="media bg-success"><i class="fa fa-thumb-tack"></i></div>
                  <div class="message"><p class="desc">Approve documents in outbox.</p></div>
                  <div class="option read" data-toggle="tooltip" data-title="Mark as Unread" data-click="set-message-status" data-status="read" data-container="body"><i class="fa fa-circle-o"></i></div>
                </a>
              </li>
              <li class="notification-item">
                <a href="javascript:;">
                  <div class="media"><i class="fa fa-calendar-plus-o"></i></div>
                  <div class="message"><p class="desc">New event posted.</p></div>
                  <div class="option" data-toggle="tooltip" data-title="Mark as Read" data-click="set-message-status" data-status="read" data-container="body"><i class="fa fa-circle-o"></i></div>
                </a>
              </li>
            </ul>
          </li>
        </ul>
      </header>
    </div>

    【讨论】:

      【解决方案2】:

      使用.closest() method,根据单击的元素选择最接近的.notification-item 祖先。应该是$(this).closest('.notification-item').find('.media')

      您也可以在.addClass()/.removeClass() 方法之后链接attr() 方法:

      Updated Example

      if (status === 'read') {
          $(this).removeClass('read').attr('data-status', 'unread');
          $(this).closest('.notification-item').find('.media').removeClass('bg-success').attr('data-status', 'unread');
      } else {
          $(this).addClass('read').attr('data-status', 'read');
          $(this).closest('.notification-item').find('.media').addClass('bg-success').attr('data-status', 'read');
          tooltipText = 'Mark as Unread';
      }
      

      作为旁注,您还可以使用$(this).prevAll('.media').first() 来选择之前的.media 元素:

      Updated Example

      if (status === 'read') {
          $(this).removeClass('read').attr('data-status', 'unread');
          $(this).prevAll('.media').first().removeClass('bg-success').attr('data-status', 'unread');
      } else {
          $(this).addClass('read').attr('data-status', 'read');
          $(this).prevAll('.media').first().addClass('bg-success').attr('data-status', 'read');
          tooltipText = 'Mark as Unread';
      }
      

      您还可以使用.toggleClass() 代替.addClass()/.removeClass() 来缩短逻辑。

      Updated Example

      var tooltipText = status === 'read' ? 'Mark as Unread' : 'Mark as Read';
      var newStatus = status === 'read' ? 'unread' : 'read';
      $(this).toggleClass('read', status !== 'read').attr('data-status', newStatus);
      $(this).prevAll('.media').first().toggleClass('bg-success', status !== 'read').attr('data-status', newStatus);
      

      【讨论】:

      • 因为您首先回复。我会检查你的。所有的答案都很好。谢谢!
      • 我有一个问题。而且我无法在codepen中复制它,但似乎点击工作我必须点击两次。一个给 LI 焦点,下一个点击事件。以前没有这样做。有什么事会响吗?
      • 啊,好吧,如果你刷新 codepen。你会看到双击发生。至少单击一次后,您可以来回单击任何 LI,单击即可完成。但是在干净的浏览器上,它不会
      • @LOTUSMS 看起来这种情况正在发生,因为其中一个元素的属性为data-status="read"。初始 HTML 需要考虑是否已经阅读了相应的通知。这是一个更新的示例 - codepen.io/anon/pen/QyvqKg - 在单击元素之前,我还初始化了所有工具提示。
      • 我明白了。是的。 codepen 工作正常,但我的工作区不是。但没关系。这不是你的代码。我必须深入挖掘并找出可能导致这种情况的其他原因。再次感谢!
      【解决方案3】:

      如果你的 html 结构不太可能改变,那么,鉴于此:

      <li class="notification-item">
          <a href="javascript:;">
              <div class="media"><i class="fa fa-exclamation-triangle"></i></div>
              <div class="message"><p class="desc">Server down on 1/24/2016.</p></div>
              <div class="option" data-toggle="tooltip" data-title="Mark as Read" data-click="set-message-status" data-status="unread" data-container="body"><i class="fa fa-circle-o"></i></div>
          </a>
      </li>
      

      $('[data-click="set-message-status"]').on('click', function (e) {
      

      然后$(this)div.option,所以要到达i.fa,您可以转到.media,然后转到i.fa

       var fa = $(this).siblings(".media").find("i.fa")
      

      或者,为了给您的 html 提供更多的灵活性,上到最适合的容器(li 而不是a)然后下到图标:

      var fa = $(this).closest("li.notification-item").find(".media > i.fa")
      

      您需要额外的.media &gt;,因为有两个i.fa,这将专门为您提供第一个。

      或者,您可以同时更改两者

      var fa = $(this).closest("li.notification-item").find("i.fa")
      

      【讨论】:

      • 我希望你提供了一个更新的演示。不过你的回答也不错。不幸的是,我只能选择一个答案。感谢您的帮助 +1
      【解决方案4】:

      我认为您向上导航到“a”元素,然后从那里进行查找,但是为了确保您获得正确的元素,您应该从事件目标开始,例如:

      $(this).parent().find(".media").removeClass('bg-success');
      

      在这种情况下,$(this) 指向在观察者上定义的项目,即发生点击的具有 data-click 属性的 div。

      您可以将$(this) 更改为$(e.target),将“.parent()”更改为“.closest('a')”或“.closest('li')

      【讨论】:

      • 感谢您的回答和时间!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-17
      • 2023-03-17
      • 2017-03-12
      • 1970-01-01
      • 1970-01-01
      • 2015-03-18
      • 2016-09-15
      相关资源
      最近更新 更多