我正在尝试实现一个脚本来为特定元素设置不同的类名...
让我们假设dom看起来像这样:
<body class='pre-existing-class-name'>
如果我做
smartToogle('body', 'new-class');
// the dom should look like this
// <body class='pre-existing-class-name new-class'>
smartToogle('body', 'new-class-2');
// the dom should look like this
// <body class='pre-existing-class-name new-class-2'>
我做了以下代码,但它不起作用:
var smartToogle = function (element, newClassName) {
var oldClassName;
var $element = $(element);
$element.addClass(newClassName);
if (oldClassName !== newClassName) {
$element.removeClass(oldClassName);
}
oldClassName = newClassName;
};
要求:
1)我正在使用查询
2)我想传递一个类名,即新名称。
解决方案:
以下代码有效,但我不喜欢它,因为它使用全局变量
任何提示修复它?
function myToggle(newClassName) {
if (window.oldClassName) {
$('body').toggleClass(window.oldClassName);
}
window.oldClassName = newClassName;
$('body').toggleClass(newClassName);
}
答案 0 :(得分:8)
您可以使用元素的数据属性,可以使用
访问$(element).data(attrib_name)
您的方法只需要进行一些小改动
function myToggle(newClassName) {
if (window.oldClassName) {
$('body').toggleClass(window.oldClassName);
}
window.oldClassName = newClassName;
$('body').toggleClass(newClassName);
}
可以替换为
function myToggle(element, newClassName) {
if ($(element).data('oldClassName')) {
$(element).toggleClass($(element).data('oldClassName'));
}
$(element).data('oldClassName', newClassName)
$(element).toggleClass(newClassName);
}
希望这能为你解决。
答案 1 :(得分:5)
<强>更新强>
您需要了解一件事。 如果您想要两种不同的行为,则行为更改不需要2个不同的类。 一个就足够了,因为您可以根据类 on 或 off 来改变行为。
假设我想让我的元素以一种方式产生红色悬停事件。 并希望它与CSS有另一种方式的蓝色悬停事件。 然后这是要走的路:
$('#toggle').click(function(){
$('.normal').each(function(){
$(this).toggleClass('active');
});
});
这里我们使用一个按钮切换所有div并改变他们的CSS行为,现在看起来很简单吗?
但是,如果您需要切换 Javascript / jQuery事件,那么这将无法做到。在这种情况下,您将需要使用其他3种方法来管理它; .on()
,.off()
和.hasClass()
。
$('#toggle').click(function(){
$('.normal').each(function(){
if($(this).hasClass('active')){
$(this).off('click');
} else {
$(this).on('click', function(){
alert('You are clicking on an active div.');
});
}
$(this).toggleClass('active');
});
});
如您所见,我们添加了 if语句。如果元素具有.active
类,我们将.off()
转为.click()
。如果没有活动课程,我们会转到.click()
.on()
。在if语句下,我们始终切换.active
类。所以这不必放在if语句中。
我希望这能为你解决所有问题,祝你好运!
旧答案:
最好在这里使用.toggleClass()
。
在元素上使用第一个类作为默认属性,第二个类作为.active
,例如用于交互。
此外,使用.on('click', function(){})
绑定将使您能够添加在切换元素后立即绑定的交互。
答案 2 :(得分:3)
这是一个小提琴:http://jsfiddle.net/NCwmF/2/
我是一个小jQuery插件。删除当前的智能类(如果有)并添加新的智能类。如果在没有参数className
的情况下调用,则仅删除当前的智能类。
$.fn.smartToggle = function (className) {
var dataId = 'smartToggle';
return this.each(function () {
var $el = $(this);
$el
.removeClass($el.data(dataId) || '')
.addClass(className)
.data(dataId, className);
});
};
像其他jQuery方法一样使用它:
$('body').smartToggle('myClass');
答案 3 :(得分:2)
NEW,SIMPLER ANSWER 类似于之前的工作,增加了2个:1。)如果最初没有类,则工作; 2.)如果其他函数在两次调用之间更改元素类,则可以工作。我还更改了函数名称,因此它不会干扰jQuerys本机toggleClass。
$.fn.fancyToggleClass = function(new_class) {
return this.each(function() {
// get the last class this function added (if exists) or false (if not)
var $this = $(this),
toggled_class = $this.data('toggled-class') || false;
// if we dont have an original class, then set it based on current class
if (toggled_class) {
$this.removeClass(toggled_class);
}
// add new class and store as data,
// which we check for next time function is called
$this.addClass(new_class).data('toggled-class', new_class);
// alert the class, just as a check to make sure everything worked!
// remove this for production, or switch to console.log
alert('element class: ' + $this.attr('class'));
});
}
更新小提琴:http://jsfiddle.net/facultymatt/xSvFC/3/
OLD ANSWER 我建议将原始类存储在elements data属性中。然后,您的函数可以检查是否设置了此数据,如果清楚,则元素类添加元素数据中的原始类以及您在函数中传递的新类。
如果未设置数据,该函数将在当第一次运行时将当前类存储为数据。
查看这个小提琴,找到一个有评论的工作示例:http://jsfiddle.net/facultymatt/xSvFC/
这是代码。它是一个jquery函数,因此可以在任何元素上调用(也可以链接!)
$.fn.toggleClass = function(new_class) {
return this.each(function() {
// cache selector for this
$this = $(this);
// get original class (if exists) or false (if not)
var original_class = $this.data('original-class') || false;
// if we dont have an original class, then set it based on current class
if (!original_class) {
original_class = $this.attr('class');
$this.data('original-class', original_class);
// we do have an original class, so we know user is now trying to add class
// here we clear the class, add the original class, and add the new class
} else {
// assign the original class, and new class,
// and a space to keep the classes from becoming one
$this.attr('class', original_class + ' ' + new_class);
}
// alert the class, just as a check to make sure everything worked!
// remove this for production, or switch to console.log
alert('element class: ' + $this.attr('class'));
});
}
希望这有帮助!
答案 4 :(得分:1)
要避免使用全局变量,可以使用@ankur写入的数据属性。以下是您的问题的可行解决方案:
function myToggle(element, newClassName) {
if (!$(element).data('baseclassname')) {
$(element).data('baseclassname', $(element).attr('class'));
}
$(element)
.attr('class', $(element).data('baseclassname'))
.addClass(newClassName);
}
答案 5 :(得分:0)
这可以帮到你吗?
var smartToogle = function (element, preExistingClassName, newClassName) {
$(element)[0].className = preExistingClassName + ' ' + newClassName;
};
答案 6 :(得分:0)
只需使用hasClass
即可。但是你必须告诉函数两个类是什么:
function smartToggle(element, class1, class2) {
var $element = $(element);
if ($element.hasClass(class1)) {
$element.removeClass(class1);
$element.addClass(class2);
}
else {
$element.removeClass(class2);
$element.addClass(class1);
}
}
答案 7 :(得分:0)
$(function(){
var smartToggle = function (element, newClassName) {
var elementClasses = element.attr('class');
element.addClass(newClassName);
// check if there is more than one class on the element
if(elementClasses .indexOf(' ') >= 0){
var oldClassNames = elementClasses.split(" ");
if (oldClassNames[oldClassNames.length - 1] !== newClassName) {
element.removeClass(oldClassNames[oldClassNames.length - 1]);
}
}
};
smartToggle($('.test'), 'newclass');
smartToggle($('.test'), 'newclass2');
});
演示 - http://jsfiddle.net/Q9A8N/ (查看控制台,了解每次传递的动态)
这应该做你想要的,但作为@ T.J。克劳德说它相当脆弱,并假设您要删除的类是元素中的最后一个。
答案 8 :(得分:0)
作为对您问题的回答,我会选择ankur's answer
作为Sem's answer的后续,关于jQuery事件的处理:
您可以使用on
函数根据实时过滤器处理来自父节点的任何jquery事件:
function myToggle(element, newClassName) {
if ($(element).data('oldClassName')) {
$(element).toggleClass($(element).data('oldClassName'));
}
$(element).data('oldClassName', newClassName);
$(element).toggleClass(newClassName);
}
//event delegation : 'on' is called on the $('.divContainer') node, but we handle
//clicks on '.divItm' items, depending on their current class
$('.divContainer')
.on('click', '.divItm.plain', function(){ myToggle( this, 'red' ); })
.on('click', '.divItm.red', function(){ myToggle( this, 'blue' ); })
.on('click', '.divItm.blue', function(){ myToggle( this, 'plain' ); });
//initialize each item with the 'plain' class
myToggle( $('.divItm'), 'plain' );
这是jsFiddle。
您将注意到,每次单击某个项目时调用的函数取决于其“实时”类,并且每次项目更改类时您都不需要手动启用/禁用click
处理程序。
您可以从documentation page了解更多详情。
答案 9 :(得分:0)
var smartToogle = function (element, newClass) {
var $element = $(element),
currentClass = $element.data('toggle-class');
if (currentClass != newClass) $element.data('toggle-class',newClass).removeClass(currentClass || '');
$element.toggleClass(newClass);
};
或其他变体:
$.fn.smartToogle = function (newClass) {
currentClass = this.data('toggle-class');
if (currentClass != newClass) this.data('toggle-class',newClass).removeClass(currentClass || '');
this.toggleClass(newClass);
};
答案 10 :(得分:0)
在此实现中,您必须保留对此fancytoggle实例的引用。
var fancytoggle = function(el, oldClass){
// create a function scope so we'll have a reference to oldClass
return function(newClass) {
// toggle the old class and the new class
$(el).toggleClass(oldClass+ ' ' + newClass);
// update the new class to be the old class
oldClass = newClass;
};
};
对于您的示例,代码看起来像。
var bodytoggle = fancytoggle('body', 'pre-existing-class-name');
bodytoggle('new-class');
// 'new-class' replaces 'pre-existing-class-name'
bodytoggle('new-class-2');
// 'new-class-2' replaces 'new-class'
要查看其中的行为,请参阅http://jsfiddle.net/aaf2L/6/