お気に入りの開発 - paulbarre/RssReader GitHub Wiki

これまでははてなのRSSを使っていましたが、別のフィードをダウンロードできるようにするため、お気に入りにフィードを追加する機能を実装します。

jsフォルダーの中にfavorite.jsという新しいファイルを追加します。

開発の流れ下記のようになります。

  1. お気に入りの登録
  2. フィード情報の取得
  3. HTMLで入力準備
  4. メニューの開発
  5. メニューからのダウンロード
  6. お気に入りの削除

お気に入りの登録

保存のため、favorite.jsでは下記の関数を実装します。

function addFavorite(favorite) {

    var favorites = loadStorage('favorites');
    favorites.push(favorite);
    saveStorage('favorites', favorites);
}

流れはこのようになります:

  1. ストレージにあるデータを読み込む
  2. 配列に新しいお気に入りを追加する(push
  3. 変更された配列を保存する

フィードの保存についてはこれだけで問題ありません。

フィード情報の取得

前のレッスンでフィードのXML構造からアイテムの部分しか使っていませんでしたが、同じXMLドキュメントからフィードの情報を読み込みます。

<channel>
    <title>フィード名</title>
    <link>フィードのウエブサイト</link>
    <description>フィードの説明</description>
    
    ...
</channel>

新しいRSSフィードを登録する時に、フィードのURLを登録しますが、上記の情報も一緒に保存します。

フィードをダウンロードする時と同じように、Ajaxのリクエストを送り、取得した情報を読み込みます。

favorite.jsに下記の関数を実装します。

function registerFavorite(url) {

    download(url, function (xmlData) {

        // こちらでは情報を読み込む
    });
}

フィードのダウンロードと同じようにapi.jsにあるdownloadメソッドを呼び出します。今回は別のスクリプトのメソッドではなく、コールバックを引数として渡します。

function registerFavorite(url) {

    download(url, function (xmlData) {

        var title = $(xmlData).find('title:first').text();
        var link = $(xmlData).find('link:first').text();
        var description = $(xmlData).find('description:first').text();
        
        console.log('-- 登録: ' + url);
        console.log('title: ' + title);
        console.log('link: ' + link);
        console.log('description: ' + description);
        
    });
}

フィードのアイテムとタグは同じな名前(titlelinkdescription)ですので、title:firstfindメソッドに入れたら、XMLの最初のタグだけを読み込みます。

読み込んだ情報から、新しいお気に入りのオブジェクトを作ります。

function registerFavorite(url) {

    download(url, function (xmlData) {

        var favorite = {
            url: url,
            title: $(xmlData).find('title:first').text(),
            link: $(xmlData).find('link:first').text(),
            description: $(xmlData).find('description:first').text()
        };
        
        console.log('-- 登録: ' + favorite.url);
        console.log('title: ' + favorite.title);
        console.log('link: ' + favorite.link);
        console.log('description: ' + favorite.description);
        
    });
}

favoriteのオブジェクトの生成はこれで完了です。

addFavoriteを呼ぶことで登録が行えます。

function registerFavorite(url) {

    download(url, function (xmlData) {

        var favorite = {
            ...
        };
        
        ...
        
        addFavorite(favorite);
    });
}

動作を確認するため、main.jsregisterFavoriteをテストしてみます。

$(document).ready(function () {
    var feed_url = 'http://feeds.feedburner.com/hatena/b/hotentry';
    
    ...
    
    registerFavorite(feed_url);
});

ブラウザーのページを更新し、ストレージに登録されているか確認してください。

HTMLで入力準備

毎回ページを更新するのではなく、HTMLのボタンを押すタイミングでフイードに登録できるようにします。

下記のHTMLをindex.htmlに追加します。

<article>
    <h3>気に入り</h3>

    ...

    <form id="add-favorite-form">
        <input name="add-favorite-url" type="text" placeholder="URL">
        <input name="add-favorite-btn" type="submit" value="登録">
    </form>
</article>

textinputに好きなURLを入力し、登録ボタンで保存します。

HTMLのformタグではonsubmitのプロパティを使えますが、今回はjQueryで管理します。

main.jsにある関数を編集します。

$(document).ready(function () {
    
    $('#add-favorite-form').on('submit', function (event) {
        
        event.preventDefault();
    });
});

追加したフォームにidを付けておけば、jQueryの場合、$('#add-favorite-form')でアクセスができます。

あとは、フォームでサブミットする際にURLを保存したいので、submitのコールバックを定義します。フォームのアクションが先に行われるのを防ぐため、event.preventDefault()を呼び出します。

このコールバックの中で、ユーザーが入力したURLを取得します。今回はinputnameでアクセスします。

$('#add-favorite-form').on('submit', function (event) {
    
    event.preventDefault();
    var url = $(this).find('input[name="add-favorite-url"]').val();
});

submitのコールバックはフォームに設定していますので、$(this)がフォームになります。

find()メソッドで、formタグ配下のadd-favorite-urlという名前のinputタグを検索します。

textinputに入力されたテキストはval()メソッドでアクセスできます。

URLの取得ができたので、上記で実装したregisterFavorite関数を呼び出します。

$('#add-favorite-form').on('submit', function (event) {
    
    event.preventDefault();
    var url = $(this).find('input[name="add-favorite-url"]').val();
    registerFavorite(url);
});

ブラウザーのページを更新し、URLを入力してから、登録ボタンを押して確認してください。

メニューの開発

URLの登録と読み込みができたので、次はメニューにあるお気に入りのサブメニューを開発しましょう。

まずfavorite.jsにHTMLに表示する関数を追加します。

function displayFavorites() {
}

前のレッスンで作ったダミーのHTMLを参考して、各リンクのHTMLを作ります。

リストのタグにidを付けます。

<ul id="favorites-list">
    <li>フィード1<button>ダウンロード</button></li>
</ul>
function displayFavorites() {
    
    $('#favorites-list').html('');
    
    var favorites = loadStorage('favorites');
    $.each(favorites, function (i, favorite) {

        var html = '<li>' + favorite.title + '</li>';
        $('#favorites-list').append(html);
    });
}

リストをクリアしてから、各お気に入りを追加します。

ブラウザーでページを更新する際に、自動的でお気に入りのリストを見れるようにするために、main.jsの関数に下記を追加します:

$(document).ready(function () {
    ...

    displayFavorites();
});

ブラウザーで実行し、確認してください。

メニューからのダウンロード

お気に入りのリストがページに表示されますが、このままだと利用できません。ダウンロードボタンを押すことで、一覧を更新できるようにするための機能を開発します。

まずボタンをクリックした際のイベントを設定します。displayFavoritesの関数に、下記のソースコードを追加します。

function displayFavorites() {
    
    $.each(favorites, function (i, favorite) {
    
        var html = 
            '<li>' + favorite.title + 
            '<button class="download-btn">ダウンロード</button>' +
            '</li>';
        $('#favorites-list').append(html);
    });
    
    $('.download-btn').on('click', function () {
        // ここでダウンロードを呼ぶ
    });
}

イベントを設定するために、download-btnのクラスでボタンを実装します。そうすることで、ページの全てのボタンではなく、このボタンだけにこのイベントを設定できます。

上記でコメントを書いている箇所で、お気に入りのダウンロードを行いたいのですが、このままではお気に入りのURLがわかりません。

URLを取得するために、HTMLタグのdataプロパテイーを使います。displayFavoritesでHTMLを作る箇所を編集します。

...

$.each(favorites, function (i, favorite) {

    var html =
        '<li>' + favorite.title + 
        '<button class="download-btn" data-url="' + favorite.url + '">ダウンロード</button>' +
        '</li>';
    $('#favorites-list').append(html);
});

...

さきほど作ったイベントでは、このdata-urlを読み込みます。

...

$('.download-btn').on('click', function () {
    
    var url = $(this).data('url');
});

...

また、このメソッドはイベントのコールバックですので、$(this)がイベントのオブジェクトのボタンになります。data()メソッドで設定したdata-urlを読み込みます。

最後に、downloadの関数を呼ぶとフィードをダウンロードします。

...

$('.download-btn').on('click', function () {
    
    var url = $(this).data('url');
    download(url, displayFeedResults);
});

...

ブラウザーで確認しましょう。

お気に入りの削除

登録したフィードを削除する機能を実装します。

ユーザーが削除するためのUIを追加しましょう。メニューにあるお気に入りのダウンロードボタンのとなりに削除用のボタンを追加します。

function displayFavorites() {

    ...
    
    $.each(favorites, function (i, favorite) {

        var html = 
            '<li>' + favorite.title + 
            '<button class="download-btn" data-url="' + favorite.url + '">ダウンロード</button>' +
            '<button class="delete-favorite-btn" data-url="' + favorite.url + '">削除</button>' +
            '</li>';
        $('#favorites-list').append(html);
    });

    ...
}

削除ボタンにはdelete-favorite-btnというクラスを付けてください。あとはダウンロードと同じように、クリックイベントを設定します。

function displayFavorites() {

    ...
    
    $.each(favorites, function (i, favorite) {
        ...
    });

    ...

    $('.delete-favorite-btn').on('click', function () {

        var url = $(this).data('url');
        deleteFavorite(url);
        displayFavorites();
    });
}

ボタンをクリックする時に、ボタンのデータにあるURLを読み込んで、deleteFavoriteメソッドを呼び出し、メニューを更新するという流れになります。

同ファイルに、実際に削除するメソッドを実装します。

function deleteFavorite(url) {

    var favorites = loadStorage('favorites');
    favorites = favorites.filter(function (favorite) {
        
    });
    saveStorage('favorites', favorites);
}

ストレージからお気に入りの配列を読み込んでから、配列の中で削除したいURLを見つけるためにjQueryのfilterメソッドを使います。

filterには変数ではなく、コールバックを渡します。配列にある全てのアイテムで、このコールバックが呼ばれるようになります。コールバックの 戻り値はブーリアンになります。trueの場合、引数が配列に残ります。falseなら、配列から引数を削除します。

お気に入りのフィルターを開発しましょう。

function deleteFavorite(url) {

    ...
    favorites = favorites.filter(function (favorite) {
        return favorite.url != url;
    });
    ...
}

配列の全てのURLを確認して、削除したいURLならfalseを設定します。

これでお気に入りの機能の開発は完了です。 ブラウザーでお気に入りの登録と削除機能を確認してみてください。

⚠️ **GitHub.com Fallback** ⚠️