FOCUS

はてなブログテーマ"Focus"のカスタマイズやあれこれ

フッタHTML内に記入するコード(ファーストリリース時)

f:id:ganapati55:20171011145040j:plain

3カラムレイアウトやグローバルナビを設置するためのコード

フッタHTMLに以下のコードを入力することでFocusで使用している各種機能が有効になります。

なお、JavaScriptがかなり使用されていますが、サイドバー内で表示崩れが起きるときの原因にもなっています。

特に3カラムレイアウトとサイドバー内のタブメニュー化の相性が悪いようです。気になるときは3カラムを取るかタブ化をとるかどちらかにして不要なJavaScriptを削除してください。

<!-- ⑥フッタHTMLに追加 -->

<!-- ⑥-1 グローバルナビのJS-->
<script>
// グローバルナビ(ヘッダーのメニュー)のJavaScript
(function(){
  // メニューを表示非表示
  var navToggleBtn = document.getElementById('js-nav-toggle-btn');
  var navBody = document.getElementById('js-nav-toggle');
  var mobileHeader = document.getElementById('js-mobile-head');
  var blackBack = document.getElementById('js-close-nav');
  var container = document.getElementById('container-inner');
  // classを操作したい要素たちをまとめる
  var elemObj = [navToggleBtn,navBody,blackBack,container,mobileHeader];
  navToggleBtn.addEventListener('click',function(){
    if(container.classList.contains('is-open')) {
      removeClassOpen();
    } else {
      addClassOpen();
    }
  });
  blackBack.addEventListener('click',function(){
    removeClassOpen();
  });
  var frameTime = 1000 / 60;
  var timer = false;
  var winWidth;

  function scrollEvent(){
    // スクロールイベントが多発しすぎないように間引く
    if(timer!==false){
      clearTimeout(timer);
    }
    timer = setTimeout(function(){
      winWidth = window.outerWidth;
      if(winWidth>768) {
        removeClassOpen();
      } else {
        showTitle();
      }
    }, frameTime);
  }
  window.addEventListener('resize',function(){
    scrollEvent();
  });
  window.addEventListener('scroll',function(){
    scrollEvent();
  });
  var title = document.getElementById('title');
  var siteName = document.getElementById('js-sitename');
  function showTitle(){
    if(siteName === null) return;
    var titleRect = title.getBoundingClientRect();
    var scrollTop = window.pageYOffset;
    var offsetTop = titleRect.top + scrollTop;
    if(offsetTop+100<scrollTop){
      siteName.classList.add('is-show');
    } else {
      siteName.classList.remove('is-show');
    }
  }
  showTitle();

  function removeClassOpen(){
    for(var i=0;i<elemObj.length;i++){
      elemObj[i].classList.remove('is-open');
    }
    navToggleBtn.classList.add('is-close');
  }
  function addClassOpen(){
    for(var i=0;i<elemObj.length;i++){
      elemObj[i].classList.add('is-open');
    }
    navToggleBtn.classList.remove('is-close');
  }
  // 検索ボックスを表示・非表示
  var toggleBtn = document.getElementById('js-search-toggle');
  var searchBody = document.getElementById('js-search-body');
  toggleBtn.addEventListener('click',function(){
    if(searchBody.classList.contains('is-open')) {
      searchBody.classList.remove('is-open');
    } else {
      searchBody.classList.add('is-open');
    }
  });
}());
</script>




<!--⑥-2 サイドバータブメニューのJS-->
<script>
$(function(){
    $(".hatena-module-entries-access-ranking,.hatena-module-recent-entries,.hatena-module-archive,.hatena-module-recent-comments").addClass("module");
    $(".hatena-module-title2").parents(".hatena-module-html").css("margin-bottom",0);
    var Module = $(".module");
    Module.hide();
    Module.first().show();
    Module.find(".hatena-module-title").hide();
    
    $(".tab").click(function(){
        var index = $(this).index();
        $(".tab").removeClass("active");
        $(this).addClass("active");
        $(Module).hide();
        $(Module).eq(index).show();
    });
});
</script>

 <!--⑥-3 クリックすると表示される目次のJS-->
<script>
$(function(){
    var $Contents = $(".table-of-contents")
    $($Contents).before('<p style="font-size: 140%;color: #333;margin-bottom: 1em;">目次<span class="show-area">[表示]</span></p>');
    $(".show-area").click(function(){
        var $this = $(this);
        if($Contents.css('display') == 'none'){
            $Contents.slideDown(400),
            $this.text("[隠す]");
        }else{
            $Contents.slideUp(400),
            $this.text("[表示]")
        };
    });
});
</script>

 <!--⑥-4FB/HBシェア数カウントのJS(SOHOオリジナルシェアボタン用)-->
<script>
/*
  シェア数をカウントするJS
*/
// コールバック関数
function getJson(json) {
  var hatebuCount = json;
  var allSelector = document.getElementsByClassName('sh-hatebu-count');
  for(var i=0;i<allSelector.length;i++){
    allSelector[i].innerHTML = hatebuCount;
  }
}
// ここは即時関数で他のコードに影響が出ない様に。
(function(){
  var now = new Date();
  var url = location.href;
  getResponse("//graph.facebook.com/?id=",'sh-facebook-count','json',callbackFb);
  // はてブのjsonpを受け取る
  var script = document.createElement('script');
  script.src = 'http://api.b.st-hatena.com/entry.count?url='+encodeURIComponent(url)+'&callback=getJson&timestamp='+now.getTime();
  document.body.appendChild(script);
  // 通信用の関数(あとで再利用するかもなので関数化)
  function getResponse(reqUrl,selector,type,callback){
    var data = null;
    var xhr = new XMLHttpRequest();
    xhr.ontimeout = function() {
      xhr.abort(); // 中止
      callback(data,selector);
    };
    // 通信エラー時の処理
    xhr.onerror = function(){callback(data,selector);};
    xhr.onreadystatechange = function(){
      if(xhr.readyState == 4 ) {
        if(xhr.status == 200) {
          data = xhr.response;
        }
        callback(data,selector);
      }
    }
    xhr.open('GET',reqUrl+encodeURIComponent(url),true);
    xhr.timeout = 15000 ;
    xhr.responseType = type;
    xhr.send();
  }
  // 各SNSのコールバック関数
  function callbackFb(obj,selector) {
    var allSelector = document.getElementsByClassName(selector);
    if(!obj.share || !obj.share.share_count) {
      for(var i=0;i<allSelector.length;i++){
        allSelector[i].innerHTML = 0;
      }
    } else {
      for(var i=0;i<allSelector.length;i++){
        allSelector[i].innerHTML = obj.share.share_count;
      }
    }
  }
}());
</script>


 <!--⑥-5 TOPへボタンのJS-->
<script>
$(function () {
   /** ページトップ処理 **/
   // スクロールした場合
   $(window).scroll(function() {
       // スクロール位置が200を超えた場合
       if ($(this).scrollTop() > 200) {
           $('#pagetop').fadeIn();
       } else {
           // ページトップへをフェードアウト
           $('#pagetop').fadeOut();
       }
   });

   // ページトップクリック
   $('#pagetop').click(function() {
       // ページトップへスクロール
       $('html, body').animate({
           scrollTop: 0
       }, 300);
       return false;
   });
})(jQuery);
</script>

<a id="pagetop" href="#top" class="page_top" style="display: none;
    font-size: small;
">TOPへ ▲</a>

<!--⑥-6 3カラム左右振り分け表示のためのJS-->
<script>
    (function (a) {
        a(function () {
            var b = a("#box2-inner"),
                c = a(".hatena-module:nth-child(2n+1)", b).removeClass("hatena-module").css("marginBottom", "1em");
            b = a(".hatena-module:nth-child(2n)", b).removeClass("hatena-module").css("marginBottom", "1.5em");
            c.wrapAll('<div class="hatena-module"></div>');
            b.wrapAll('<div class="hatena-module"></div>')
        })
    })(jQuery);
</script>



<!-- ⑥-7 追尾する目次のJS ver3.0.0β  https://git.io/vdzpg -->
<!-- 追尾する目次 ver3.0.0β  https://git.io/vdzpg -->
<script>
(function() {
'use strict';
//----------------------
// ↓設定ここから↓

// 各ページごとの動作設定
// entry:記事, index:トップ, archive:アーカイブ, static:固定ページ
//
// display : 目次を表示するかどうか(true, false)
// listPage: 記事一覧ページに付ける(true)
// class   : 各ページでbodyに設定されているクラス名
// title   : 目次タイトル('':空文字で非表示)
// (一覧ページ以外は title の設定を 'entry-title' にすると記事タイトル表示)
const PAGES = [
  {
    display  : true,
    class    : 'page-entry',
    title    : '目次'
  },
  {
    display  : true,
    listPage : true,
    class    : 'page-index',
    title    : 'このページの記事一覧'
  },
  {
    display  : true,
    listPage : true,
    class    : 'page-archive',
    title    : 'このページの記事一覧'
  },
  {
    display  : false,
    class    : 'page-static_page',
    title    : 'entry-title'
  },
];

// 目次を固定する時の上の余白(px)
const MARGIN_TOP = 10;
// 目次を固定する時の下の余白(px)
const MARGIN_BOTTOM = 0;

// 現在位置表示の位置取得に余裕をもたせる(px)
const CURRENT_MARGIN = 50;

// 固定開始位置がずれるときの調整用(px)
const ADJUST_FIXED = 0;

// 表示する見出しタグ(順番注意)
const HEADLINE_QUERY = ['h2', 'h3', 'h4'];
// 見出しがn個以下なら表示しない(0以上)
const HEADLINE_MIN = 1;

// スムーズスクロールを使う(true, false)
const SMOOTH_SCROLL = true;
// スムーズスクロールにかける時間(ミリ秒)
const SMOOTH_SCROLL_TIME = 400;
// スムーズスクロール先の調整(px)
const ADJUST_SCROLL = 0;

// 目次内のスクロールを自動追尾(true, false)
const TOC_INSIDE_SCROLL = true;

// 目次タイトルにトップへ移動するリンクを設定(true, false)
const TOC_TITLE_TOP = true;

// ページ内リンクをブラウザ履歴に追加(true, false)
const LINK_HISTORY = false;

// 固定位置に応じたCSS用のクラス設定を行う(true, false)
const SET_CLASS = true;

// ページが読み込まれてから追尾処理の開始を遅らせる時間(ミリ秒)
const DELAY_TIME = 250;
// ページが完全に読み込まれてから追尾処理の開始を遅らせる時間(ミリ秒)
const DELAY_TIME_2 = 0;

// 常に表示されるグローバルメニューなどの要素を指定(配列)
const GLOBAL_HEADER = ['globalheader-container'];

// 使用するリスト要素(ol, ul)
const USE_LIST = 'ol';

// サイドバーが横に表示されていない時処理を止める(true, false)
const PAUSE_NO_SIDEBAR = true;
// サイドバーより記事の方が小さい時処理を止める(true, false)
const PAUSE_MAIN_SMALL = true;

// サイドバーが横に表示されているかの判定をmatchMedia関数で行う(true, false)
const MATCH_MEDIA = false;
// MATCH_MEDIAがtrueの時だけ有効
const MEDIA_QUERY_SIDEBAR = '(max-width: 1000px)';

// ↑設定ここまで↑
//----------------------

function t(t){return t+"px"}function e(){return a.createElement("div")}function n(t,e){const n=parseFloat(_(t)[e]);return n}function o(t,e,o){let i=[];const s=t.classList,l=o.filter(function(t){return s.contains(t)});return l.forEach(function(t){s.remove(t)}),e.forEach(function(e){i.push(n(t,e))}),l.forEach(function(t){s.add(t)}),i}function i(t){return t.replace(/[-]./g,function(t){return t.charAt(1).toUpperCase()})}function s(t,e){let n=t.offsetHeight;return e&&(n+=r(t,L)),n}function l(t,e){return t.getBoundingClientRect().top+(void 0!==e?e:c.pageYOffset)}function r(t,e){let n=0;const o=_(t);for(let t=0,i=e.length;t<i;t++){const i=parseInt(o[e[t]],10);isNaN(i)||(n+=i)}return n}const c=window,a=document,f="fade-in",u="active",d="tracking",g="fixed",m="absolute",E="static",h="fixed",p="absolute",L=["marginTop","marginBottom"],T=["paddingTop","borderTopWidth","paddingBottom","borderBottomWidth"],_=function(){const t={};return function(e){const n=i(e.id);if(!t[n]){const o=getComputedStyle(e,null);if(!n)return o;t[n]=o}return t[n]}}(),A=function(){function t(t){return t<.5?2*t*t:(4-2*t)*t-1}let e;const n=1e3/30,o=c.scrollTo;let i,s,l;{const t="requestAnimationFrame";(l=c.hasOwnProperty(t))?(i=c[t],s=c.cancelAnimationFrame):(i=c.setTimeout,s=c.clearTimeout)}const r=c.performance?performance:Date;return function(a,f){function u(n){(g=n-m)>=f?o(h,a):(o(h,t(g/f)*p+E),e=i(u))}function d(){(g=r.now()-m)>=f?o(h,a):(o(h,t(g/f)*p+E),e=i(d,n))}let g;const m=r.now(),E=c.pageYOffset,h=c.pageXOffset,p=a-E;s(e),e=i(l?u:d)}}();!function(){function i(){R.display="none"}function I(t){t.preventDefault();const e=decodeURIComponent(t.currentTarget.hash),n=l(a.getElementById(e.substr(1)))-Z+ADJUST_SCROLL;SMOOTH_SCROLL?A(Math.min(n,W),SMOOTH_SCROLL_TIME):c.scrollTo(c.pageYOffset,n),LINK_HISTORY&&c.history.pushState(null,e,e)}function O(e){C.style.maxHeight=e?t(nt):"",ot=e}function S(t){const e=rt[t];lt=t!==E,Object.keys(e).forEach(function(t){R[t]=e[t]}),SET_CLASS&&(M.classList.toggle(d,lt),M.classList.toggle(g,h===t),M.classList.toggle(m,p===t)),O(lt)}function N(){function e(t,e,n){if(At(t),V=e,t&&e)n();else if(_t(0),S(E),!t)for(let t=0,e=X.length;t<e;t++)X[t].classList.remove(u)}function i(t,e,n){let o;const i=e.style,l=i[n];return i[n]="",o=s(t,!0),i[n]=l,o}function f(t,e){function o(t,e){let o=[];for(let i=0,s=t.length;i<s;i++)o.push(n(t[i],e));return Math.max.apply(null,o)}function i(t,e){const o=t.length-1,i=2*e;if(o>0)for(let e=0;e<o;e++)for(let o=0;o<2;o++)if(n(t[e],T[o+i])>0)return t.slice(0,e+1);return t}const s=o(i(t,0),L[0]),l=o(i(e,1),L[1]);return 0===s||0===l?0:Math.min(s,l)}const A=c.innerHeight,I=A-a.documentElement.clientHeight;W=Math.max(a.documentElement.scrollHeight-A,0),Z=0;for(let t=0,e=q.length;t<e;t++)Z+=_(q[t]).position===h?s(q[t]):0;$=Z+MARGIN_TOP,et=ct.getBoundingClientRect().left+c.pageXOffset,nt=A-I-$-MARGIN_BOTTOM-r(M,T)-r(C.parentElement,T),k&&(nt-=s(k,!0));for(let t=0,e=D.length;t<e;t++)st[t]=l(D[t])-Z;if(R.width=_(ct).width,ht(-1),MATCH_MEDIA?c.matchMedia(MEDIA_QUERY_SIDEBAR).matches:"none"===_(Q).cssFloat){if(e(!PAUSE_NO_SIDEBAR,!1),PAUSE_NO_SIDEBAR)return}else if(i(Q,ut,"height")>s(j)){if(e(!PAUSE_MAIN_SMALL,!1),PAUSE_MAIN_SMALL)return}else e(!0,!0,function(){O(lt),_t(-1),it=0;const e=s(b),n=o(M,["marginTop","marginLeft"],[d,g,m]),r=n[0],c=n[1];et-=c,z=l(ct)-Z+r+ADJUST_FIXED,at&&(z-=f([M,k],[at,at.children[1]])),ft?z-=MARGIN_TOP:lt&&(z+=i(M,C,"maxHeight"));const a=Math.min(A-$,s(M));K=l(b)+e-a-$,tt=l(ct.offsetParent),rt[h].top=t($-r),rt[p].top=t(K-tt+$-r)});y()}function y(){const e=c.pageYOffset,n=c.pageXOffset;if(K<e?Lt(2)&&S(p):z<e?Lt(1,function(t){ft||0!==t||M.classList.add(f),S(h)}):Lt(0)&&S(E),1===Tt()&&n!==it&&(R.left=t(et-n),it=n),e<=CURRENT_MARGIN)ht(0);else if(W-e<=CURRENT_MARGIN)ht(J);else for(let t=J;t>=0;t--)if(e>st[t]-CURRENT_MARGIN){ht(t);break}}const C=a.getElementById("stoc"),M=C.parentNode.parentNode,R=M.style,B=a.body.classList;let v;for(let t=0,e=PAGES.length;t<e;t++)if(PAGES[t].display&&B.contains(PAGES[t].class)){v=PAGES[t];break}if(!v)return void i();const b=a.getElementById("main-inner");let D=[];if(v.listPage){const t=b.getElementsByClassName("entry-title");for(let e=0,n=t.length;e<n;e++)D.push(t[e].children[0])}else D=b.getElementsByClassName("entry-content")[0].querySelectorAll(HEADLINE_QUERY.join());if(D.length<=HEADLINE_MIN)return void i();const H=b.getElementsByClassName("table-of-contents");let P=!1,U=[],G=[],x=0;if(!v.listPage&&H.length){const t=H[0].getElementsByTagName("a"),e=t[0].href.split("#")[0].length+1;for(let n=0,o=t.length;n<o;n++)U.push(t[n].href.slice(e)),t[n].addEventListener("click",I,!1);P=!0}for(let t=0,e=D.length;t<e;t++){const e=D[t];let n="section"+t,o=0;P?n=U[t]:e.setAttribute("id",n),G.push('<li><a href="#'+n+'">'+e.textContent+"</a>");for(let t=1,n=HEADLINE_QUERY.length;t<n;t++)if(e.nodeName.toLowerCase()===HEADLINE_QUERY[t]){o=t;break}for(;x<o;)G[t]="<"+USE_LIST+">"+G[t],x++;for(;x>o;)G[t]="</"+USE_LIST+"></li>"+G[t],x--}let Y,k=!1;""!==v.title&&(Y=v.listPage||"entry-title"!==v.title?v.title:b.getElementsByClassName("entry-title")[0].children[0].textContent);const w=M.getElementsByClassName("hatena-module-title")[0];if(w&&M.removeChild(w),Y){const t=e();t.id="stoc-title",t.className="hatena-module-title",t.innerHTML=TOC_TITLE_TOP?'<a href="#">'+Y+"</a>":Y,k=M.insertBefore(t,M.firstElementChild),TOC_TITLE_TOP&&k.getElementsByTagName("a")[0].addEventListener("click",function(t){t.preventDefault(),t.stopPropagation(),SMOOTH_SCROLL?A(0,SMOOTH_SCROLL_TIME):c.scrollTo(c.pageXOffset,0)},!1)}C.parentElement.id="stoc-body";const F=a.createElement("ol");F.innerHTML=G.join(""),C.appendChild(F),M.setAttribute("id","stoc-module");const X=C.getElementsByTagName("a");for(let t=0,e=X.length;t<e;t++)X[t].addEventListener("click",I,!1);const j=a.getElementById("main"),Q=a.getElementById("box2"),q=[];for(let t=0,e=GLOBAL_HEADER.length;t<e;t++)q.push(a.getElementById(GLOBAL_HEADER[t]));const J=G.length-1;let W,z,K,V,Z,$,tt,et,nt,ot,it,st=[],lt=!1;const rt={};rt[p]={position:p,left:""},rt[h]={position:h},rt[E]={position:E};let ct,at,ft;const ut=M.parentNode,dt=ut.children,gt=dt.length,mt=e();mt.id="stoc-guide",mt.className="hatena-module",mt.style.cssText=["visibility: hidden;","height: 0;","margin-top: 0;","margin-bottom: 0;","padding-top: 0;","padding-bottom: 0;","border-top: 0;","border-bottom: 0;"].join(""),1===gt?(ct=ut.insertBefore(mt,M),ft=!0):(ft=dt[gt-1]===M)?((at=M.previousElementSibling).id="stoc-sub-guide",ct=ut.insertBefore(mt,M)):ct=ut.appendChild(mt);let Et;c.addEventListener("resize",function(){clearTimeout(Et),Et=setTimeout(N,200)},!1),M.addEventListener("animationend",function(){M.classList.remove(f)},!1),c.addEventListener("DOMContentLoaded",function(){setTimeout(function(){N(),c.addEventListener("load",function(){setTimeout(N,DELAY_TIME_2)},!1)},DELAY_TIME)},!1);const ht=function(){let t=-1;return function(e){if(e!==t){if(t>=0&&X[t].classList.remove(u),t=e,e<0)return;let n=X[e];n.classList.add(u),TOC_INSIDE_SCROLL&&ot&&lt&&(C.scrollTop=n.offsetTop+n.offsetHeight-nt)}}}(),pt=function(){let t=0;return{update:function(e,n){return!(e===t||!V)&&(n&&n(t),t=e,!0)},get:function(){return t},set:function(e){t=e}}}(),Lt=pt.update,Tt=pt.get,_t=pt.set,At=function(){let t=!1;const e="ontouchstart"in c?"touchmove":"scroll";return function(n){n!==t&&(t?c.removeEventListener(e,y,!1):c.addEventListener(e,y,!1),t=n)}}()}();}());
</script>