Форум программистов, компьютерный форум, киберфорум
jQuery
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
мну довольно <(-__-)l
 Аватар для gGrn-7DA
217 / 206 / 15
Регистрация: 17.01.2010
Сообщений: 2,462

Странное поведение $.addClass

15.12.2013, 22:28. Показов 997. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
вот так все работает - анимация бекграунда в топ-меню
HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
 
<style>
html,body{
  margin:0;
  padding:0;
}
 
html{
  height: 100%;
  overflow-y: scroll;
  overflow-x: hidden;
  background: rgba(224,224,240,1);
  font-size: 14pt;
}
 
a,a:hover,a:link,a:visited{
  text-decoration: none;
  color: inherit;
}
 
.cl{clear:both;}
.cll{clear:left;}
.clr{clear:right;}
 
body{
  width: 1200px;
  overflow: hidden;
  margin: 20px auto 40px;
  box-shadow: 0px 0px 4px rgba(0,0,0,.7);
}
 
.header, .footer{
  background: rgba(32,64,192,.8);
  color: #eee;
}
.header{
}
.footer{
}
 
.header .logo{
  float: right;
  width: 240px;
  display: block;
  cursor: pointer;
  text-align: right;
  /*background: rgba(80,80,80,.4);*/
}
.header .name,
.header .desc{
  padding: 8px 16px;
}
.header .name{
  font-weight: 600;
  font-size: 18pt;
}
.header .desc{
  font-size: 12pt;
}
 
.header .top_menu{
  float: left;
  width: 960px;
  /*background: rgba(180,180,180,.2);*/
}
.header .top_menu .el{
  display: inline-block;
  margin-right: 4px;
  cursor: pointer;
}
.header .top_menu .el.current,
.header .top_menu .el.hover{
  background: rgba(80,80,80,.4);
}
 
.footer{
  padding: 8px;
  text-align: right;
}
 
.content{
  padding:64px 0;
}
</style>
 
<script type="text/javascript" src="../jquery/jquery-2.0.3.js"></script>
<script type="text/javascript" src="../jquery/jquery-ui-1.10.3.flick/js/jquery-ui-1.10.3.flick.js"></script>
 
<script type="text/javascript">
  $(function(){
    var menus = {
      main:{
        name:'Main',
        desc:'The main page'
      },
      search:{
        name:'Search',
        desc:'The search page'
      },
      map:{
        name:'Map',
        desc:'The map page'
      },
      home:{
        name:'Home',
        desc:'The home page'
      }
    };
    var menu = $('.top_menu');
    var nav = $('nav', menu);
    var desc = $('.desc', menu);
    var duration = 128;
    
    var
    el = '.el',
    elClass = 'el',
    current = '.current',
    currentEl = '.current.el',
    currentClass = 'current',
    hover = '.hover',
    hoverClass = 'hover',
    mustBeHover = '.must-be-hover',
    mustBeHoverClass = 'must-be-hover',
    mustBeUnhover = '.must-be-unhover',
    mustBeUnhoverClass = 'must-be-unhover'
    ;
    
    function updateDesc(){
      desc.text(menus[this.attr('id')].desc);
    }
    
    function addHoverClass(){
      var t = $(this);
      if(t.is(mustBeHover) && (!(t.is(current) || t.is(hover)))){
        t.toggleClass(hoverClass, duration, 'easeOutSine');
      }
      t.removeClass(mustBeHover);
    }
    function removeHoverClass(){
      var t = $(this);
      if(t.is(mustBeUnhover) && t.is(hover)){
        t.toggleClass(hoverClass, duration, 'easeOutSine');
      }
      t.removeClass(mustBeUnhoverClass);
    }
    function removeHoverClassPermanently(){
      $(this).removeClass(hoverClass);
    }
    
    nav.empty();
    $.each(menus, function(id, m){
      nav.append(
        '<div id="{id}" class="name el">{name}</div>'
        .replace(/{id}/g,id)
        .replace(/{name}/g,m.name)
      );
    });
    nav.on('click', el, function(event){
      event.preventDefault();
      
      var t = $(this);
      
      updateDesc.call(t);
      
      if(!t.is(current)){
        $(currentEl, nav).removeClass(currentClass);
        t.addClass(currentClass);
      }
    });
    
    nav.on('mouseenter', el, function(){
      var t = $(this);
      t.removeClass(mustBeUnhoverClass);
      t.addClass(mustBeHoverClass);
      
      if(!t.is(current)){
        t.promise().always(addHoverClass);
        updateDesc.call(t);
      }
    });
    nav.on('mouseout', el, function(){
      var t = $(this);
      t.removeClass(mustBeHoverClass);
      t.addClass(mustBeUnhoverClass);
      
      if(t.is(current)){
        t.promise().always(removeHoverClassPermanently);
      }
      else{
        t.promise().always(removeHoverClass);
      }
      
      var c = $(currentEl, nav);
      updateDesc.call(c);
    });
    $(el, nav).first().trigger('click');
  });
</script>
 
</head>
<body>
  <div class="container">
    <div class="header">
      <a href="./index.html" class="logo">
        <div class="name">project</div>
        <div class="desc">The project site</div>
      </a>
      
      <div class="top_menu">
        <nav></nav>
        <div class="desc"></div>
      </div>
      <div class="cl"></div>
    </div>
    <div class="content"></div>
    <div class="footer">
      <div class="copy">project &copy; 2013</div>
    </div>
  </div>
</body>
</html>
а вот так вот уже не работает
HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
 
<style>
html,body{
  margin:0;
  padding:0;
}
 
html{
  height: 100%;
  overflow-y: scroll;
  overflow-x: hidden;
  background: rgba(224,224,240,1);
  font-size: 14pt;
}
 
a,a:hover,a:link,a:visited{
  text-decoration: none;
  color: inherit;
}
 
.cl{clear:both;}
.cll{clear:left;}
.clr{clear:right;}
 
body{
  width: 1200px;
  overflow: hidden;
  margin: 20px auto 40px;
  box-shadow: 0px 0px 4px rgba(0,0,0,.7);
}
 
.header, .footer{
  background: rgba(32,64,192,.8);
  color: #eee;
}
.header{
}
.footer{
}
 
.header .logo{
  float: right;
  width: 240px;
  display: block;
  cursor: pointer;
  text-align: right;
  /*background: rgba(80,80,80,.4);*/
}
.header .name,
.header .desc{
  padding: 8px 16px;
}
.header .name{
  font-weight: 600;
  font-size: 18pt;
}
.header .desc{
  font-size: 12pt;
}
 
.header .top_menu{
  float: left;
  width: 960px;
  /*background: rgba(180,180,180,.2);*/
}
.header .top_menu .el{
  display: inline-block;
  margin-right: 4px;
  cursor: pointer;
}
.header .top_menu .el.current,
.header .top_menu .el.hover{
  background: rgba(80,80,80,.4);
}
 
.footer{
  padding: 8px;
  text-align: right;
}
 
.content{
  padding:64px 0;
}
</style>
 
<script type="text/javascript" src="../jquery/jquery-2.0.3.js"></script>
<script type="text/javascript" src="../jquery/jquery-ui-1.10.3.flick/js/jquery-ui-1.10.3.flick.js"></script>
 
<script type="text/javascript">
(function(){
      var 
      duration = 200,
     mustBeHoverClass = 'project-must-be-hover',
     mustBeUnhoverClass = 'project-must-be-unhover',
     projectHoverDefaults = $.extend({}, {
       elClass: 'el',
       currentClass: 'current',
       hoverClass: 'hover'
     });
     
     function selector(_class){
       return '.' + _class;
     }
     
     function addHoverClass(o){
       var t = $(this);
       if(t.hasClass(mustBeHoverClass) && (!(t.hasClass(o.currentClass) || t.hasClass(o.hoverClass)))){
         t.toggleClass(o.hoverClass, duration, 'easeOutSine');
       }
       t.removeClass(mustBeHoverClass);
     }
     function removeHoverClass(o){
       var t = $(this);
       if(t.hasClass(mustBeUnhoverClass) && t.hasClass(o.hoverClass)){
         t.toggleClass(o.hoverClass, duration, 'easeOutSine');
       }
       t.removeClass(mustBeUnhoverClass);
     }
     function removeHoverClassPermanently(o){
       var t = $(this);
       t.removeClass(o.hoverClass);
       t.removeClass(mustBeUnhoverClass);
     }
     
     function projectHover(nav, o){
       var elSelector = selector(o.elClass);
       
       nav.on('mouseenter', elSelector, function(){
         var t = $(this);
         t.removeClass(mustBeUnhoverClass);
         t.addClass(mustBeHoverClass);
         
         if(!t.hasClass(o.currentClass)){
           t.promise().always(addHoverClass);
           o.callback(this);
         }
       });
       
       nav.on('mouseout', elSelector, function(){
         var t = $(this);
         t.removeClass(mustBeHoverClass);
         t.addClass(mustBeUnhoverClass);
         
         if(t.hasClass(o.currentClass)){
           t.promise().always(removeHoverClassPermanently);
         }
         else{
           t.promise().always(removeHoverClass);
           o.callback(undefined);
         }
       });
     }
     
     $.fn.extend({
       projectHover: function(o){
         if(typeof(o)=="function"){
           o = {callback: o};
         }
         o = $.extend({}, projectHoverDefaults, o);
         projectHover(this, o);
       }
     });
    })();
function f1(){
  var menus = {
    main:{
      name:'Main',
     desc:'The main page'
    },
     search:{
       name:'Search',
     desc:'The search page'
     },
     map:{
       name:'Map',
     desc:'The map page'
     },
     home:{
       name:'Home',
     desc:'The home page'
     }
  };
  var menu = $('.top_menu');
  var nav = $('nav', menu);
  var desc = $('.desc', menu);
  
  var
  el = '.el',
  elClass = 'el',
  current = '.current',
  currentEl = '.current.el',
  currentClass = 'current'
  ;
  
  function updateDesc(){
    desc.text(menus[this.attr('id')].desc);
  }
  
  
  nav.empty();
  $.each(menus, function(id, m){
    nav.append(
      '<div id="{id}" class="name el">{name}</div>'
      .replace(/{id}/g,id)
      .replace(/{name}/g,m.name)
    );
  });
  
  nav.on('click', el, function(event){
    event.preventDefault();
    
    var t = $(this);
    
    updateDesc.call(t);
    
    if(!t.is(current)){
      $(currentEl, nav).removeClass(currentClass);
      t.addClass(currentClass);
    }
  });
  
  nav.projectHover(function(target){
    if(target == undefined){
      var c = $(currentEl, nav);
    }
    else{
      var c = $(target);
    }
    updateDesc.call(c);
  });
 
  $(el, nav).first().trigger('click');
 
  }
  $(f1);
</script>
 
</head>
<body>
  <div class="container">
    <div class="header">
      <a href="" class="logo">
        <div class="name">project</div>
        <div class="desc">The project site</div>
      </a>
      
      <div class="top_menu">
        <nav></nav>
        <div class="desc"></div>
      </div>
      <div class="cl"></div>
    </div>
    <div class="content"></div>
    <div class="footer">
      <div class="copy">project &copy; 2013</div>
    </div>
  </div>
</body>
</html>
при чем

addClass отрабатывает есль элемент имеет класс .current иначе нет.

если писать так, то добавляется класс mustBeHoverUnhoverClass+"_"
JavaScript
1
2
         t.addClass(mustBeHoverUnhoverClass);
         t.addClass(mustBeHoverUnhoverClass+"_");
JavaScript
1
2
         t.addClass(mustBeHoverUnhoverClass+"_");
         t.addClass(mustBeHoverUnhoverClass);
если писать так, то опять не работает
JavaScript
1
         t.addClass(mustBeHoverUnhoverClass+"_");
Добавлено через 42 секунды
браузер
О программе
Информация о версии
Версия: 12.16
Сборка: 1860
Платформа: Linux
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
15.12.2013, 22:28
Ответы с готовыми решениями:

метод addClass и removeClass
Добрый день! подскажите почему старый класс не заменяется новым? $(document).ready(function(){...

removeClass и addClass
Если сделать div(например 2-ой блок) активным(с классом .focusnav), то у div&gt;a удаляется класс...

Метод addClass()
У меня множество объектов которые выводится в цикле на сайте Проблема: при наведение мышью на...

7
Иллюзионист
 Аватар для philin
154 / 153 / 27
Регистрация: 02.10.2013
Сообщений: 330
15.12.2013, 23:36
Вы бы хоть обрезали лишнее или строки указали, куда смотреть. Работа с классами почти везде. Искать изменения в 250 строках — не секундное дело, тем более, что структура изменилась.
Кстати, mustBeHoverUnhoverClass присутствует только в разъяснении внизу. Проверил этот пример - ничего странного не увидел. И без "_" добавляет, и с "_". (jQuery 2.0.3, Chrome 30, Win8)

Покажите, пожалуйста, короткий образец непосредственно из кода, рабочий и нерабочий варианты. Или укажите строки.
1
Superposition
 Аватар для Padimanskas
950 / 615 / 256
Регистрация: 27.10.2013
Сообщений: 2,083
15.12.2013, 23:44
Цитата Сообщение от gGrn-7DA Посмотреть сообщение
addClass отрабатывает есль элемент имеет класс .current иначе нет.
http://api.jquery.com/addClass
It's important to note that this method does not replace a class. It simply adds the class
"Важно заметить, что этот метод не меняет класс, а просто добавляет его"
This method is often used with .removeClass() to switch elements' classes from one to another
"Этот метод часто используется совместно с .removeClass() для переключения элементов с одного класса на другой"
0
мну довольно <(-__-)l
 Аватар для gGrn-7DA
217 / 206 / 15
Регистрация: 17.01.2010
Сообщений: 2,462
16.12.2013, 21:49  [ТС]
philin, ну вообще можно было бы найти поиском слова addClass, ну да ладно. хотел выложить что бы работало. Сейчас оставлю только js

Добавлено через 4 минуты
Padimanskas, я это знаю.

во втором случае метод addClass отрабатывает так

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
$(<div class="el name">qwerty</div>).addClass(mustBeHoverClass) 
-> <div class="el name">qwerty</div>
 
$(<div class="el name current">qwerty</div>).addClass(mustBeHoverClass) 
-> <div class="el name current must-be-hover">qwerty</div>
 
$(<div class="el name">qwerty</div>).addClass(mustBeHoverClass).addClass(mustBeHoverClass+"_") 
-> <div class="el name must-be-hover_">qwerty</div>
$(<div class="el name">qwerty</div>).addClass(mustBeHoverClass+"_").addClass(mustBeHoverClass) 
-> <div class="el name must-be-hover_">qwerty</div>
 
$(<div class="el name">qwerty</div>).addClass(mustBeHoverClass+"_") 
-> <div class="el name">qwerty</div>
Добавлено через 3 минуты
между первым и вторым вариантом еще есть разница в использовании is(".class") и hasClass("class"), но в силу того что вызов addClass стоит раньше этой проверки влиять оно не может.

Добавлено через 4 минуты

смотреть нужно на вызовы t.addClass внутри обработчиков mouseenter и mouseout

второй вариант это попытка запихнуть поведение в изолированный модуль. callback вызывается.

первый вариант, рабочий
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
$(function(){
    /*...*/
    var nav = $('nav', menu);
    /*...*/
    var duration = 128;
    
    var
    el = '.el',
    elClass = 'el',
    current = '.current',
    currentEl = '.current.el',
    currentClass = 'current',
    hover = '.hover',
    hoverClass = 'hover',
    mustBeHover = '.must-be-hover',
    mustBeHoverClass = 'must-be-hover',
    mustBeUnhover = '.must-be-unhover',
    mustBeUnhoverClass = 'must-be-unhover'
    ;
    
    function updateDesc(){/*...*/}
    
    function addHoverClass(){
      var t = $(this);
      if(t.is(mustBeHover) && (!(t.is(current) || t.is(hover)))){
        t.toggleClass(hoverClass, duration, 'easeOutSine');
      }
      t.removeClass(mustBeHover);
    }
    function removeHoverClass(){
      var t = $(this);
      if(t.is(mustBeUnhover) && t.is(hover)){
        t.toggleClass(hoverClass, duration, 'easeOutSine');
      }
      t.removeClass(mustBeUnhoverClass);
    }
    function removeHoverClassPermanently(){
      $(this).removeClass(hoverClass);
    }
    
    /*генерация меню - обработчик click ставит элементу класс current*/
    
    nav.on('mouseenter', el, function(){
      var t = $(this);
      t.removeClass(mustBeUnhoverClass);
      t.addClass(mustBeHoverClass);
      
      if(!t.is(current)){
        t.promise().always(addHoverClass);
        updateDesc.call(t);
      }
    });
    nav.on('mouseout', el, function(){
      var t = $(this);
      t.removeClass(mustBeHoverClass);
      t.addClass(mustBeUnhoverClass);
      
      if(t.is(current)){
        t.promise().always(removeHoverClassPermanently);
      }
      else{
        t.promise().always(removeHoverClass);
      }
      
      var c = $(currentEl, nav);
      updateDesc.call(c);
    });
 
    $(el, nav).first().trigger('click');
  });
второй вариант
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
(function(){
      var 
      duration = 200,
     mustBeHoverClass = 'project-must-be-hover',
     mustBeUnhoverClass = 'project-must-be-unhover',
     projectHoverDefaults = $.extend({}, {
       elClass: 'el',
       currentClass: 'current',
       hoverClass: 'hover'
     });
     
     function selector(_class){
       return '.' + _class;
     }
     
     function addHoverClass(o){
       var t = $(this);
       if(t.hasClass(mustBeHoverClass) && (!(t.hasClass(o.currentClass) || t.hasClass(o.hoverClass)))){
         t.toggleClass(o.hoverClass, duration, 'easeOutSine');
       }
       t.removeClass(mustBeHoverClass);
     }
     function removeHoverClass(o){
       var t = $(this);
       if(t.hasClass(mustBeUnhoverClass) && t.hasClass(o.hoverClass)){
         t.toggleClass(o.hoverClass, duration, 'easeOutSine');
       }
       t.removeClass(mustBeUnhoverClass);
     }
     function removeHoverClassPermanently(o){
       var t = $(this);
       t.removeClass(o.hoverClass);
       t.removeClass(mustBeUnhoverClass);
     }
     
     function projectHover(nav, o){
       var elSelector = selector(o.elClass);
       
       nav.on('mouseenter', elSelector, function(){
         var t = $(this);
         t.removeClass(mustBeUnhoverClass);
         t.addClass(mustBeHoverClass);
         
         if(!t.hasClass(o.currentClass)){
           t.promise().always(addHoverClass);
           o.callback(this);
         }
       });
       
       nav.on('mouseout', elSelector, function(){
         var t = $(this);
         t.removeClass(mustBeHoverClass);
         t.addClass(mustBeUnhoverClass);
         
         if(t.hasClass(o.currentClass)){
           t.promise().always(removeHoverClassPermanently);
         }
         else{
           t.promise().always(removeHoverClass);
           o.callback(undefined);
         }
       });
     }
     
     $.fn.extend({
       projectHover: function(o){
         if(typeof(o)=="function"){
           o = {callback: o};
         }
         o = $.extend({}, projectHoverDefaults, o);
         projectHover(this, o);
       }
     });
    })();
function f1(){
  /*...*/
  var nav = $('nav', menu);
  /*...*/
  
  var
  el = '.el',
  elClass = 'el',
  current = '.current',
  currentEl = '.current.el',
  currentClass = 'current'
  ;
  
  function updateDesc(){/*...*/}
  
  /*генерация меню - обработчик click ставит элементу класс current*/
  
  nav.projectHover(function(target){
    if(target == undefined){
      var c = $(currentEl, nav);
    }
    else{
      var c = $(target);
    }
    updateDesc.call(c);
  });
 
  $(el, nav).first().trigger('click');
 
  }
Добавлено через 3 минуты
Цитата Сообщение от philin Посмотреть сообщение
Кстати, mustBeHoverUnhoverClass присутствует только в разъяснении внизу.
это должны быть mustBeHoverClass и mustBeUnhoverClass

у меня была мысль что дело в браузере, но что бы столь простая вещь как добавление класса не работала... нонсенс)

Добавлено через 9 часов 45 минут
chromium Версия 31.0.1650.57 (235101) та же история.
0
Иллюзионист
 Аватар для philin
154 / 153 / 27
Регистрация: 02.10.2013
Сообщений: 330
17.12.2013, 00:38
Покопался. Повырезал куски. Нашел корень зла:
JavaScript
1
 t.promise().always(addHoverClass);
Конкретно - promise(). Без него классы нормально добавляются/удаляются.
1
мну довольно <(-__-)l
 Аватар для gGrn-7DA
217 / 206 / 15
Регистрация: 17.01.2010
Сообщений: 2,462
17.12.2013, 16:15  [ТС]
ок, если не сложно поставь duration = 1500 и просто поводи быстро мышкой над меню. думаю ты сразу выловишь пару новых багов...
собственно, если бы мне хватало toggleClass, то я бы столько всего не городил...
хотя возможно это и поможет, все таки классы mustBuHoverUnhover я добавил уже после того как взялся за promise() ...

но ты все равно проверь duration = 1500 и я сам тоже проверю

Добавлено через 1 минуту
да и сам баг непонятен. всего то я события mouseenter mouseout вешаю на 2 уровня глубже в функциях...

Добавлено через 2 минуты
хотя может собака зарыта тут, в вызове метода $.extend
но ведь контекст не теряется при этом и вызов callback таки проходит успешно...
JavaScript
1
2
3
4
5
6
7
8
9
$.fn.extend({
       projectHover: function(o){
         if(typeof(o)=="function"){
           o = {callback: o};
         }
         o = $.extend({}, projectHoverDefaults, o);
         projectHover(this, o);
       }
     });
Добавлено через 10 минут
сделал так. и баги (наличие бекграунда после того как уведешь курсор с элемента быстрее чем за 200 (duration) секунд после наведения) вылезли даже на duration = 200
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function projectHover(nav, o){
       var elSelector = selector(o.elClass);
       
       nav.on('mouseenter', elSelector, function(){
         var t = $(this);
         t.removeClass(mustBeUnhoverClass);
         t.addClass(mustBeHoverClass);
         
         if(!t.hasClass(o.currentClass)){
           //t.promise().always(addHoverClass);
           addHoverClass.call(this, o);
           o.callback(this);
         }
       });
       
       nav.on('mouseout', elSelector, function(){
         var t = $(this);
         t.removeClass(mustBeHoverClass);
         t.addClass(mustBeUnhoverClass);
         
         if(t.hasClass(o.currentClass)){
           //t.promise().always(removeHoverClassPermanently);
           removeHoverClassPermanently.call(this, o);
         }
         else{
           //t.promise().always(removeHoverClass);
           removeHoverClass.call(this, o);
           o.callback(undefined);
         }
       });
     }
может вы как то по другому сделали?

Добавлено через 20 минут
опять же в первом варианте promise() работает на ура
0
Иллюзионист
 Аватар для philin
154 / 153 / 27
Регистрация: 02.10.2013
Сообщений: 330
17.12.2013, 16:19
Брал из первого поста 2 вариант, "нерабочий". Убрал оттуда promise() в mouseenter - классы стали добавляться. Разве что у .project-must-be-hover фон не определен.
Заменил projectHover() из последнего поста - стал добавляться .hover. Но не вижу косяков с фоном, нормально исчезает.
Кстати, duration совсем не вижу, все мгновенно. В любом варианте.
Больше ничего вроде и не делал.
Вот без замены projectHover():
CSS
Кликните здесь для просмотра всего текста
CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
html,body{
  margin:0;
  padding:0;
}
 
html{
  height: 100%;
  overflow-y: scroll;
  overflow-x: hidden;
  background: rgba(224,224,240,1);
  font-size: 14pt;
}
 
a,a:hover,a:link,a:visited{
  text-decoration: none;
  color: inherit;
}
 
.cl{clear:both;}
.cll{clear:left;}
.clr{clear:right;}
 
body{
  width: 1200px;
  overflow: hidden;
  margin: 20px auto 40px;
  box-shadow: 0px 0px 4px rgba(0,0,0,.7);
}
 
.header, .footer{
  background: rgba(32,64,192,.8);
  color: #eee;
}
.header{
}
.footer{
}
 
.header .logo{
  float: right;
  width: 240px;
  display: block;
  cursor: pointer;
  text-align: right;
  /*background: rgba(80,80,80,.4);*/
}
.header .name,
.header .desc{
  padding: 8px 16px;
}
.header .name{
  font-weight: 600;
  font-size: 18pt;
}
.header .desc{
  font-size: 12pt;
}
 
.header .top_menu{
  float: left;
  width: 960px;
  /*background: rgba(180,180,180,.2);*/
}
.header .top_menu .el{
  display: inline-block;
  margin-right: 4px;
  cursor: pointer;
}
.header .top_menu .el.current,
.header .top_menu .el.hover{
  background: rgba(80,80,80,.4);
}
 
.footer{
  padding: 8px;
  text-align: right;
}
 
.content{
  padding:64px 0;
}

HTML
Кликните здесь для просмотра всего текста
HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
 
 
<script type="text/javascript" src="jquery.min.js"></script>
<!-- <script type="text/javascript" src="../jquery/jquery-2.0.3.js"></script> -->
<!-- <script type="text/javascript" src="../jquery/jquery-ui-1.10.3.flick/js/jquery-ui-1.10.3.flick.js"></script> -->
 
 
</head>
<body>
  <div class="container">
    <div class="header">
      <a href="" class="logo">
        <div class="name">project</div>
        <div class="desc">The project site</div>
      </a>
 
      <div class="top_menu">
        <nav></nav>
        <div class="desc"></div>
      </div>
      <div class="cl"></div>
    </div>
    <div class="content"></div>
    <div class="footer">
      <div class="copy">project &copy; 2013</div>
    </div>
  </div>
</body>
</html>

JS
Кликните здесь для просмотра всего текста
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
(function(){
      var
      duration = 1500,
     mustBeHoverClass = 'project-must-be-hover',
     mustBeUnhoverClass = 'project-must-be-unhover',
     projectHoverDefaults = $.extend({}, {
       elClass: 'el',
       currentClass: 'current',
       hoverClass: 'hover'
     });
 
     function selector(_class){
       return '.' + _class;
     }
 
     function addHoverClass(o){
       var t = $(this);
       if(t.hasClass(mustBeHoverClass) && (!(t.hasClass(o.currentClass) || t.hasClass(o.hoverClass)))){
         t.toggleClass(o.hoverClass, duration, 'easeOutSine');
       }
       t.removeClass(mustBeHoverClass);
     }
     function removeHoverClass(o){
       var t = $(this);
       if(t.hasClass(mustBeUnhoverClass) && t.hasClass(o.hoverClass)){
         t.toggleClass(o.hoverClass, duration, 'easeOutSine');
       }
       t.removeClass(mustBeUnhoverClass);
     }
     function removeHoverClassPermanently(o){
       var t = $(this);
       t.removeClass(o.hoverClass);
       t.removeClass(mustBeUnhoverClass);
     }
 
     function projectHover(nav, o){
       var elSelector = selector(o.elClass);
       
       nav.on('mouseenter', elSelector, function(){
         var t = $(this);
         t.removeClass(mustBeUnhoverClass);
         t.addClass(mustBeHoverClass);
         
         if(!t.hasClass(o.currentClass)){
           t.always(addHoverClass);
           o.callback(this);
         }
       });
       
       nav.on('mouseout', elSelector, function(){
         var t = $(this);
         t.removeClass(mustBeHoverClass);
         t.addClass(mustBeUnhoverClass);
         
         if(t.hasClass(o.currentClass)){
           t.promise().always(removeHoverClassPermanently);
         }
         else{
           t.promise().always(removeHoverClass);
           o.callback(undefined);
         }
       });
     }
 
     $.fn.extend({
       projectHover: function(o){
         if(typeof(o)=="function"){
           o = {callback: o};
         }
         o = $.extend({}, projectHoverDefaults, o);
         projectHover(this, o);
       }
     });
    })();
function f1(){
  var menus = {
    main:{
      name:'Main',
     desc:'The main page'
    },
     search:{
       name:'Search',
     desc:'The search page'
     },
     map:{
       name:'Map',
     desc:'The map page'
     },
     home:{
       name:'Home',
     desc:'The home page'
     }
  };
  var menu = $('.top_menu');
  var nav = $('nav', menu);
  var desc = $('.desc', menu);
 
  var
  el = '.el',
  elClass = 'el',
  current = '.current',
  currentEl = '.current.el',
  currentClass = 'current'
  ;
 
  function updateDesc(){
    desc.text(menus[this.attr('id')].desc);
  }
 
 
  nav.empty();
  $.each(menus, function(id, m){
    nav.append(
      '<div id="{id}" class="name el">{name}</div>'
      .replace(/{id}/g,id)
      .replace(/{name}/g,m.name)
    );
  });
 
  nav.on('click', el, function(event){
    event.preventDefault();
 
    var t = $(this);
 
    updateDesc.call(t);
 
    if(!t.is(current)){
      $(currentEl, nav).removeClass(currentClass);
      t.addClass(currentClass);
    }
  });
 
  nav.projectHover(function(target){
    if(target == undefined){
      var c = $(currentEl, nav);
    }
    else{
      var c = $(target);
    }
    updateDesc.call(c);
  });
 
  $(el, nav).first().trigger('click');
 
  }
  $(f1);
0
мну довольно <(-__-)l
 Аватар для gGrn-7DA
217 / 206 / 15
Регистрация: 17.01.2010
Сообщений: 2,462
17.12.2013, 18:29  [ТС]
45 строка javascript
JavaScript
1
t.always(addHoverClass);
нет такого метода

Добавлено через 2 минуты
Цитата Сообщение от philin Посмотреть сообщение
Кстати, duration совсем не вижу, все мгновенно. В любом варианте.
с 1500 задержка должна быть полторы секунды, это очень странно!
Цитата Сообщение от philin Посмотреть сообщение
Разве что у .project-must-be-hover фон не определен.
это классы для индикации состояния элемента. точнее было бы написать hoveringInProcess и unhoveringInProcess

Добавлено через 3 минуты
поставил 45 строкой
JavaScript
1
addHoverClass.call(this, o);
фон появляется но не убирается.
убрав совсем promise мы полчуим баг, при котором при быстром проведении курсором над меню фон будет оставаться.

Добавлено через 26 минут
Пришел к выводу, что не отрабатывает toggleClass

Добавлено через 42 минуты
надо разбираться почему $.effects.animateClass не отрабатывает...

Добавлено через 4 минуты
ок, буду смотреть в сторону css3 анимаций.

Добавлено через 12 минут
так намного лучше
CSS
1
2
3
4
5
6
7
8
9
10
11
.header .top_menu .el{
  display: inline-block;
  margin-right: 4px;
  cursor: pointer;
  transition: all 0.2s ease;
}
.header .top_menu .el.current,
.header .top_menu .el:hover{
  background: rgba(80,80,80,.4);
  transition: all 0.2s ease;
}
вместо моего js костыля, хотя очень интересный костыль то))))
JavaScript
1
2
3
4
5
6
  nav.on('mouseenter', el, function() {
    $(this).addClass(hoverClass);
  });
  nav.on('mouseout', el, function() {
    $(this).removeClass(hoverClass);
  });
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
17.12.2013, 18:29
Помогаю со студенческими работами здесь

addClass не назначается таблице
Почему CSS класс не применяется к созданной через Jquery таблице? &lt;div...

AddClass()
&lt;div onclick=&quot;action(0)&quot; class=&quot;button&quot;&gt; &lt;div class=&quot;button2&quot;&gt;&lt;/div&gt; &lt;div...

Как лучше: animate или transition, addClass
Нужно сделать поочерёдное плавное появление нескольких элементов на странице. Я сделал в CSS у...

RemoveClass/addClass() не работает в Firefox
Есть код: js... $('li').click(function() { $('li').removeClass('active');//Снимаем...

AddClass - не активный класс
Добрый день. Скажите пожалуйста почему при создании класса с помощью «addClass», этот ново...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru