Written by Anonymous
<?php //子テーマ用関数
if ( !defined( 'ABSPATH' ) ) exit;
//子テーマ用のビジュアルエディタースタイルを適用
add_editor_style();
//以下に子テーマ用の関数を書く
/*
* **********************************
* ポップアップ設置
* **********************************
*/
function popup($atts, $content){
/*******************************************************************************
【入力パラメータ$attsの内容】
enabled => ポップアップ 0=無効 1=有効
init_display => 0=デフォルトで出さない 1=デフォルトで出す
modal_option => jQuery.modalに渡すオプション配列をJS連想配列の記述で。
デフォルト {escapeClose: true, clickClose: true, showClose: true,}
escapeClose→Escキーを押したときに閉じるか
clickClose→暗い背景をクリックしたときに閉じるか
showClose→閉じる×アイコンを表示するか
onpopup ポップアップしたときに実行するスクリプト。スクリプトの文字列囲みには'を使用。
onclick 画像型の場合にクリックしたときに実行するスクリプト。スクリプトの文字列囲みには'を使用。
①画像型のポップアップ
以下のURLで設定
banner_url => バナー画像のURL。URLパラーメータのバインド変数{%パラメータ名}を入力可能
link_url => バナークリックしたときのリンク先URL。URLパラーメータのバインド変数{%パラメータ名}を入力可能
②カスタマイズhtml型のポップアップ
自由なhtmlを記述。ショートコードブロックは余計なスペースなど入るので非推奨。カスタムhtmlブロックを推奨。
ショートコードを囲み型にして中のテキストを$contentで受け取れるテキスト型
URLパラーメータのバインド変数{%パラメータ名}を入力可能
********************************************************************************/
//パラメータ初期化
extract(shortcode_atts(array(
'enabled' => 1,
'modal_id' => 'ss-popup-banner',
'init_display' => 1,
'banner_url' => '',
'link_url' => '',
'modal_option' => '{escapeClose: true, clickClose: true, showClose: true,}',
'onpopup' => '',
'onclick' => '',
), $atts));
/***********************************************
* 入力パラメータチェック
************************************************/
if($content == null && $banner_url == null){
return null;
}
if($enabled == 0){
return null;
}
if($init_display != 1){
$init_display = 0;
}else{
$init_display = 1;
}
/***********************************************
* 囲みの中の文字列があればテキスト型。そのテキストをポップアップに。
* なければ画像型。引数で指定されたURLを使う
************************************************/
$content_check = trim(strip_tags($content)); //囲みテキストからタグを除く。コメントアウトされていれば空になり無効になる
if($content_check != null){ //囲みテキストが空じゃない
$popup_html =<<<EOF
<!-- ポップアップバナー(囲みテキスト) -->
<div id="{$modal_id}" class="modal ss-popup-banner-text">
{$content}
</div>
<!-- /ポップアップバナー -->
EOF;
}else{
$link_url = replace_req_params(array("encode" => "urlencode"), $link_url); //リンクURLパラメータ変換
$banner_url = replace_req_params(array("encode" => "urlencode"), $banner_url); //バナーURL変換
$popup_html =<<<EOF
<!-- ポップアップバナー(画像型) -->
<div id="{$modal_id}" class="modal ss-popup-banner-image">
<a style="display: block; margin: auto;" href="{$link_url}" target="_blank" onClick="{$onclick}">
<img style=" width: 100%; margin: 0; max-width: 500px;" src="{$banner_url}" />
</a>
</div>
<!-- /ポップアップバナー(画像型) -->
EOF;
}
/***********************************************
* 出力するHTMLを設定
************************************************/
$html =<<<EOF
<style>
.modal{
z-index: 3;
padding: 0;
border-radius: 0;
display: none;
/* width: initial; */
}
.modal.ss-popup-banner-image{
/* width: auto; */
}
.modal.ss-popup-banner-text{
}
.modal img, modal a{
display: block;
}
.blocker{
z-index: 2;
}
.modal a.close-modal{
width: 2.4rem;
height: 2.4rem;
opacity: 0.5;
top: -2rem;
right: -2rem;
z-index: -1;
}
</style>
<script>
load_count = 0; // ライブラリを読み込んだ回数。グローバル
jQuery(function(){
var init_display = $init_display;
/* ==============================================
* 外部ライブラリjquery.modalを動的にロード
* ============================================== */
if(typeof jQuery.modal != "function" && load_count == 0){ /* 初回のみライブラリを読み込む */
++load_count;
var src = 'https://cdnjs.cloudflare.com/ajax/libs/jquery-modal/0.9.1/jquery.modal.min.js';
var script = jQuery('<script>').attr({
'type': 'text/javascript',
'src': src,
});
jQuery('head')[0].appendChild(script[0]);
console.log("load " + src);
var link = jQuery('<link>').attr({
'rel': 'stylesheet',
'href': 'https://cdnjs.cloudflare.com/ajax/libs/jquery-modal/0.9.1/jquery.modal.min.css',
});
jQuery('head')[0].appendChild(link[0]);
}
var count = 0;
/* ==============================================
* 外部ライブラリが実行されている時だけ一度実行するようインターバル実行
* ============================================== */
var timer = setInterval(function(){
++count;
if(typeof jQuery.modal == "function"){
//console.log("■開始 count=" + count + "回目 ----------------------------------------------");
clearInterval(timer); /* 最初の実行したらインターバル実行キャンセル */
var modal_option = {$modal_option};
if(init_display == 1){
console.log("init_display=1");
jQuery("#{$modal_id}").modal(modal_option);
{$onpopup};
}
}
}, 100);
});
</script>
{$popup_html}
EOF;
$html = do_shortcode($html); //ショートコードの中のショートコードを展開
return $html;
}
add_shortcode('popup', 'popup');
/*
* **************************************************************************
* 文字列の中のURLパラメータバインド変数({%パラメータ名})を実際の値に置換
* **************************************************************************
*/
function replace_req_params($atts, $content){ //こちらをショートコードに登録
//パラメータ初期化
extract(shortcode_atts(array(
'encode' => 'esc_html', //使用するエンコードorエスケープ関数 esc_html, urlencode
), $atts));
if($encode != "esc_html" && $encode != "urlencode"){
return null; //それ以外エンコード指定は危ないので出力しない
}
return replace_req_params_base($atts, $content);
}
function replace_req_params_base($atts, $content){ //こちらはショートコードに登録はしない
//パラメータ初期化
extract(shortcode_atts(array(
'encode' => 'esc_html', //使用するエンコードorエスケープ関数 esc_html, urlencode, none
), $atts));
//複数ヒットするとmatchesはこうなる
//print_r($matches);
// Array
// (
// [0] => Array
// (
// [0] => {%from}
// [1] => {%from}
// [2] => {%to}
// )
// )
if($encode != "esc_html" && $encode != "urlencode" && $encode != "none"){
return null; //それ以外エンコード指定は出力しない
}
$content = do_shortcode($content);
preg_match_all('|\{%[a-z0-9\-_\[\]]+\}|', $content, $matches); //{%パラメータ名}を全てマッチさせる
if(count($matches) > 0){
//{%パラメータ名}を1つ1つループ
foreach($matches[0] as $idx => $param_str){
$param_name = str_replace(
array("{%", "}")
, ""
, $param_str
);
$param_val = null;
if(isset($_GET[$param_name])){
$param_val = $_GET[$param_name];
}
//{%パラメータ名}を実際に変換
if($encode == "none"){
$content = str_replace($param_str, $param_val, $content);
}else{
$content = str_replace($param_str, $encode($param_val), $content);
}
}
}
return $content;
}
add_shortcode('replace_req_params', 'replace_req_params'); /* ショートコードを登録 */
/*
* **********************************
* 離脱防止ポップアップのトリガー設置
* **********************************
*/
function popup_stop_exit($atts, $content){
/*******************************************************************************
【入力パラメータ$attsの内容】
enabled => ポップアップ 0=無効 1=有効
init_display => 0=デフォルトで出さない 1=デフォルトで出す
modal_option => jQuery.modalに渡すオプション配列をJS連想配列の記述で。
デフォルト {escapeClose: true, clickClose: false, showClose: true,}
escapeClose → Escキーを押したときに閉じるか
clickClose → 暗い背景をクリックしたときに閉じるか
showClose → 閉じる×アイコンを表示するか
onpopup => ポップアップしたときに実行するスクリプト。スクリプトの文字列囲みには'を使用。
onclick => 画像型の場合にクリックしたときに実行するスクリプト。スクリプトの文字列囲みには'を使用。
popup_after_sec => 何秒後にポップアップ出すか。0は無効
popup_slidein_selector => スクロールしてこのセレクタの要素を持つHTMLタグが画面内に入ったらポップアップ出す(最初の1回だけ)
popup_cursorout => ブラウザのウィンドウからカーソルが外に出た(カーソルアウト)時にポップアップを出す(ブラウザアラートなし)
popup_background => ウィンドウがバックグラウンド移行時にポップアップを出す(ブラウザアラートなし)
popup_browserback => ブラウザの「戻る」でポップアップを出す(ブラウザアラートなし) ※注1
popup_page_trans => リンクのクリックによるページ移動やウィンドウの閉じるを防止(ブラウザアラート「キャンセル」選択後にポップアップを出す) ※スマホのウィンドウの閉じるは制御不能
page_trans_through_links => popup_page_transによるページ移動のブラウザアラートを出さないURL条件文字列を指定できる。カンマ区切りで複数指定可能。"/cat, /dog"とすればこれらの文字列をURLに含むリンクをクリックしてもアラートは出ない。
※注1) ブラウザ自体の仕様により画面に対してタッチなど何かしらのアクションをした後でないとブラウザバック関するアクションは起動しない
********************************************************************************/
//パラメータ初期化
$new_atts = shortcode_atts(array(
'enabled' => 1,
'modal_id' => 'ss-popup-banner',
'init_display' => 0,
'banner_url' => '',
'link_url' => '',
'modal_option' => '{escapeClose: true, clickClose: false, showClose: true,}',
'onpopup' => '',
'onclick' => '',
'popup_after_sec' => 0,
'popup_slidein_selector' => '',
'popup_cursorout' => 0,
'popup_background' => 1,
'popup_browserback' => 1,
'popup_page_trans' => 1,
'page_trans_through_links' => '',
), $atts);
extract($new_atts);
/***********************************************
* 入力パラメータチェック
************************************************/
if($enabled == "0"){
return null;
}
//ポップアップ本体のショートコードを実行してHTML取得
$popup_html = popup($new_atts, $content);
if($popup_html == null){ //popup自体が無効なら終了
return null;
}
//popup_after_secが数字でないなら無効
if(is_numeric($popup_after_sec) == false){
$popup_after_sec = 0;
}
if($popup_cursorout != 1){
$popup_cursorout = 0;
}
if($popup_background != 1){
$popup_background = 0;
}
if($popup_browserback != 1){
$popup_browserback = 0;
}
if($popup_page_trans != 1){
$popup_page_trans = 0;
}
//page_trans_through_links_selectorで指定された除外パスをjqueryセレクタに変換
$page_trans_through_links_selector = "";
if($popup_page_trans == 1) {
$links = explode(",", $page_trans_through_links);
$i = 0;
foreach ($links as $loop_link) {
if ($i > 0) {
$page_trans_through_links_selector .= ",";
}
$page_trans_through_links_selector .= "a[href*=\"{$loop_link}\"]";
++$i;
}
}
/***********************************************
* 出力するHTMLを設定
************************************************/
$html =<<<EOF
{$popup_html}
<script>
//ブラウザの履歴を仮想的に操作
function addHistory(){
let hash = location.hash;
if(hash != '#back') {
history.pushState(null,null,location.href);
history.replaceState(null,null,'#back');
}
}
$(function(){
var modal_option = $modal_option;
var popup_cursorout = {$popup_cursorout};
var popup_background = {$popup_background};
var popup_browserback = {$popup_browserback};
var popup_page_trans = {$popup_page_trans};
var popup_after_sec = {$popup_after_sec};
var popup_slidein_selector = "{$popup_slidein_selector}";
//「〇秒後にポップアップ」の処理
if(popup_after_sec > 0){
setTimeout(function(){
//if(popuped_slidein == false){ //スクロールによるポップアップが出てない時だけ
console.log("popup_after_sec");
jQuery("#{$modal_id}").modal(modal_option);
{$onpopup};
//}else{
// console.log("popup_after_sec スキップ");
//}
}, popup_after_sec * 1000);
}
//「スクロールで指定要素をこえたらポップアップ」の処理
if(popup_slidein_selector){
var popuped_slidein = false;
$(window).scroll(function(){
var top = $(popup_slidein_selector).offset().top; // ターゲットの位置取得
console.log("ターゲット位置 " + $(window).scrollTop() + "/" + position);
var position = top - $(window).height(); // ターゲットが上からスクロールしたときに見える位置
if(
$(window).scrollTop() > position
){
console.log('{$popup_slidein_selector}現れた popuped_slidein=' + popuped_slidein);
if(typeof jQuery.modal == "function" && popuped_slidein == false){ //modalがあれば一度だけ表示
popuped_slidein = true;
jQuery("#{$modal_id}").modal(modal_option);
{$onpopup};
console.log('popuped_slidein 出た');
}else{
console.log('popuped_slidein スキップ');
}
}else{
console.log('#{$modal_id}現れない');
}
})
}
//「画面からカーソルアウトしたらポップアップ」の処理
if(popup_cursorout == 1){
$("html").on("mouseleave", function() {
console.log("mouseout");
jQuery("#{$modal_id}").modal(modal_option);
{$onpopup};
});
}
//「画面からフォーカスが外れた(バックグラウンドになった)らポップアップ」の処理
if(popup_background == 1){
$(window).on("blur", function() {
console.log("blur");
jQuery("#{$modal_id}").modal(modal_option);
{$onpopup};
});
}
//「ブラウザバックしたらポップアップ」の処理
if(popup_browserback == 1){
addHistory(); /* 履歴を追加 */
/* 戻るを押したら(設定した履歴が消えたら)実行する */
$(window).on("popstate", function() {
console.log("history.popstate");
if(location.hash != "#back"){
jQuery("#{$modal_id}").modal(modal_option);
{$onpopup};
}
});
}
//「リンクのクリックによる移動や画面を閉じる等でブラウザアラートを出す」処理 ※ポップアップは「キャンセル」選択後
if(popup_page_trans == 1){
/* 目的の遷移の場合はbeforeunloadをオフに */
$('{$page_trans_through_links_selector},a[href=""],a[href^="#"]').on('click', function(e) {
console.log("beforeunload off!!!");
$(window).off('beforeunload');
});
/* リンクによるページの移動やウィンドウタブを閉じる場合ブラウザ警告を出す */
$(window).on("beforeunload", function() {
console.log("beforeunload");
jQuery("#{$modal_id}").modal(modal_option);
{$onpopup};
return "このページから移動してよろしいですか?"; /* 空でないreturn必要 */
});
}
});
</script>
EOF;
return $html;
}
add_shortcode('popup_stop_exit', 'popup_stop_exit');