monaca「RSSリーダー」アプリに記事画像も表示したい。
「monaca」と「nifty mobile backend」を使って、RSSリーダーアプリを作成しています。
monacaのドキュメントにあるサンプルアプリ『RSSリーダー』を参考にして作っているのですが、記事元の画像(WordPressで言うところのアイキャッチ画像)も表示したいと思っています。
ドキュメントは「タイトル・日付・概要文」のみの取得・表示となっており、画像の取得表示方法を自分でも時間をかけて色々と調べてやってみたのですが画像の取得も表示する事も出来ないでいます。
何卒宜しくお願い致します。
※RSSの記事元はWordPressで作られたサイト(ブログ)となります。
【補足1】
質問内容が不足しており申し訳御座いません。
下記に補足させて頂きます。
▼RSSを処理するjsコードです。
Feed.prototype.createListElement = function(item) {
var $item = $(item);
var link = this.escape($item.find('link').text());
var title = this.escape($item.find('title').text());
var description = this.escape(strip_tags($item.find('description').text()));
var date = new Date($item.find('pubDate').text());
return '<li class="feed-item" data-link="' + link + '">' +
'<time>' + date.getFullYear() + '/' + (date.getMonth() + 1) + '/' + date.getDate() + '</time>' +
'<h2>' + title + '</h2><p>' + description +'</p></li>';
};
Feed.prototype.escape = function(string) {
return htmlspecialchars(string, 'ENT_QUOTES');
};
return Feed;})();
▼取得先のRSSのコードです。(コードは記事の画像URLを表示している箇所のみを貼り付けます)
<guid isPermaLink="false">http://samplesiteurl.com/?p=9963</guid>
<description><![CDATA[<div><img width="350" height="233" src="http://samplesiteurl.com/wp-content/uploads/2016/09/kiji_app-1-350x233.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="アイキャッチ画像" srcset="http://samplesiteurl.com/wp-content/uploads/2016/09/kiji_app-1-350x233.png 350w, http://samplesiteurl.com/wp-content/uploads/2016/09/kiji_app-1-596x397.png 596w, http://samplesiteurl.com/wp-content/uploads/2016/09/kiji_app-1.png 600w" sizes="(max-width: 350px) 100vw, 350px" /></div>
この中にある、
http://samplesiteurl.com/wp-content/uploads/2016/09/kiji_app-1-350x233.png
の画像URLを取得して表示したいと思い調べています。
html側は、
<ul id="feed-list"></ul>
でリスト形式で表示を行います。
タイトルや概要文と同様に、「var image = ...」などで取得して、
return箇所に「」として表示出来ないか試行錯誤しています。
尚、現状は「記事タイトル・記事URL・概要文・日付」の情報は問題なく取得表示出来ております。
【補足2】
sujoyu様、ご回答頂き誠にありがとうございます。
なるほど、CDATAはそのようにして取得することが出来るのですね。大変勉強になります。
早速教えて頂いたコードをもとにトライしてみたのですが、まだ画像が取得(表示)できない状態です。
(勉強不足で大変申し訳ないです)
▼修正後の現在のコードです。
Feed.prototype.createListElement = function(item) {
var $item = $(item);
var link = this.escape($item.find('link').text());
var title = this.escape($item.find('title').text());
var description = this.escape(strip_tags($item.find('description').text()));
var date = new Date($item.find('pubDate').text());
// アイキャッチ画像取得
var imageUrl = $($item.find('description').text()).find('img').attr('src');
return '<li class="feed-item" data-link="' + link + '">' +
'<img src="' + imageUrl +'" ' + 'width="100" height="100"' + '>' +
'<br>' +
'<time>' + date.getFullYear() + '/' + (date.getMonth() + 1) + '/' + date.getDate() + '</time>' +
'<h2>' + title + '</h2><p>' + description +'</p></li>';
};
Feed.prototype.escape = function(string) {
return htmlspecialchars(string, 'ENT_QUOTES');
};
return Feed;
})();
▼こちらが現在のjsファイル全文となります。(feed-reader.js)
/**
* Feed class
*/
var Feed = (function() {
var Feed = function(options) {
// URL for RSS
this.url = '';
//Mask element
this.maskEl = "#mask";
//Error message element
this.errorEl = "#error-message";
//List container
this.listEl = "#feed-list";
if (options) {
$.extend(this, options);
}
this.addClickHandler();
};
/**
* Fetch RSS and display the contents of it
*/
Feed.prototype.load = function() {
var self = this;
$(this.maskEl).show();
$(this.errorEl).text('');
$.ajax({
url: this.url,
dataType: 'text',
crossDomain: true,
success: function(data) {
data = $.parseXML(data.trim());
$(self.listEl).empty();
// Display RSS contents
var $rss = $(data);
$rss.find('item').each(function() {
var item = this;
$(self.listEl).append(self.createListElement(item));
});
},
error: function() {
$(self.errorEl).text('Failed to load RSS.');
},
complete: function() {
$(self.maskEl).hide();
}
});
};
Feed.prototype.addClickHandler = function() {
$(this.listEl).on('click', 'li', function() {
var url = $(this).data('link');
if (/^http/.test(url)) {
var ref = window.open(url, '_blank', 'location=yes');
ref.addEventListener("exit", function() {});
} else {
alert('Invalid URL.');
}
});
};
/**
* Create list element
* @param Array item
* @returns DOMElement
*/
Feed.prototype.createListElement = function(item) {
var $item = $(item);
var link = this.escape($item.find('link').text());
var title = this.escape($item.find('title').text());
var description = this.escape(strip_tags($item.find('description').text()));
var date = new Date($item.find('pubDate').text());
// アイキャッチ画像取得
//var imageUrl = $($item.find('description').text()).find('img').attr('src');
return '<li class="feed-item" data-link="' + link + '">' +
//'<img src="' + imageUrl +'" ' + 'width="100" height="100"' + '>' +
//'<br>' +
'<time>' + date.getFullYear() + '/' + (date.getMonth() + 1) + '/' + date.getDate() + '</time>' +
'<h2>' + title + '</h2><p>' + description +'</p></li>';
};
Feed.prototype.escape = function(string) {
return htmlspecialchars(string, 'ENT_QUOTES');
};
return Feed;
})();
/**
* htmlspecialchars
*
* @see http://phpjs.org/
*/
function htmlspecialchars(string, quote_style, charset, double_encode) {
// http://kevin.vanzonneveld.net
// + original by: Mirek Slugen
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + bugfixed by: Nathan
// + bugfixed by: Arno
// + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + bugfixed by: Brett Zamir (http://brett-zamir.me)
// + input by: Ratheous
// + input by: Mailfaker (http://www.weedem.fr/)
// + reimplemented by: Brett Zamir (http://brett-zamir.me)
// + input by: felix
// + bugfixed by: Brett Zamir (http://brett-zamir.me)
// % note 1: charset argument not supported
// * example 1: htmlspecialchars("<a href='test'>Test</a>", 'ENT_QUOTES');
// * returns 1: '<a href='test'>Test</a>'
// * example 2: htmlspecialchars("ab\"c'd", ['ENT_NOQUOTES', 'ENT_QUOTES']);
// * returns 2: 'ab"c'd'
// * example 3: htmlspecialchars("my "&entity;" is still here", null, null, false);
// * returns 3: 'my "&entity;" is still here'
var optTemp = 0,
i = 0,
noquotes = false;
if (typeof quote_style === 'undefined' || quote_style === null) {
quote_style = 2;
}
string = string.toString();
if (double_encode !== false) { // Put this first to avoid double-encoding
string = string.replace(/&/g, '&');
}
string = string.replace(/</g, '<').replace(/>/g, '>');
var OPTS = {
'ENT_NOQUOTES': 0,
'ENT_HTML_QUOTE_SINGLE': 1,
'ENT_HTML_QUOTE_DOUBLE': 2,
'ENT_COMPAT': 2,
'ENT_QUOTES': 3,
'ENT_IGNORE': 4
};
if (quote_style === 0) {
noquotes = true;
}
if (typeof quote_style !== 'number') { // Allow for a single string or an array of string flags
quote_style = [].concat(quote_style);
for (i = 0; i < quote_style.length; i++) {
// Resolve string input to bitwise e.g. 'ENT_IGNORE' becomes 4
if (OPTS[quote_style[i]] === 0) {
noquotes = true;
} else if (OPTS[quote_style[i]]) {
optTemp = optTemp | OPTS[quote_style[i]];
}
}
quote_style = optTemp;
}
if (quote_style & OPTS.ENT_HTML_QUOTE_SINGLE) {
string = string.replace(/'/g, ''');
}
if (!noquotes) {
string = string.replace(/"/g, '"');
}
return string;
}
/**
* strip_tags
*
* @see http://phpjs.org/
*/
function strip_tags(input, allowed) {
// http://kevin.vanzonneveld.net
// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: Luke Godfrey
// + input by: Pul
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + bugfixed by: Onno Marsman
// + input by: Alex
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + input by: Marc Palau
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + input by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + bugfixed by: Eric Nagel
// + input by: Bobby Drake
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + bugfixed by: Tomasz Wesolowski
// + input by: Evertjan Garretsen
// + revised by: Rafał Kukawski (http://blog.kukawski.pl/)
// * example 1: strip_tags('<p>Kevin</p> <br /><b>van</b> <i>Zonneveld</i>', '<i><b>');
// * returns 1: 'Kevin <b>van</b> <i>Zonneveld</i>'
// * example 2: strip_tags('<p>Kevin <img src="someimage.png" onmouseover="someFunction()">van <i>Zonneveld</i></p>', '<p>');
// * returns 2: '<p>Kevin van Zonneveld</p>'
// * example 3: strip_tags("<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>", "<a>");
// * returns 3: '<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>'
// * example 4: strip_tags('1 < 5 5 > 1');
// * returns 4: '1 < 5 5 > 1'
// * example 5: strip_tags('1 <br/> 1');
// * returns 5: '1 1'
// * example 6: strip_tags('1 <br/> 1', '<br>');
// * returns 6: '1 1'
// * example 7: strip_tags('1 <br/> 1', '<br><br/>');
// * returns 7: '1 <br/> 1'
allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
return input.replace(commentsAndPhpTags, '').replace(tags, function($0, $1) {
return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
});
}
▼現在のHTMLファイル全文です。(index.html)
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta http-equiv="Content-Security-Policy" content="default-src * data:; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'">
<script src="components/loader.js"></script>
<link rel="stylesheet" href="components/loader.css">
<script src="js/feed-reader.js"></script>
<link rel="stylesheet" href="css/style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
var feedUrl = "http://samplesiteurl.com/feed/";
$(function() {
var feed = new Feed({
url: feedUrl
});
if (monaca.isIOS) {
$('.toolbar').css('margin-top', '20px');
$('.button').css('top', '20px');
}
$('.button').click(function() {
console.log('Reload.');
feed.load();
});
feed.load();
});
</script>
</head>
<body>
<div class="toolbar">
<h2>ブログRSS</h2>
<div class="button">更新</div>
</div>
<div id="mask">
<div id="loading"><img src="loading.gif"></div>
</div>
<ul id="feed-list"></ul>
<p id="error-message"></p>
</body>
</html>
もし宜しければご意見を頂けませんでしょうか。
何卒宜しくお願い致します。