jQuery Snippets #10

jQuery Snippets #10

基礎的なものからちょっとした機能の実装方法など、jQueryに関する個人的なメモ・スニペットリストです。
書いている内容に対して「もっとスマートにできる」とか「そもそも間違ってる」みたいなのがあれば、ツッコミ大歓迎なのでコメントなど通じて是非教えてください。

動きをすぐ確認できるデモなどは基本的に用意していないので、実際の動きを確認したい場合などは自身で簡単な環境を作成して試してもらうか、CodePenJSFiddleなどを利用して確認してください。

jQuery Snippets #10 目次

  1. ul要素内のli要素を分割する
  2. data属性を利用したシンプルなフィルタ機能
  3. 1度だけ実行させる
  4. 本来の画像サイズを取得
  5. 特定の要素が何番目かを取得する
  6. 特定の文字列を置換する
  7. フラグ判定
  8. 現在地によってページ内ナビゲーションにclassを追加・削除する
  9. 要素をアルファベット順でソートする
  10. 要素の数字でソートする

1. ul要素内のli要素を分割する

ul要素内にあるli要素を指定した数に分割するという動きを実装するもので、何分割するかはul要素に記述してあるdata-colsというdata属性で指定します。
下記サンプルコードのHTMLをそのまま使用した場合は「li要素を3つのul要素に分割させる」という動きになり、1〜4がひとつ目、5〜7がふたつ目、8〜10がみっつ目として分割されて、それぞれが異なるul要素で括られます。
また、jQueryの一番下ではもともとあったul.split-listdiv.split-listに変換させており、これによりul要素直下にul要素がきてしまうのを回避しています。

HTML

<ul class="split-list" data-cols="3">
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
  <li>7</li>
  <li>8</li>
  <li>9</li>
  <li>10</li>
</ul>

jQuery

$('.split-list').each(function() {
  var splitCols = $(this).data('cols'),
      itemPerCol = [],
      $item = $(this).find('li'),
      minItemsPerCol = Math.floor( $item.length / splitCols ),
      diff = $item.length - (minItemsPerCol * splitCols);
  for ( var i = 0; i < splitCols; i++ ) {
    if ( i < diff ) {
      itemPerCol[i] = minItemsPerCol + 1;
    } else {
      itemPerCol[i] = minItemsPerCol;
    }

    $(this).append('<ul class="child-list"></ul>');
    for ( var j = 0; j < itemPerCol[i]; j++ ) {
      var pointer = 0;
      for ( var k = 0; k < i; k++ ) {
        pointer += itemPerCol[k];
      }
      $(this).find('.child-list').last().append($item[j + pointer]);
    }
  }
  $(this).replaceWith('<div class="split-list">' + $(this).html() + '</div>');
});

今回のサンプルではulを利用していますが、少し記述を変更すればolはもちろん、他の要素でも使用可能です。

目次へ

2. data属性を利用したシンプルなフィルタ機能

4. classを利用したシンプルなフィルタ機能 - jQuery Snippets #5」で紹介した動きをdata属性を用いて実装したもので、HTMLとjQueryをそれぞれ下記のように記述します。

HTML

<div class="filter-nav">
  <button data-type="all">all</button>
  <button data-type="foo">foo</button>
  <button data-type="bar">bar</button>
  <button data-type="baz">baz</button>
</div>
<div class="filter-item">
  <div data-type="foo">foo</div>
  <div data-type="bar">bar</div>
  <div data-type="baz">baz</div>
  <div data-type="foo">foo</div>
  <div data-type="bar">bar</div>
  <div data-type="baz">baz</div>
  <div data-type="bar">bar</div>
  <div data-type="baz">baz</div>
  <div data-type="foo">foo</div>
  <div data-type="foo">foo</div>
  <div data-type="bar">bar</div>
  <div data-type="foo">foo</div>
</div>

jQuery

$('.filter-nav button').on('click', function() {
  var type = $(this).data('type');
  if ( type == 'all' ) {
    $('.filter-item > div').show();
  } else {
    $('.filter-item > div').hide().filter('[data-type="' + type + '"]').show();
  }
});

目次へ

3. 1度だけ実行させる

例えば.on()を利用したイベントが用意されていたとして、特定のタイミングでそれを実行されないようにしたいというときは.off()を利用することで実装できますが、1度だけ実行できる(1回実行されたらその後は実行されたくない)ようにということであれば、下記のように.one()を用いる形で実装できます。

jQuery

$('button').one('click', function() {
  console.log('hello world');
});

目次へ

4. 本来の画像サイズを取得

要素のサイズを取得したいときによく利用するのが.width().height()ですが、これらを利用して画像サイズを取得しようとした場合は現在表示されているサイズの値が取得されるので、例えばその画像がCSSなどで拡大・縮小などされている場合はその値が取得されます。
そうではなく、何らかの理由で本来の画像サイズを取得したいというときは下記の方法で取得できます。

jQuery

var nativeImage = new Image();
nativeImage.src = $('img').attr('src');
var imageNativeWidth = nativeImage.width,
    imageNativeHeight = nativeImage.height;
console.log('native width:' + imageNativeWidth + ', native height:' + imageNativeHeight);

目次へ

5. 特定の要素が何番目かを取得する

何らかのタイミングで要素が何番目かを取得したいときに使える方法です。
下記はクリックしたli要素が何番目かを取得するというもので、且つ単純に取得した場合は0から始まるのをわかりやすくするために取得した値に1をプラスしています。

jQuery

$('ul li').on('click', function() {
	var index = $(this).index() + 1;
	console.log(index);
});

目次へ

6. 特定の文字列を置換する

指定した要素内にある特定の文字列を.replace()を使って任意の文字列に置換する方法で、赤文字で表示しているbeforeの部分に記述した文字列が、同じく赤文字で表示しているafterの部分に記述した文字列に置換されます。
また、afterの部分を空にすれば特定の文字列を削除するという動きにもできます。

jQuery

$('selector').each(function() {
  $(this).html($(this).html().replace(/before/g, 'after'));
});

URL文字列にリンクを設定する

同じく.replace()を使って下記のように記述することで、指定した要素内にURL文字列があった場合にリンクを設定させることができ、このサンプルコードの場合はtarget="_blank"付きのリンクが設定されます。

jQuery

$('selector').each(function() {
  $(this).html($(this).html().replace(/((http|https|ftp):\/\/[\w?=&.\/-;#~%-]+(?![\w\s?&.\/;#~%"=-]*>))/g, '<a href="$1" target="_blank">$1</a>'));
});

目次へ

7. フラグ判定

例えば、ボタン押下で処理を行う場合にボタンはひとつでも条件によって処理を変えたいときがあります。
やり方はいろいろあるとは思いますが、そういったときに使えるフラグ判定方法を3パターン紹介します。

※ここで紹介しているのは、いずれも先ほど例にあげたようにボタン押下時とフラグ判定を組み合わせたものになります。

7-1. フラグ判定(true/false)

あらかじめ用意したフラグがtruefalseを判断して処理をわけるというものなり、このサンプルコードの場合は、1行目にあるflagがフラグ判定に使用する変数で、初期値はtrueと設定しています。
あとは、ボタンが押下された際に条件分岐を使用してフラグがtruefalseかでそれぞれ別の処理を書くことで、同じボタンをクリックした場合でも条件によって異なる処理が実行されるようになります。
また、今回はボタン押下の度に異なる処理を行う必要があるので、条件分岐内のflag = false;flag = true;といった部分でボタンが押下される度に現在のフラグを書き換えるようにしておきます。

jQuery

var flag = true;
$('button').on('click', function() {
  if ( flag ) {
    console.log('flag true');
    flag = false;
  } else {
    console.log('flag false');
    flag = true;
  }
});

7-2. フラグ判定(要素の表示・非表示)

こちらは特定の要素が表示されているかどうかで判断して処理をわけるというものなり、このサンプルコードの場合は、特定の要素として用意した$flagElementsが表示されている(display: block;)ならtrue、逆に非表示(display: none;)であればfalseとなります。

jQuery

var $flagElements = $('selector');
$('button').on('click', function() {
  if ( $flagElements.css('display') == 'block' ) {
    console.log('flag true');
    $flagElements.hide();
  } else {
    console.log('flag false');
    $flagElements.show();
  }
});

7-3. フラグ判定(classの有無)

こちらは.hasClass()を使って特定の要素に特定のclassが付いているかで判断して処理をわけるというものなります。
このサンプルコードの場合は、特定の要素をbutton要素で特定のclassが.is-trueとし、button要素に.is-trueが付与されていればtrue、付与されていなければfalseとなります。

jQuery

var flagClass = 'is-true';
$('button').on('click', function() {
  if ( $(this).hasClass(flagClass) ) {
    console.log('flag true');
    $(this).removeClass(flagClass);
  } else {
    console.log('flag false');
    $(this).addClass(flagClass);
  }
});

目次へ

8. 現在地によってページ内ナビゲーションにclassを追加・削除する

特に長いページなどで各セクションへ容易に移動できるようなナビゲーションを設置することがありますが、そのようなナビゲーションに現在どのセクションにいるかをわかりやすく装飾を付ける動きを実装する方法です。
具体的には現在地によって特定のナビゲーションにclassの追加・削除を行い、そのclassに対してCSSを指定しておくことで、例えば現在見ている部分に対応しているナビゲーションのみカラーが変わるなどの動きを実装できます。

HTML

<nav>
  <ul>
    <li><a href="#section01">section 01</a></li>
    <li><a href="#section02">section 02</a></li>
    <li><a href="#section03">section 03</a></li>
    <li><a href="#section04">section 04</a></li>
    <li><a href="#section05">section 05</a></li>
  </ul>
</nav>

<section id="section01"> ... </section>
<section id="section02"> ... </section>
<section id="section03"> ... </section>
<section id="section04"> ... </section>
<section id="section05"> ... </section>

jQuery

$(function() {
  var $win = $(window),
      sectionArr = [],
      $section = $('section'),
      $nav = $('nav ul li'),
      currentClass = 'is-current';

  $section.each(function(i) {
    var sectionTop = $(this).offset().top,
        sectionBottom = $(this).offset().top + $(this).outerHeight() - 1;
    sectionArr[i] = [sectionTop, sectionBottom];
  });

  function currentPosition() {
    var value = $win.scrollTop(),
        adjustOffset = 0;
    for ( var i = 0; i < sectionArr.length; i++ ) {
      if ( sectionArr[i][0] - adjustOffset <= value && sectionArr[i][1] - adjustOffset >= value ) {
        $nav.removeClass(currentClass);
        $nav.eq(i).addClass(currentClass);
        break;
      }
    };
  }

  $win.on('load scroll', function() {
    currentPosition();
  });
});

このサンプルコードの場合は、現在表示されているナビゲーション(li要素)に.is-currentというclassが付与される動きになっているので、それを利用してスタイルを指定することで現在表示されているのがどこなのかわかりやすくすることができます。
また、classが付与されるタイミングはadjustOffsetという変数部分に任意で数値を指定することで調整でき、例えばadjustOffset = 200;と指定すれば各セクションのトップから200px分早くclassの追加・削除される動きになります。

目次へ

9. 要素をアルファベット順でソートする

例えば下記のようなHTMLがあったとして...。

HTML

<ul>
  <li>a</li>
  <li>x</li>
  <li>c</li>
  <li>b</li>
  <li>y</li>
  <li>z</li>
</ul>

単純にHTMLを表示した場合は上から順に「a → x → c → b → y → z」と表示されますが、これを要素内のテキストを判別・ソートして「a → b → c → x → y → z」のようにアルファベット順にして出力させる方法です。

jQuery

$('ul li').sort(function(a, b) {
  return $(a).text() > $(b).text();
}).appendTo('ul');

上記は昇順指定となるので、降順指定にしたい場合はreturn $(a).text() < $(b).text();とします。

また、大文字小文字関係なくソートする場合は下記のように.toLowerCase()を組み合わせます。

jQuery

$('ul li').sort(function(a, b) {
  return $(a).text().toLowerCase() > $(b).text().toLowerCase();
}).appendTo('ul');

こちらも同じく上記は昇順指定となるので、降順指定にしたい場合はreturn $(a).text().toLowerCase() < $(b).text().toLowerCase();とします。

目次へ

10. 要素の数字でソートする

こちらは数字の大きさでソートするもので、下記サンプルコードの場合は「0 → 1 → 2 → 5 → 10 → 100」と出力されます。

HTML

<ol>
  <li>100</li>
  <li>10</li>
  <li>2</li>
  <li>0</li>
  <li>1</li>
  <li>5</li>
</ol>

jQuery

$('ol li').sort(function(a, b) {
  return $(a).text() - $(b).text();
}).appendTo('ol');

上記は昇順指定となるので、降順指定にしたい場合はreturn $(b).text() - $(a).text();とします。

目次へ


上記以外のjQuery Snippetsに関しては下記ページにまとめているので、興味ある方はこちらもご覧ください。

Close the search window,
please press close button or esc key.