Narrow_DynamicHeader

小説家になろうのヘッダーを動的に表示する

目前為 2015-01-15 提交的版本,檢視 最新版本

// ==UserScript==
// @name        Narrow_DynamicHeader
// @description 小説家になろうのヘッダーを動的に表示する
// @version     1
// @namespace   phodra531
// @include     http://ncode.syosetu.com/*
// @include     http://novelcom.syosetu.com/*
// @include     http://novel18.syosetu.com/*
// @include     http://novelcom18.syosetu.com/*
// ==/UserScript==


(function (){
	// ユーザーID
	// 自分のIDを調べて書き換えてください。
	// 通常版のユーザーIDは、ホーム画面の右上に以下のように表示されています。
	//  (ユーザー名)[ID:000000]でログイン中
	// 18禁サイト用のユーザーIDは、Xホーム右側の
	// 「評価をつけた作品一覧」のURLから得ることが出来ます。
	var myUserID = 0;
	var myXUserID = 0;

	// 移動ボタンのスタイル
	// 直下行の行頭の/を消すとコメント範囲が切り替わります。
//*
	//  標準のスタイル
	var moveButtonStyle = "\
		.move_button{ \
			color: #666 !important; \
			background-color:#cdd !important; \
		} \
		.move_button:hover{ \
			color: #fff !important; \
			background-color:#9bc !important; \
		} \
	";
/*/
	//  Stylishテーマ「小説家になろうを見やすく」(kanachan氏 作)
	//    https://userstyles.org/styles/107606/theme
	//  に合わせたスタイル
	var moveButtonStyle = "\
		.move_button{ \
			color: #ccc !important; \
			background-color:rgba(48, 48, 48, 0.9) !important; \
		} \
		.move_button:hover{ \
			color: #fff !important; \
			background-color:#666 !important; \
		} \
		.move_button:link{ \
			color:#ccc !important; \
		} \
		.move_button:visited{ \
			color:#ccc !important; \
		} \
	";
//*/



	// ※そのまま移動させると元の場所が埋め立てられるので、
	// ※クローンを作成したのちにオリジナルは visibility = hidden で隠す。
	// ヘッダー(オリジナル)
	var $header_org = $('#novel_header');
	// ヘッダー(クローン)
	var $header_cln = $header_org.clone(true);
	// 強制的に追従しない設定にする
	$header_cln.css( "position", "absolute");

	var title = $('.margin_r20').text();
	var chapter, cpt_txt;
	// 本文がある(作品各話)→情報ラベルを整形
	var infoHeight = 0;
	if( $('#novel_honbun').size() ){
		var $info_org = $('.contents1');
		// 情報ラベルにサブタイトルを埋め込む
		chapter = $('.chapter_title');
		if( chapter.size() ){
			cpt_txt = chapter.text();
			// 章分けがされている
			// チャプタータイトルにサブタイトルを追加
			chapter.append( " - " + $('.novel_subtitle').text() );
		}else{
			// 章分けなし
			// サブタイトル用のエレメントを作成
			var $subtitle = $('<p class="info_label"/>');
			$subtitle.text( $('.novel_subtitle').text() );
			$info_org.append($subtitle);
		}
		
		// 情報ラベルのクローン
		var $info_cln =  $info_org.clone(true);
		$info_cln.css(
			{	"margin": "0 auto",
				"opacity": "0.9"
			});

		infoHeight = $info_org.outerHeight();
		
		// ※$header_clnの兄弟だと設定が面倒なので子にする。
		$header_cln.append($info_cln);
		
		$info_org.css("visibility","hidden");
	}

	// ヘッダーの親になるボックス
	var $header_box =  $('<div/>');
	$header_box.attr( "id", "header_box");
	$header_box.css(
		{	"position": "fixed",
			"top": 0,
			"width": "100%",
			"height": $header_org.height() + infoHeight,
			"zIndex": 1
		});
	$header_box.append($header_cln);
	
	$('body').append($header_box);
	// オリジナルを隠す
	$header_org.css("visibility","hidden");



	// ボタンのボックス
	var $button_box = $('<div />');
	$button_box.attr( "id", "button_box");
	$button_box.css(
		{
			"pointerEvents": "none",
			"position": "fixed",
			"top": 0,
			"width": "100%",
			"height": $header_org.height(),
			"zIndex": 2
		});
	$('body').append($button_box);

	// 表示設定
	var $navi_box = $('#novelnavi_right');
	if( $navi_box.size() ){
		$header_org.find('#novelnavi_right').remove();
		$header_cln.find('#novelnavi_right').hide();
		var $navi = $('<div />');
		$navi.attr("id", "navi_button");
		$navi.css(
			{
				"pointerEvents": "auto",
				"position": "absolute",
				"display": "block",
				"margin": 0,
				"top": 16,
				"right": 3,
				"height": 28,
				"width": 10
			}
		);
		
		var $menu_on = $('<div />');
		var $menu_off = $('<div />');
		var menuStyle = {
			"position": "absolute",
			"height": "100%",
			"width": "100%"
		};
		$menu_on.css(menuStyle);
		$menu_on.attr(
			{
				"id": "menu_open",
				"class": "move_button"
			}
		);
		$menu_on.click(
			function(e){
				$('#menu_on').click();
				$menu_off.show();
				$menu_on.hide();
			}
		);
		$navi.append($menu_on);
		
		$menu_off.css(menuStyle);
		$menu_off.attr(
			{
				"id": "menu_close",
				"class": "move_button"
			}
		);
		$menu_off.click(
			function(e){
				$('#menu_off').click();
				$menu_off.hide();
				$menu_on.show();
			}
		);
		$navi.append($menu_off);
		$menu_off.hide();
		
		$navi.append($('.novelview_navi'));
		$button_box.append($navi);
		$('#menu_off_2').click(
			function(event){
				$menu_off.click();
				$button_box.fadeOut();
			}
		);
	}

	// 移動ボタン群
	var $btnDef = $('#pageBottom');
	var $moveButton = $('<a />');
	$moveButton.attr("class", "move_button");
	$moveButton.css(
		{
			"pointerEvents": "auto",
			"position": "absolute",
			"padding": "10px",
			"margin": "4px",
			"top": 0,
			"bottom": 0
		}
	);
	var mb_style = $('<style type="text/css" />');
	mb_style.append(moveButtonStyle);
	$('head').append(mb_style);

	// 最下部へ移動
	var $pbtm = $moveButton.clone();
	$pbtm.attr(
		{
			"id": "pageBottom2",
			"href": "#page_bottom"
		}
	);
	$pbtm.text("↓");
	$pbtm.css("right", "15px");
	$pbtm.click(
		function(e){
			$('html,body').animate(
				{scrollTop:$('body').height()},
				500
			);
			return event.preventDefault();
		});
	$button_box.append($pbtm);

	// 最上部へ移動
	var $ptop = $moveButton.clone();
	$ptop.attr(
		{
			"id": "pageTop2",
			"href": "#page_top"
		}
	);
	$ptop.text("↑");
	$ptop.css("right", "55px");
	$ptop.click(
		function(e){
			$('html,body').animate(
				{scrollTop:0},
				500
			);
			return event.preventDefault();
		});
	$button_box.append($ptop);

	// 前ページ
	var bn_p = $('a:contains("<<")');
	if( bn_p.size() ){
		var $preEp = $moveButton.clone()
		$preEp.attr(
			{
				"id": "pagePrev",
				"href": bn_p.attr("href")
			}
		);
		$preEp.text("<");
		$preEp.css("left", "15px");
		$button_box.append($preEp);
	}

	// 次ページ
	var bn_n = $('a:contains(">>")');
	if( bn_n.size() ){
		var $nxtEp = $moveButton.clone()
		$nxtEp.attr(
			{
				"id": "pageNext",
				"href": bn_n.attr("href")
			}
		);
		$nxtEp.text(">");
		$nxtEp.css("left", "55px");
		$button_box.append($nxtEp);
	}
	
	$('#pageBottom').remove();
	$('#pageTop').remove();
	
	// AutoPagerizeのページ移動
	if( $('#autopagerize_icon').size() ){
		var $pnxt = $moveButton.clone()
		$pnxt.attr(
			{
				"id": "pageNext",
				"href": "#page_next"
			}
		);
		$pnxt.text("▽");
		$pnxt.css("right", "100px");
		// ボタンが押された時
		$pnxt.click(function(event){
			var tgt_page = now_page+1;
			var tgt_posY =
				tgt_page>seams.length-1?
				$('body').height(): seams[tgt_page]+1;
			
			$('html,body').animate({scrollTop:tgt_posY}, 500);
			return event.preventDefault();
		});
		$button_box.append($pnxt);
	
		var $ppre = $moveButton.clone()
		$ppre.attr(
			{
				"id": "pagePrev",
				"href": "#page_prev"
			}
		);
		$ppre.text("△");
		$ppre.css("right", "140px");
		// ボタンが押された時
		$ppre.click(function(event){
			var tgt_page = $(window).scrollTop()==seams[now_page]+1?
				now_page-1: now_page;
			if( tgt_page<0 ) tgt_page=0;
			var tgt_posY = tgt_page>0? seams[tgt_page]+1: 0;
			
			$('html,body').animate({scrollTop:tgt_posY}, 500);
			return event.preventDefault();
		});
		$button_box.append($ppre);
	}


	// AutoPagerize対応
	var seams = [0];
	document.body.addEventListener('AutoPagerize_DOMNodeInserted',function(e){
		var $page_info = $('.autopagerize_page_info:eq(-1)');
		var num = parseInt( $page_info.children('a:first').text() );
		if( num>1 && seams[num-1]==null ){
			seams[num-1] = parseInt($page_info.eq(-1).offset().top)-$header_box.height();
		}
	}, false);

	var now_page=0;
	// 最下部で表示固定させるフラグ
	var lock = 0;
	// ウィンドウのスクロールが発生した時
	$(window).scroll(function(event){
		var scTop = $(window).scrollTop();
		
		if( moving == 0 ){
			SetHboxTop();
		}

		for( var i=seams.length-1; i>=0; i-- ){
			if( scTop > seams[i] ){
				if( $('#novel_honbun').size() ){
					var sub = $('.novel_subtitle').eq(i).text();
					document.title = title + " - " + sub;
					if( chapter.size() ){
						$('.chapter_title').text( cpt_txt + " - " + sub );
					}else{
						$('.info_label').text(sub);
					}
				}

				if( lock ){
					if( hoving==0 ){
						Hbox_Close();
					}
					lock = 0;
				}
				now_page = i;
				break;
			}
		}
		if( $('#autopagerize_icon').size()<1 ){
			var btmline = $('.novel_bn:eq(-1)');
			if( btmline.size()<1 ) btmline = $('#footer');
			if( btmline.offset().top < scTop + $(window).height() ){
				Hbox_Open( true );
				moving = 1;
				lock = 1;
			}
		}
	});



	// $header_boxの状態
	// 0:移動していない 1:出現中 -1:消失中 2:表示中
	var moving = 0;
	// $header_boxにマウスが乗っているか
	var hoving = 0;

	// 画面上部にポインターを近づける
	document.onmousemove = function (e){
		// InternetExplorer 用
		if(!e) e = window.event;

		if( e.clientY <= $header_org.height() ){
			if( $(window).scrollTop() > 0 &&
				moving < 1  && hoving == 0 ){
				Hbox_Open();
			}
			$button_box.fadeIn("fast");
		}else{
			if( $(window).scrollTop() > 0 &&
				moving != 0 && hoving == 0 && lock==0 ){
				Hbox_Close();
			}
			if( $navi_box.size()? $('.novelview_navi').css("display")=="none": true ){
				$button_box.fadeOut("fast");
			}
		}
	};
	// ヘッダーボックスに乗せる、外す
	$header_box.hover(
		function(){
			Hbox_Open();
			hoving = 1;
		},
		function(){
			if( $(window).scrollTop()>0 ){
				if( lock==0 ){
					Hbox_Close();
				}
			}else{
				moving = 0;
			}
			hoving = 0;
		}
	);

	// ヘッダーを表示させる
	var Hbox_Open = function(){
		if( moving<=0 ){
			// 消えている最中でもすぐにまた表示させる
			$header_box.stop();
			// ヘッダーを表示させるアニメ
			$header_box.animate(
				{"top": 0},
				{	duration : "fast",
					easing   : "swing",
					complete : function(){
						moving = 2;
					}
				}
			);
		}
		moving = 1;
	}
	// ヘッダーを隠す
	var Hbox_Close = function(){
		if( moving > 0 ){
			// とりあえず画面のすぐ上まで持っていく
			var target = -$header_box.height();
			
			$header_box.stop();
			// ヘッダーを非表示にするアニメ
			$header_box.animate(
				{"top": target},
				{
					duration : "normal",
					easing   : "linear",
					complete : function(){
						moving = 0;
					},
					progress : function(s){
						var scTop = $(window).scrollTop();
						if( parseInt($(this).css("top")) <= -scTop ){
							$(this).stop();
							$(this).css("top", -scTop);
							moving = 0;
						}
					}
				}
			);
		}
		moving = -1;
	}

	// ロードした時、ヘッダーが見えない位置なら隠す
	$(document).ready(function(){
		SetHboxTop();
		$button_box.hide();
		moving=0;
	});

	// スクロール位置によってヘッダー位置を調整
	var SetHboxTop = function(){
		var scTop = $(window).scrollTop();
		var hHgt = $header_box.height();
		if( scTop <= hHgt ){
			// 上端ならスクロール位置に合わせて絶対座標っぽく
			$header_box.css( "top", -scTop );
		}else if( $header_box.css("top") != -hHgt ){
			// 上部の表示される位置でなければ、画面のすぐ上
			$header_box.css( "top", -hHgt );
		}
	}



	var href;
	// ヘッダーに「目次」を追加
	var $index_li = $('<li />');
	var $index_node = $('<a />');
	var index_href = $('#contents_main>a:first').attr("href");
	if( index_href==null ){
		// 携帯用のアドレスから生成
		var handheld = $('link[media="handheld"]').attr("href");
		index_href = handheld.match(/\/n\d+?\w+?\//);
	}
	$index_node.text("目次");
	$index_node.attr("href", index_href);
	$index_li.append($index_node);
	$('#header_box li:contains("感想")').before($index_li);

	var userid;
	// ノベルフッターから作者コードを抜く
	var user_href = $('.undernavi a:contains("マイページ")').attr("href");
	if( user_href==null ){
		// よくわからんけど作者コードっぽいので引っこ抜く
		var atom = $('link[title="Atom"]').attr("href");
		if( atom ){
			userid = atom.match(/(\d+|x\d+[^\.]+?)/)[0] + "/";
			user_href = "http://mypage.syosetu.com/" + userid;
		}else{
			userid=null;
			user_href=null;
		}
	}else{
		userid = user_href.match(/(\d+\/|x\d+.+)/)[0];
	}
	
	// ヘッダーに「作者マイページ」を追加
	var $user_li = $('<li />');
	var $user_node = $('<a />');
	$user_node.text("作者");
	if( userid ){
		$user_node.attr("href", user_href);
	}else{
		$user_node.css("cssText", "color: rgba(200,200,200,0.3) !important;");
	}
	$user_li.append($user_node);
	$('#header_box li:contains("感想")').before($user_li);

	// ヘッダーに「メール」を追加
	var $mail_li = $('<li />');
	var $mail_node = $('<a />');
	$mail_node.text("メール");
	if( userid && userid[0]!="x" ){
		$mail_node.attr("href", "http://syosetu.com/message/sendinput/to/" + userid);
	}else{
		$mail_node.css("cssText", "color: rgba(200,200,200,0.3) !important;");
	}
	$mail_li.append($mail_node);
	$('#header_box li:contains("感想")').before($mail_li);

	// N2コードを取得
	var dlurl, n2code;
	dlurl = $('.undernavi li:contains("ダウンロード")>a');
	if( dlurl.size() ){
		n2code = dlurl.attr("href").match(/\d+\//);
	}
	var bm_config = userid && userid[0]=="x"?
	"http://syosetu.com/favnovelmain18/updateinput/xidfavncode/" + myXUserID:
	"http://syosetu.com/favnovelmain/updateinput/useridfavncode/" + myUserID;
	bm_config += "_" + n2code;
	
	var dl_prm = {
		'hankaku': "0",
		'code': "utf-8",
		'kaigyo': "crlf"
	};
	// テキストダウンロードボタンを追加
	var $down_li = $('<li />');
	var $down_node = $('<a />');
	$down_node.text("DL");
	if( n2code ){
		var txtdl_url = userid[0]=="x"?
		"http://novel18.syosetu.com/txtdownload/dlstart/ncode/":
		"http://ncode.syosetu.com/txtdownload/dlstart/ncode/";
		$down_node.attr("href",
			txtdl_url + n2code +
			"?hankaku=" + dl_prm.hankaku +
			"&code=" + dl_prm.code +
			"&kaigyo=" + dl_prm.kaigyo +
			"&no=" + location.href.match( /\d+(?=\/$)/ ));
	}else{
		$down_node.css("cssText", "color: rgba(200,200,200,0.3) !important;");
	}
	$down_li.append($down_node);
	$('#header_box li:contains("レビュー")').after($down_li);
	
	// 「縦書で読む」を消す
	$('#header_box li a.menu').parent().remove();
	
	// 「ブックマークに追加」/「ブックマークを解除」を改変
	var $blist = $('#header_box li.booklist>a');
	if( $blist.size() ){
		$blist.text("☆");
		$blist.attr("alt", "ブックマークに追加");
	}else{
		$blist = $('#header_box li.booklist_now>a');
		$blist.text("★");
		$blist.attr(
			{
				"href": bm_config,
				"alt": "ブックマーク設定"
			}
		);
	}
	$blist.css( "fontSize", "18px");

	// しおりを挿む/しおり中ボタンの改変
	var $bookmark = $('#header_box li.bookmark_now');
	var $bmark_li = $('<li />');
	var $bmark_img = $('<img>');
	var $bmark_node = $('<a />');
	if( $bookmark.size() ){
		var $a = $bookmark.children("li>a");
		$bmark_node.attr(
			{
				"href": $a.attr("href"),
				"alt": "しおりを挿む"
			}
		);
		$bmark_node.text("挿栞");
		$bmark_img.attr("src", "/novelview/img/bookmarker_now.png");
	}else{
		$bookmark  = $('#header_box .bookmark');
		$bmark_node.attr(
			{
				"href": bm_config,
				"alt": "ブックマーク設定"
			}
		);
		$bmark_node.text("設定");
		$bmark_img.attr("src", "/novelview/img/bookmarker.png");
	}
	
	if( $bookmark.size() ){
		$bmark_node.attr("class", "bookmark2");
		var bmark_style = $('<style type="text/css" />');
		bmark_style.append("\
			.bookmark2 { \
				font-weight: normal !important; \
				border-style: none !important; \
				padding-left: 34px !important; \
			} \
			.bookmark2:hover{ \
				font-weight: bold !important; \
				background: none !important; \
			} \
		");
		$('head').append(bmark_style);
		$bmark_img.css(
			{
				"pointer-events": "none",
				"position": "absolute",
				"top": 0,
				"bottom": 0,
				"margin": "auto",
				"padding-left": "12px"
			}
		);
		$bmark_li.append($bmark_img);
		$bmark_li.append($bmark_node);
		$header_cln.children('ul').append($bmark_li);
		$bookmark.remove();
	}
	
	
	
	// 感想ページ
	if( location.href.indexOf("impression")>0){
		// コメントフォームをコメント一覧の上に持っていく
		var parent = document.getElementById('contents_main');
		var target = document.getElementsByTagName('h1')[0];
		var hyouka = document.getElementById('hyoukalan');

		// 横幅いっぱいにする
		hyouka.style.boxSizing = "border-box";
		hyouka.style.width = "100%";
		var textarea = document.getElementsByTagName('textarea');
		for( var i=0; i<textarea.length; i++){
			textarea[i].style.boxSizing = "border-box";
			textarea[i].style.width = "100%";
		}

		parent.insertBefore( hyouka, target);
		parent.insertBefore( document.createElement('hr'), target);
		
		// "▽感想を書く"を消去
		document.getElementsByClassName('input')[0].style.display = "none";
	}
})();



// 小説メニューバーの振る舞いを変更
window.changeMenuBar = function(fixMenuBar){
//	// novel_headerエレメントを取得
//	var element = $('#novel_header');
//	if(element.size() == 0) return false;
//
//	if(isDefined(fixMenuBar)){
//		gIsFixMenuBar = fixMenuBar ? true : false;
//	}else{
//		gIsFixMenuBar = parseInt(CookieManager.get('fix_menu_bar'), 10);
//		if(isNaN(gIsFixMenuBar) || (gIsFixMenuBar != 0)){
//			gIsFixMenuBar = true;
//		}else{
//			gIsFixMenuBar = false;
//		}
//	}
//
//	if(gIsFixMenuBar){
//		$('#novel_header,#novelnavi_right,#menu_on,#menu_off').css('position', 'fixed');
//		$('input[name="fix_menu_bar"]').prop('checked', true);
//	}else{
//		$('#novel_header,#novelnavi_right,#menu_on,#menu_off').css('position', 'absolute');
//		$('.novelview_navi').css('position', 'fixed');
//		$('input[name="fix_menu_bar"]').removeProp('checked');
//	}
//
//	// クッキーに記憶
//	fixMenuBar = gIsFixMenuBar ? 1 : 0;
//	var expires = 86400 * 1000 * 90;	// 90日
//	CookieManager.set({key:'fix_menu_bar', value:fixMenuBar, domain:domain, path:'/', expires:expires});
}

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址