JSが動いてないことに気づく
目次
経緯
いつの頃からかYouTubeなどの動画埋め込みの自動再生がされなくなっていた。
恐らくhexo-tag-owlを再インストールしたからだなと。
てことで、もう一度改修する。
要件
まずは改修する要件を明確にする。
- youtube埋め込みコードの自動生成
- niconico埋め込みコードの自動生成
- dailymotion埋め込みコードの自動生成
- imdbの映画情報タグの自動生成
以上の改修をhexo-tag-owlに対して行う。
そしてさらにyoutube、niconico、dailymotionのエレメントに
jqueryのinviewイベントをトリガーに自動再生を行う。
modified file list
- hexo-tag-owl/lib/tag/index.js
- hexo-tag-owl/lib/tag/images/imdb.js1
- hexo-tag-owl/lib/tag/videos/niconico.js
- hexo-tag-owl/lib/tag/videos/nicovideo.js1
- hexo-tag-owl/lib/tag/videos/dailymotion.js1
- hexo-tag-owl/lib/tag/videos/youtube.js
index.js
index.js
use strict';
/**
* tag list
**/
// tag list
var list = {
videos: {
path: ['.', 'videos'],
tags: ['youtube', 'nicovideo', 'niconico', 'bilibili', 'vimeo', 'tudou', 'youku', 'tencent', 'ted', 'dailymotion']
},
images: {
path: ['.', 'images'],
tags: ['local', 'giphy', 'imdb']
}
};
// selector for recording a lot of videos and images tags
var selector = {};
Object.keys(list).forEach(function (type) {
var path = list[type].path.join('/');
list[type].tags.forEach(function (tag) {
selector[tag] = require(path + '/' + tag);
})
});
module.exports = selector;
imdb.js
imdb.js
'use strict';
const cheerio=require('cheerio-httpcli');
module.exports = (hexo, args) => {
/* search */
let q=args[1];
let title=((q)=>{
let titleArray=q.split(" ");
let searchTitle="";
for(let i=0;i<titleArray.length;i++){
(i!=titleArray.length-1)?searchTitle+=titleArray[i]+'+':searchTitle+=titleArray[i];
}
return searchTitle;
})(q);
let movies=[];
let searchurl='https://www.imdb.com/find';
let searchoptions={
s: 'tt',
ttype: 'ft',
ref_: 'fn_ft',
q: title,
};
const result=cheerio.fetchSync(searchurl, searchoptions);
if(result.error)
return '<div class="owl-media owl-image owl-imdb"><img src="/assets/no-media.png" alt="no media"></div>';
let $=result.$;
$('.findResult').each(async (i, element)=>{
const $image = $(element).find('td a img');
const $title = $(element).find('td.result_text a');
const imdbID = $title.attr('href').match(/title\/(.*)\//)[1];
const movie = {
image: $image.attr('src'),
title: $title.text(),
imdbID : imdbID
};
movies.push(movie);
return false;
});
/* details */
let detailurl='https://www.imdb.com/title/'+movies[0].imdbID+'/';
let detailoptions={
ref_:'fn_al_tt_1',
};
const result2=cheerio.fetchSync(detailurl, detailoptions);
if(result2.error)
return '<div class="owl-media owl-image owl-imdb"><img src="/assets/no-media.png" alt="no media"></div>';
$=result2.$;
var articleChildren = $('.subtext').children()
var movieDetails = {
title : $('.title_wrapper h1').text(),
year: $('#titleYear a').text(),
rating : $('.ratingValue strong span').text(),
votes : $('.imdbRating a span').text(),
time : $('.subtext time').text().trim(),
poster : $('.poster a img').attr('src'),
release : $(articleChildren[7]).text().trim(),
story : $('.article .canwrap p span').text().trim(),
writtenBy : $('.article .canwrap em a').text()
}
return '<div class="owl-media owl-image owl-imdb"><img src="'+movieDetails.poster+'" alt="'+movieDetails.title+'"><div class="imdb-staff"><ul><li>Title: '+movieDetails.title+'</li><li>Release Date: '+movieDetails.release+'</li></ul></div></div>';
}
niconico.js
niconico.js
'use strict';
var config = require('./config');
// niconico
module.exports = function (hexo, args) {
var id = args[0],
type = args[1] || 'thumb',
res = '';
if ('thumb' === type) {
// thumb
res += '<div class="owl-media owl-video owl-niconico niconico-thumb"><iframe src="//ext.nicovideo.jp/thumb/' + id + '" scrolling="no" ' + config.iframe + '></iframe></div>';
}
else {
// watch
res += '<div class="niconico-video owl-media owl-video owl-niconico niconico-watch" data-video-id="'+id+'"><div class="movie-wrap" data-video-id="'+id+'"></div></div>';
}
return res;
}
nicovideos.js
これはタグ名をすぐ忘れるので作っただけ。
{% owl niconico sm9999999 watch %}
{% owl nicovideo sm9999999 watch %}
どっちの書き方が合っているかうろ覚えだったので、だったらどっちも書けるようにしただけ。
niconico.jsをコピーしただけ。
dailymotion.js
dailymotion.js
'use strict';
var config = require('./config');
// dailymotion
module.exports = function (hexo, args) {
var id = args[0];
return '<div class="owl-media owl-video owl-dailymotion"><div class="dmplayer" dailyid="'+id+'" playoption="off"></div></div>';
}
youtube.js
youtube.js
'use strict';
var config = require('./config');
// youtube 9:16
module.exports = function (hexo, args) {
var id = args[0];
return '<div class="owl-media owl-video owl-youtube"><div class="movie-wrap"><div id="yt__'+id+'" class="youtube-video" width="854" height="480" data-video-id="'+id+'"></div></div></div>';
}
ここまででプラグインの改修は終わり。
次はView側を手をつける。
CSS
hexoはmain.cssを使っているので見た目を変えていく。
やったことはレスポンシブ対応のため
<div class="owl-video">
<div class="movie-wrap">
<iframe/>
</div>
</div>
こんな構造としてiframeは常に100%の大きさで、movie-wrapクラスのdivエレメントでは大きさを考慮してパディングを確保、親のdivエレメントで最大の大きさを調整って感じ。
やったことはこんな感じ。
main.css
@media (min-width:1099px){
.owl-video {
max-width: 800px;
margin: 0 auto;
}
}
@media (max-width:1099px) {
.owl-video {
max-width: 600px;
margin: 0 auto;
}
}
.movie-wrap {
position: relative;
padding-bottom: 56.25%;
height: 0;
overflow: hidden;
}
.movie-wrap iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
JavaScript
先のタグの構造を実現するために以下を行っている。
YouTubeはjquery.youtube-inview-autoplay.jsで実現しているので、ここではniconicoとDailymotionだけ実現している。
main.js
$(document).ready(function(){
$("div.niconico-video div.movie-wrap").each((i, _div)=>{
$.when(
$('<iframe>').attr({
src: nicosrc+'/watch/' + $(_div).attr("data-video-id") + '?jsapi=1&playerId=' + i,
id: 'nicovideoPlayer-' + i,
frameborder: 0,
allowfullscreen: '',
width: '100%',
height: '100%'
}).appendTo($(_div))
).done((obj)=>{
nicoPlayer.push(obj[0]);
$(obj[0]).on('inview', function(event, isInView) {
if (isInView) {
// element is now visible in the viewport
nicoPostMessage(event.target.id,
{
sourceConnectorType: 1,
eventName: 'play'
});
$("#nowplaying-img>img").attr('src', obj[0].thumbnail_url);
$("#nowplaying-product-title").text(obj[0].title);
$("#nowplaying-product-author").text('');
} else {
// element has gone out of viewport
nicoPostMessage(event.target.id,
{
sourceConnectorType: 1,
eventName: 'pause'
});
$('#nowplaying-product-title').text(nowPlayingTitle);
$('#nowplaying-img>img').attr('src',nowPlayingImageUrl);
$('#nowplaying-product-author').text(nowPlayingAuthor);
}
});
}).fail();
});
window.addEventListener('message', (e) => {
if (e.origin !== nicosrc) return;
if (nicoPlay === undefined) nicoPlay=0;
if (e.data.playerId === nicoPlay) {
const { data } = e.data;
switch (e.data.eventName) {
case 'playerMetadataChange': {
nicoPlayerMetadataChange(data);
break;
}
case 'playerStatusChange': {
nicoPlayerStatusChange(data);
break;
}
case 'loadComplete': {
nicoRenderInfoTable(data.videoInfo);
break;
}
default:
console.log(e.data);
}
nicoPlaying = Object.assign({}, nicoPlaying, data);
}
});
$('.dmplayer').each((i, _div)=>{
$.when(
$(_div).wrap(
$('<div>').attr({
class: 'movie-wrap'
})
)
).done((obj)=>{
$(_div).attr('id','dmplayer-'+i);
let videoid=$(_div).attr('dailyid');
let isautoplay=($(_div).attr('playoption')=="on")?true:false;
let player=DM.player(_div, {
video: videoid,
width: "100%",
height: "100%",
params: {
autoplay: isautoplay,
mute: false
}
});
player.load();
dmPlayer.push(player);
$('#dmplayer-'+i).on('inview', (event, isInView)=>{
if (isInView) {
// element is now visible in the viewport
player.play();
$('#nowplaying-product-title').text(player.video.title);
$('#nowplaying-img>img').attr('src',player.video.thumbnail_url);
$('#nowplaying-product-author').text('');
} else {
// element has gone out of viewport
player.pause();
$('#nowplaying-product-title').text(nowPlayingTitle);
$('#nowplaying-img>img').attr('src',nowPlayingImageUrl);
$('#nowplaying-product-author').text(nowPlayingAuthor);
}
});
$('#dmplayer-'+i).attr('height','400');
}).fail();
});
});
では、これでやってみる。
Leeeettttt’s do it again
$ cd $HEXO_HOME
$ cd node_modules/hexo-tag-owl
$ npm i cheerio-httpcli --save
$ cd ../..
$ rm db.json
$ hexo g
$HEXO_HOMEは適宜読み替えていただきたい。
これでやりたいことはできた。
うれしい。
- 1.新規作成 ↩