ページ遷移でフェードかけるだけのJavaScript作った

絶賛脱jQueryで墓穴を掘っている感ある今日このごろです。 いつまで続くのか分からない感ありますが、脱jQueryで作ったものをちまちま公開したいと思います。脱jQueryのせいで夏休みがなくなってる感あるので誰か使ってあげて下さい。

ページ遷移でフェードかけるだけのJavaScript

動作環境
transition使ってるためIE10以上(8以上にするかもしれませんがいつものようにしないと思います)

demo

;(function(window,config){
function deleteVendor(vendor){
var re = /^webkit|^moz|^ms|^O/g,
str = vendor,
noVendor = str.replace(re, "");
return noVendor.toLowerCase();
}
function ieFixLoop(ieFix){
var arr = ieFix.arr,
prop = ieFix.prop,
value = ieFix.value,
selector;
for (var i = 0; i < arr.length; i++) {
selector = arr[i];
if(!document.querySelector(selector)){
return;
}
var noVendor = deleteVendor(prop);
document.querySelector(selector).style[prop] = value;
document.querySelector(selector).style[noVendor] = value;
}
}
function fadePage(config){
var options = {
'duration': 1000,
'smp' : false,
'selector': []
},
vendor = (/webkit/i).test(navigator.appVersion) ? 'webkit' :
(/firefox/i).test(navigator.userAgent) ? 'moz' :
(/trident/i).test(navigator.userAgent) ? 'ms' :
'opera' in window ? 'O' : '';
for (var i in config) {
if (!options.hasOwnProperty(i)) {
continue;
}
options[i] = config[i];
}
if(!options.smp&&/iPhone|iPad|iPod|Android/.test(navigator.userAgent)){
return;
}
document.body.style.visibility ='hidden';
document.body.style.opacity =0;
ieFixLoop({
'arr' : options.selector,
'prop' : 'opacity',
'value': 0
});
window.addEventListener('load', function(){
setTimeout(function(){
document.body.style[vendor+'Transition'] = 'all ' + options.duration*0.5*0.001 + 's ease-in';
document.body.style['transition'] = 'all ' + options.duration*0.5*0.001 + 's ease-in';
ieFixLoop({
'arr' : options.selector,
'prop' : vendor+'Transition',
'value': 'all ' + options.duration*0.5*0.001 + 's ease-in'
});
document.body.style.visibility ='';
}, options.duration*0.5);
setTimeout(function(){
document.body.style.opacity =1;
ieFixLoop({
'arr' : options.selector,
'prop' : 'opacity',
'value': 1
});
}, options.duration);
}, false);
}
window.addEventListener('DOMContentLoaded', function(){
fadePage(config);
}, false);
function clickFade(e,config){
var targetURL = e.target.href,
targetAnchor = e.target,
thisURL = location.href,
options = {
'duration': 1000,
'smp' : false,
'selector': [],
'noClass' : [],
'noData' : []
};
for (var i in config) {
if (!options.hasOwnProperty(i)) {
continue;
}
options[i] = config[i];
}
function checkClass(className){
var checked = false,
targetClass = className.split(' ');
for (var i = 0; i < targetClass.length; i++) {
options.noClass.indexOf(targetClass[i]);
if(options.noClass.indexOf(targetClass[i]) > -1){
checked = true;
return checked;
}
}
return checked;
}
function checkData(anchor){
var checked = false;
for (var k = 0; k < options.noData.length; k++) {
if(anchor.hasAttribute(options.noData[k])){
checked = true;
return checked;
}
}
return checked;
}
if(!targetURL){
//hrefがなかったらある親まで遡る
var parent = e.target.parentNode;
while(parent.localName!=='a'){
parent = parent.parentNode;
}
targetURL = parent.href;
targetAnchor = parent;
}
if(targetAnchor.hasAttribute('target')){
return;
}
e.preventDefault();
if(checkClass(targetAnchor.className)||checkData(targetAnchor)){
return;
}
if(thisURL.split('#')[0] === targetURL.split('#')[0] && e.target.hash){
location.href=targetURL
}else{
document.body.style.opacity =0;
ieFixLoop({
'arr' : options.selector,
'prop' : 'opacity',
'value': '0'
});
setTimeout(function(){
location.href=targetURL;
}, options.duration);
}
}
var selector = document.querySelectorAll('a[href]');
Array.prototype.forEach.call(selector,function(node){
node.addEventListener('click', function(e){
clickFade(e,config);
}, false);
});
})(window,{
'duration': 1000,
'smp' : false,
'selector': ['.header','.js-pageNavFixed'],
'noClass' : [],
'noData' : ['data-tabs','data-imagelightbox']
});
view raw fadePage.js hosted with ❤ by GitHub
;(function(e,t){function n(e){var t=/^webkit|^moz|^ms|^O/g,n=e,r=n.replace(t,"");return r.toLowerCase()}function r(e){var t=e.arr,r=e.prop,i=e.value,s;for(var o=0;o<t.length;o++){s=t[o];if(!document.querySelector(s)){return}var u=n(r);document.querySelector(s).style[r]=i;document.querySelector(s).style[u]=i}}function i(t){var n={duration:1e3,smp:false,selector:[]},i=/webkit/i.test(navigator.appVersion)?"webkit":/firefox/i.test(navigator.userAgent)?"moz":/trident/i.test(navigator.userAgent)?"ms":"opera"in e?"O":"";for(var s in t){if(!n.hasOwnProperty(s)){continue}n[s]=t[s]}if(!n.smp&&/iPhone|iPad|iPod|Android/.test(navigator.userAgent)){return}document.body.style.visibility="hidden";document.body.style.opacity=0;r({arr:n.selector,prop:"opacity",value:"0"});e.addEventListener("load",function(){setTimeout(function(){document.body.style[i+"Transition"]="all "+n.duration*.5*.001+"s ease-in";document.body.style["transition"]="all "+n.duration*.5*.001+"s ease-in";r({arr:n.selector,prop:i+"Transition",value:"all "+n.duration*.5*.001+"s ease-in"});document.body.style.visibility=""},n.duration*.5);setTimeout(function(){document.body.style.opacity=1;r({arr:n.selector,prop:"opacity",value:"1"})},n.duration)},false)}function s(e,t){function a(e){var t=false,n=e.split(" ");for(var r=0;r<n.length;r++){o.noClass.indexOf(n[r]);if(o.noClass.indexOf(n[r])>-1){t=true;return t}}return t}function f(e){var t=false;for(var n=0;n<o.noData.length;n++){if(i.hasAttribute(o.noData[n])){t=true;return t}}return t}e.preventDefault();var n=e.target.href,i=e.target,s=location.href,o={duration:1e3,smp:false,selector:[],noClass:[],noData:[]};for(var u in t){if(!o.hasOwnProperty(u)){continue}o[u]=t[u]}if(!n){var l=e.target.parentNode;while(l.localName!=="a"){l=l.parentNode}n=l.href;i=l}if(a(i.className)){return}if(f(i)){return}if(s.split("#")[0]===n.split("#")[0]&&e.target.hash){location.href=e.target.href}else{document.body.style.opacity=0;r({arr:o.selector,prop:"opacity",value:"0"});setTimeout(function(){location.href=n},o.duration)}}e.addEventListener("DOMContentLoaded",function(){i(t)},false);var o=document.querySelectorAll("a[href]");Array.prototype.forEach.call(o,function(e){e.addEventListener("click",function(e){s(e,t)},false)})})(
window,{
duration:1000,
smp :false,
selector:[".mainNav","footer","article nav"],
noClass :["aaa"],
noData :["data-tabs","data-imagelightbox"]
});
view raw fadePage.min.js hosted with ❤ by GitHub

オプション項目

	'duration': 1000, //何秒かけてフェードさせるか(大体)デフォルト1000
	'smp'     : false,//スマホに対応させるか。デフォルト false
	'selector': ['.mainNav','footer','article nav'],//position:fixedの要素。IEでフェードかからないため
	'noClass' : ['aaa'],//除外したいクラス名
	'noData'  : ['data-tabs','data-imagelightbox']//除外したい属性

一応内部アンカーは除外、クラスと属性も除外できるようにしてあります。 サイズは普通で4kb、minify版で2.4kbです

IEではなぜかposition:fixedかかってるものはフェードかからないため指定してあげる必要があります。面倒くさいですね。

たまに画面がちらつくのですが、多分データが重くないとちらつくみたい。その場合は直opacityかければと思ったんですけど、それでもちらついたりする場合があります。100%できるやり方があるのを知ってる方は教えて下さい。
なにか問題などあったらコメント下さい。コードは適当なのでパブリックドメインでかまいません。

ぶっちゃけページ遷移でエフェクトかけるのはおすすめしません。pjaxでもたまにちらついて中身見えたりするサイトもあるので難しいのかも。

作ってみて改めて思うのはjQuery is 神