7

特定の要素に異なるクラス名を設定するスクリプトを実装しようとしています…</p>

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)クラス名を1つだけ、新しい名前を渡したい。


解決策:
次のコードは機能しますが、グローバル変数を使用しているため、私はそれが好きではありません。
それを修正するためのヒントはありますか?

function myToggle(newClassName) {
    if (window.oldClassName) {
         $('body').toggleClass(window.oldClassName);
    }
    window.oldClassName = newClassName;
    $('body').toggleClass(newClassName);
}
4

11 に答える 11

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);
}

これで解決することを願っています。

于 2012-10-18T10:15:44.410 に答える
5

アップデート:

理解する必要があることが1つあります。2つの異なる動作が必要な場合は、動作の変更に2つの異なるクラスは必要ありませんクラスがオンオフかに基づいて動作を変更できるため、1つで十分です。

ある方法で要素に赤いホバーイベントを持たせたいとしましょう。そして、CSSで逆に青いホバーイベントを発生させたいと考えています。次に、これが進むべき道です:

$('#toggle').click(function(){
    $('.normal').each(function(){
        $(this).toggleClass('active');
    });        
});

JSFiddleデモ

ここでは、ボタンを使用してすべての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');
    });        
});

JSFiddleデモ2

ご覧のとおり、ifステートメントを追加しました。要素に.activeクラスがある場合は、をオン.off()にし.click()ます。そして、アクティブなクラスがない場合は、をオンにし.click() .on()ます。ifステートメントでは、常にクラスを切り替えます.active。したがって、これをifステートメント内に配置する必要はありません。

これですべてがクリアされることを願っています、頑張ってください!


古い答え:

ここで使用することをお勧めし.toggleClass()ます。

要素の最初のクラスをデフォルトのプロパティに使用し、2番目のクラス.activeをたとえば相互作用に使用します。

また、.on('click', function(){})バインドを使用すると、要素が切り替えられるとすぐにバインドされるインタラクションを追加できるようになります。

于 2012-10-16T08:15:48.220 に答える
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');
于 2012-10-19T22:55:04.750 に答える
2

新しい、より単純な回答 以前と同様に機能しますが、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 元のクラスを要素のデータ属性に格納することをお勧めします。次に、関数はこのデータが設定されているかどうかを確認できます。設定されている場合は、要素データから元のクラスを追加して要素クラスをクリアし、関数に渡した新しいクラスも追加します。

データが設定されていない場合、関数は最初の実行時に現在のクラスをデータとして保存します。

コメント付きの実際の例については、このフィドルを確認してください: 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'));

    });
}

お役に立てれば!

于 2012-10-23T21:11:07.530 に答える
1

グローバル変数を回避するには、@ankur の書き込みとして data 属性を使用できます。あなたの問題に対する有効な解決策は次のとおりです。

function myToggle(element, newClassName) { 
    if (!$(element).data('baseclassname')) { 
        $(element).data('baseclassname', $(element).attr('class')); 
    } 
    $(element)
        .attr('class', $(element).data('baseclassname'))
        .addClass(newClassName); 
}
于 2012-10-18T21:51:08.977 に答える
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);
};
于 2012-10-23T18:53:35.047 に答える
0

これはあなたの仕事をしますか?

var smartToogle = function (element, preExistingClassName, newClassName) {
    $(element)[0].className = preExistingClassName + ' ' + newClassName;
};
于 2012-10-16T08:18:07.457 に答える
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);
    }
}
于 2012-10-16T08:18:46.643 に答える
0

あなたの質問への答えとして、私はアンクルの答えに行きます

jQueryイベントの処理に関するSemの回答のフォローアップとして:

関数を使用し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アイテムのクラスが変わるたびにハンドラーを手動で有効/無効にする必要がないことに注意してください。

詳細については、ドキュメント ページを参照してください。

于 2012-10-23T12:09:49.350 に答える
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/ (コンソールを見て、各パスで何をしているかを確認してください)

それはあなたが望むことをするはずですが、@TJ Crowderが言ったように、それはかなり壊れやすく、削除したいクラスが要素の最後のクラスであると想定しています。

于 2012-10-16T08:31:20.357 に答える
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/を参照してください。

于 2012-10-24T18:35:43.027 に答える