フィルターの開発 - paulbarre/RssReader GitHub Wiki
ページのレイアウトを準備した際に、フィルターを入力するためtext
のinput
を記述しています。
このinput
にキーワードを入力すると、フィルター処理を開始します。
ボタンのクリックと同じように、インプット用のイベントがあるので、このイベントを利用するために、input
タグにid
を設定しましょう。
<footer>
<input id="feed-filter" type="text" placeholder="検索する...">
</footer>
イベントの設定はmain.js
の関数で行います。
$(document).ready(function () {
...
$('#feed-filter').on('input', function () {
var word = $(this).val();
console.log('-- フィルター: ' + word);
});
});
input
というイベントを実装すると、テキストが変更されるタイミングでコールバックが呼ばれます。
コールバックが呼ばれ、入力したキーワードを読み込んでフィルターを実行します。
feed.js
に新しい関数を実装します。
function filterFeed(word) {
if (word.length >= 2) {
// フィルターを実行する
} else {
// フィルターをリセットする
}
}
このフィルターでは、2文字以上入力されたらフィルター処理を行います。
フィルターによって入力したキーワードを一覧から検索し、キーワードに一致しないアイテムは非表示にします。
function filterFeed(word) {
if (word.length >= 2) {
$('article').each(function () {
var title = $(this).find('.article-title').text();
var description = $(this).find('.article-description').text();
});
} else {
}
}
上記の処理によって各アイテムのタイトルと概要をtitle
とdescription
という変数にセットします。
title
とdescription
がstring型なので、文字列の中に存在する該当のキーワードを検索するために、indexOf
という関数を使います。
例:
var hello_world = 'Hello world!';
var index = hello_world.indexOf('world');
上記のソースコードを実行してみると、index
が6
になります。6
はhellow_world
にあるworld
の位置です。H
は0
、e
は1
、空白は5
、w
は6
となります。
var index = hello_world.indexOf('ward');
上記のソースコードではindex
が-1
になります。ward
というstringがhello_word
に存在しないので、存在しない場合は-1
を返します。
フィードのフィルターについても、タイトルと概要からキーワードを検索する方法と同様のやり方で行います。
function filterFeed(word) {
if (word.length >= 2) {
$('article').each(function () {
var title = $(this).find('.article-title').text();
var titleHasWord = title.indexOf(word) >= 0;
var description = $(this).find('.article-description').text();
var descriptionHasWord = description.indexOf(word) >= 0;
});
} else {
}
}
タイトルにフィルターしたいキーワードがあれば、titleHasWord
がtrue
になり、概要にあればdescriptionHasWord
がtrue
になります。どちらかがtrue
であればアイテムが表示され、どちらもfalse
であればアイテムを隠します。
function filterFeed(word) {
if (word.length >= 2) {
$('article').each(function () {
var title = $(this).find('.article-title').text().toLowerCase();
var titleHasWord = title.indexOf(word.toLowerCase()) >= 0;
var description = $(this).find('.article-description').text().toLowerCase();
var descriptionHasWord = description.indexOf(word.toLowerCase()) >= 0;
if (titleHasWord || descriptionHasWord) {
// 表示します
} else {
// 隠します
}
});
} else {
// 全てのアイテムを普通に表示します
}
}
アイテムを非表示にするためにCSSを使います。css
フォルダーにmain.css
というファイルを作成します。
index.html
のヘッダーにリンクを設定します。
<head>
<meta charset="UTF-8">
<title>Rss Reader</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
...
</head>
main.css
では下記を追記します:
.hidden {
display: none;
}
上記のCSSは「hidden
というクラスを使っている項目を非表示にします。
次に隠したいフィードのアイテムにhidden
のクラスを付け、feed.js
にフィルターを実装します。
function filterFeed(word) {
if (word.length >= 2) {
$('article').each(function () {
var title = $(this).find('.article-title').text().toLowerCase();
var titleHasWord = title.indexOf(word.toLowerCase()) >= 0;
var description = $(this).find('.article-description').text().toLowerCase();
var descriptionHasWord = description.indexOf(word.toLowerCase()) >= 0;
if (titleHasWord || descriptionHasWord) {
$(this).removeClass('hidden');
} else {
$(this).addClass('hidden');
}
});
} else {
$('article').removeClass('hidden');
}
}
jQueryではクラスを付けるためにaddClass
を使います。削除する場合はremoveClass
を使います。
最後にmain.js
に戻り、フィルターを呼び出しましょう。
$(document).ready(function () {
...
$('#feed-filter').on('input', function () {
var word = $(this).val();
filterFeed(word);
});
});
ブラウザーで、ページを更新し、フィードをダウンロードしてからフィルターを試してください。
チュートリアルで使うはてなのRSSフィードを使う限りは気づかないかもしれませんが、英語のフィードを使うとバグが発生します。
確認のため、TechCrunchさんのフィードをつかってみましょう:
http://feeds.feedburner.com/crunchgear
このフィードを登録し、ダウンロードします。大文字と小文字、どちらも使う言葉をフィードの中にピックアップします。例:World
。
開発したフィルターのインプットにはWorld
ではなく、world
を入力しましょう。World
を使っているアイテムまで非表示になってしまいます。
理由はindexOf
は大文字と小文字を区別するためです。この対応を行うため、toLowerCase
というメソッドを使用します。このメソッドはstringの全ての文字を小文字にします。
下記のソースコードを実行してみてください。
var hello_world = 'Hello world!';
var index;
// 0
index = hello_world.indexOf('Hello');
// -1
index = hello_world.indexOf('hello');
// 0
index = hello_world.toLowerCase().indexOf('hello');
// 6
index = hello_world.indexOf('world');
// -1
index = hello_world.indexOf('World');
// 6
index = hello_world.indexOf('World'.toLowerCase());
場合によっては、検索するキーワードとターゲットのキーワードの両方にtoLowerCase
を付けます。
index = hello_world.toLowerCase().indexOf('World'.toLowerCase());
フィルターにこの対応を追加します。
function filterFeed(word) {
if (word.length >= 2) {
$('article').each(function () {
var title = $(this).find('.article-title').text().toLowerCase();
var titleHasWord = title.indexOf(word.toLowerCase()) >= 0;
var description = $(this).find('.article-description').text().toLowerCase();
var descriptionHasWord = description.indexOf(word.toLowerCase()) >= 0;
if (titleHasWord || descriptionHasWord) {
$(this).removeClass('hidden');
} else {
$(this).addClass('hidden');
}
});
} else {
$('article').removeClass('hidden');
}
}
もう一度英語のフィードをダウンロードして確認してみてください。