すべてのサイトページに表示されるアラートボックスをいくつか開発しました。
ユーザーは各ボックスを個別に閉じることができます。
$(document).ready(function() {
$("#close-alert-box-news").click(function() {
$("#alert-box-news").hide(800);
});
$("#close-alert-box-maintenance").click(function() {
$("#alert-box-maintenance").hide(800);
});
});
.alert-box {
width: 50vw;
position: relative;
margin: 20px auto;
border: 1px solid black;
}
.alert-box-close {
position: absolute;
top: -12px;
right: -12px;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<article class="alert-box" id="alert-box-news">
<h1>News Alerts</h1>
<p>text text text text text text text text text text text text text text</p>
<a class="alert-box-close" id="close-alert-box-news">
<img src="http://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
</a>
</article>
<article class="alert-box" id="alert-box-maintenance">
<h1>Site Maintenance</h1>
<p>text text text text text text text text text text text text text text</p>
<a class="alert-box-close" id="close-alert-box-maintenance">
<img src="http://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
</a>
</article>
ここで、ユーザーが閉じたボックス(1つでも、両方でもかまいません)、サイトの閲覧時に再表示されないこと、またはページをリロードしないことを確認する必要があります。
PHP cookieを24時間で期限切れにするように設定できると思います。しかし、このサイトの関連する投稿のほとんどはJavaScript cookieを推奨しています。残念ながら、JavaScriptソリューションを実装するための私の努力はうまくいきませんでした。 tは機能しました(ボックスを閉じると再び表示されます)。ここで概説するように、さまざまな方法を試しました。
各ボックスをサイト全体で24時間非表示にする簡単な方法は何でしょうか。
私はjQuery、プレーンJavaScript、PHP、Cookie、セッションなどを受け入れています。
localStorage()
を使用します。
ローカルストレージはオリジンごと(ドメインおよびプロトコルごと)
localStorage
にlocalStorage.setItem('desiredTime', time)
として格納しますshow/hide
_に基づいて、保存されているタイムスタンプlocalStorage.getItem('desiredTime')
で現在のタイムスタンプを確認します。jQuery
_$(document).ready(function(){
//Get current time
var currentTime = new Date().getTime();
//Add hours function
Date.prototype.addHours = function(h) {
this.setTime(this.getTime() + (h*60*60*1000));
return this;
}
//Get time after 24 hours
var after24 = new Date().addHours(10).getTime();
//Hide div click
$('.hide24').click(function(){
//Hide div
$(this).hide();
//Set desired time till you want to hide that div
localStorage.setItem('desiredTime', after24);
});
//If desired time >= currentTime, based on that HIDE / SHOW
if(localStorage.getItem('desiredTime') >= currentTime)
{
$('.hide24').hide();
}
else
{
$('.hide24').show();
}
});
_
[〜#〜] html [〜#〜]
_<div>DIV-1</div>
<div class='hide24'>DIV-2</div>
_
注意事項
$.cookie
_も使用できますが、これは現在では古いアプローチです。<div>
_の_hide24
_は非表示になります。localStorage
の場合、HTML5ブラウザが必要です。お役に立てれば。
@Loadingに続いて..答え:
アラートボックスは、リロード時に常に短時間再表示されてから消えます。何か案は?
これはなぜですか?
$(document).ready()
内の関数は、DOM全体がロードされるまで実行されます。そのため、アラートがレンダリングされ、関数が実行されるとすぐにアラートが非表示になります。
解決策:
CSSOMが構築されるまでブラウザがコンテンツをレンダリングしないことを利用するために、最初はクラスでアラートを非表示にすることができます。
使用しているクラスは、プロパティ_display: none;
_を設定しているだけです。
_.hidden {
display: none;
}
_
もちろん、これによりブラウザで再描画が発生します。 (注を参照)
あなたのロジックはすでにアラートを表示しています
_ if (localStorage.getItem('desiredTime') >= currentTime) {
$('#alert-box-news').hide();
} else {
$('#alert-box-news').show();
}
_
.show()
を使用すると、インラインスタイルの_display: block;
_が追加されるため、_.hidden
_クラスよりも特異性が高くなり、アラートが表示されます。
注:
display: none;
_を使用すると、アラートの下のコンテンツが上下にプッシュされます。必要に応じて、この回答の範囲外の_visibility: hidden;
_やtransform
などの他の方法を使用できます。次の手順を実行する図を以下に示します。
localStorage
関数をトリガーして、desiredTime
キーを設定します。最後に、キーが実際に設定されていることを確認するために、次の場所に移動します。
DevTools(F12)-> [アプリケーション]タブ-> [ローカルストレージ]-> [jsFiddleシェル]。
カウントダウンが終了した後、もう一度実行がヒットし、アラートが再び表示されます。
図:
このアプローチが実際に機能していない場合は、このアプローチの問題を解決するためにさらに詳細が必要になる場合があります。
私があなたの質問を理解している限り、アラートを24時間非表示にする(その後、アラートを表示するall 1日後に再び表示する)と、ユーザーエクスペリエンスが低下します。
ある種のデータベースからこれらのアラートをロードしていると思います。もしそうなら、適切な答えはそこにステータスを保存することです。 status
列かdeleted_at
タイムスタンプ、実装は無限大です。
いずれにせよ、アラート状態をデータベースに保存し、それに応じてプルするときにデータをフィルタリングします。
したがって、あなたの見解では(ここでphpを想定):
<?php
<?php if(!empty($newlyFilteredAlerts)): ?>
<article class="alert-box" id="alert-box-news">
<h1>News Alerts</h1>
<?php foreach(newlyFilteredAlerts as $alert): ?>
<p><?= $alert ?></p>
<?php endforeach;?
<a class="alert-box-close" id="close-alert-box-news">
<img src="http://i.imgur.com/czf8yas.png" height="25" width="25" alt="" >
</a>
</article>
<?php endif; ?>
次に、それに応じて、データベースのステータスを変更するために、ある種のエンドポイントを追加する必要があります。
$(document).ready(function() {
$("#close-alert-box-news").click(function() {
$.post({
url: '/alerts',
type: 'DELETE',
success: function () {
$("#alert-box-news").hide(800);
},
});
});
});
注:この回答は、コードを書くのではなく、正しい方向に向けることを目的としています????。上記のコードはすべて完全にテストされていないため、単にコピーして貼り付けると機能しない可能性があります。
stackoverflowでは機能しません。デモリンクでテストできます
$(document).ready(function() {
checkCookie("alertDisplayed")
$("#close-alert-box-news").click(function() {
setCookie("alertDisplayed", 'yes', 1);
$(".alert-box").hide(800);
});
$("#close-alert-box-maintenance").click(function() {
setCookie("alertDisplayed", 'yes', 1);
$(".alert-box").hide(800);
});
});
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function checkCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
$(".alert-box").hide();
}
}
return;
}
.alert-box {
width: 50vw;
position: relative;
margin: 20px auto;
border: 1px solid black;
}
.alert-box-close {
position: absolute;
top: -12px;
right: -12px;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<article class="alert-box" id="alert-box-news">
<h1>News Alerts</h1>
<p>text text text text text text text text text text text text text text</p>
<a class="alert-box-close" id="close-alert-box-news">
<img src="http://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
</a>
</article>
<article class="alert-box" id="alert-box-maintenance">
<h1>Site Maintenance</h1>
<p>text text text text text text text text text text text text text text</p>
<a class="alert-box-close" id="close-alert-box-maintenance">
<img src="http://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
</a>
</article>
クッキーとローカルストレージは異なる目的を果たします。 Cookieは主にサーバー側を読み取るためのものであり、ローカルストレージはクライアント側でのみ読み取ることができます。
あなたの場合、各HTTPヘッダーのすべてのデータを送信することで帯域幅を浪費しています。したがって、Cookieの代わりにHTMLローカルストレージを使用することをお勧めします。
技術的な違いと私の理解によると:
https://jsfiddle.net/eath6oyy/33/
$(document).ready(function() {
var currentTime = new Date().getTime();
var timeAfter24 = currentTime + 24*60*60*1000;
$("#close-alert-box-news").click(function() {
$("#alert-box-news").hide(800);
//Set desired time till you want to hide that div
localStorage.setItem('desiredTime', timeAfter24);
});
if(localStorage.getItem('desiredTime') >= currentTime)
{
$('#alert-box-news').hide();
}else{
$('#alert-box-news').show();
}
$("#close-alert-box-maintenance").click(function() {
$("#alert-box-maintenance").hide(800);
//Set desired time till you want to hide that div
localStorage.setItem('desiredTime1', timeAfter24);
});
if(localStorage.getItem('desiredTime1') >= currentTime)
{
$('#alert-box-maintenance').hide();
}else{
$('#alert-box-maintenance').show();
}
});
.alert-box {
width: 50vw;
position: relative;
margin: 20px auto;
border: 1px solid black;
}
.alert-box-close {
position: absolute;
top: -12px;
right: -12px;
cursor: pointer;
}
<article class="alert-box" id="alert-box-news">
<h1>News Alerts</h1>
<p>text text text text text text text text text text text text text text</p>
<a class="alert-box-close" id="close-alert-box-news">
<img src="http://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
</a>
</article>
<article class="alert-box" id="alert-box-maintenance">
<h1>Site Maintenance</h1>
<p>text text text text text text text text text text text text text text</p>
<a class="alert-box-close" id="close-alert-box-maintenance">
<img src="http://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
</a>
</article>
このソリューションを試してください jsfiddle そしてストレージパスに関するコメントを読んでください。 _sub domain
_で作業している場合は、setCookie()
コメントのように記述されたCookieでドメインを指定する必要があります。 _working on localhost
_の場合、cookie-domainは「localhost」ではなく「」またはNULLまたはFALSEに設定する必要があります。ドメインリファレンスについては、調べることができます このstackoverflowの質問
_function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = "expires="+ d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
// document.cookie = cname + "=" + cvalue + ";" + expires + ";domain=.example.com;path=/"; if you are trying in any sub-domain
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0)==' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length,c.length);
}
}
return "";
}
$(document).ready(function() {
if(getCookie('news')==1) { //check if cookie news exist if exist then hide.
$("#alert-box-news").hide();
}
if(getCookie('maintenance')==1) { //check if cookie maintenance exist if exist then hide.
$("#alert-box-maintenance").hide();
}
$("#close-alert-box-news").click(function() {
setCookie('news',1,1); // set cookie news to 1 for 1 day = 24 hours here setCookie(key,value,number of cookie expiration day)
$("#alert-box-news").hide(800);
});
$("#close-alert-box-maintenance").click(function() {
setCookie('maintenance',1,1); // set cookie maintenance to 1 for 1 day = 24 hours here setCookie(key,value,number of cookie expiration day)
$("#alert-box-maintenance").hide(800);
});
});
_
JavascriptのsessionStorage
でそれが可能です。
例えば :
現在の日付を保存します(var currentDate
)および1分後の日付(var afterOneMinute
)sessionStorage内。ボタンまたはリロードページをクリックするたびに、現在の日付を変更し、それらをafterOneMinute
変数と比較し、ボックスを非表示または表示した後
htmlファイル
<head>
<script src="jquery.js"></script>
</head>
<body>
<button onclick="hideOneMinute()">Hide box while 1 minute </button>
<div id="box" style="border: 1px solid red; display: inherit">
<h2>Box</h2>
hello
</div>
<div id="messageBox"></div>
</body>
[〜#〜] js [〜#〜]
<script>
var currentDate, afterOneMinute;
function addDate(){
var current = new Date();
// Converts current date in seconds
currentDate = current.getHours()*3600+current.getMinutes()*60+current.getSeconds();
// Current date + 1 minute
afterOneMinute = currentDate + 1*60;
}
addDate();
console.log(currentDate);
// verify sessionStorage when page is reloaded ;
if(typeof(Storage) !== "undefined") {
if(sessionStorage.currentDate){
addDate();
sessionStorage.currentDate = currentDate;
if(Number(sessionStorage.currentDate) < Number(sessionStorage.afterOneMinute))
{
$('#box').hide();
console.log('hide');
}
else{
sessionStorage.clear();
console.log('show');
$('#box').show();
}
}
}
function hideOneMinute() {
if(typeof(Storage) !== "undefined") {
if(sessionStorage.currentDate){
addDate();
sessionStorage.currentDate = currentDate;
if(Number(sessionStorage.currentDate) < Number(sessionStorage.afterOneMinute))
{
$('#box').hide();
}
else{
sessionStorage.clear();
console.log('show');
$('#box').show();
}
}else{
addDate();
sessionStorage.currentDate = currentDate;
sessionStorage.afterOneMinute = afterOneMinute;
console.log('hide');
$('#box').hide();
}
document.getElementById("messageBox").innerHTML = "Box will be shown at " + sessionStorage.afterOneMinute;
} else {
document.getElementById("messageBox").innerHTML = "Sorry, your browser does not support web storage...";
}
}
</script>
あなたはあなたが持っているコードに加えて24時間で期限切れになるクッキーを設定することができます:
MDN JavaScript Cookie Framework をインストールします
Jsで、Cookieの有効期限を保持するtomorrow
変数を設定します。
var today = new Date();
var tomorrow = today.setHours(today.getHours() + 24);
次のようにCookieを設定します。
docCookies.setItem('hide_news', 'true', tomorrow);
Cookieの値に基づいて条件付きでボックスを非表示にします
if (docCookies.getItem('hide_news') == 'true'){
$("#alert-box-news").add_class('hidden');
};
CSSファイルでhidden
クラスを定義します
.hidden {
display none;
}
このcodepen ですべての動作を確認できます。
24時間チェックでスクリプトを更新しました
タイムスタンプをどこにどのように保存するかは、どのコントロールを使用するかと関係があります。
関係するユーザーがいるので、サーバー側に移動して、ユーザーデータベーステーブルにこれらの状態が保持される追加のフィールドを作成します。
このように、ユーザーがCookie /ストレージをクリアできるのとは反対に、youはどのアラートを制御するかそれは隠されたままで、どのくらいの期間必要です。
2番目の利点は、これが時間に加えてロールベースであり、ユーザーとその資格情報に基づいて特定のアクションを実行できることです。
いずれにせよ、私はこのように表示/非表示を作成します。ここでは、ボックスを視覚化するかどうかを制御するクラスまたは属性をhtmlタグに格納します。
これが持つ利点は、「最初に表示してから非表示にする」問題を取り除き、サーバー側で追加するか、スクリプトを使用して機能することです。
これは、スクリプト、プレーンjavascriptを使用した簡単なサンプルです。これは決して最適化されたものではなく、単に私が示したかったロジックのためのものです。
これは、セキュリティ上の問題により、実際にはスタックスニペットとして実行されないため、次のようなフィドルが実行されます。 https://jsfiddle.net/essjuj4y/10 /
For this demo - to clear local storage
ボタンをクリックすると、ストレージがクリアされ、ページを再度実行すると、ボックスが表示されます。
/* add an event handler to be able to close a box */
var alerts = document.querySelectorAll('.alert-box-close');
for (var i = 0; i < alerts.length; i++) {
alerts[i].addEventListener('click', function(e) {
var boxtype = e.target.parentElement.id.split('-').pop();
document.getElementById('alert-box-' + boxtype).style.display = "none";
localStorage.setItem("al-" + boxtype, new Date());
})
}
/* add an event handler to be able to clear storage - for demo purpose */
document.querySelector('button').addEventListener('click', function(e) {
localStorage.clear();
})
.alert-box {
display: none;
width: 50vw;
position: relative;
margin: 20px auto;
border: 1px solid black;
}
.alert-box-close {
position: absolute;
top: -12px;
right: -12px;
cursor: pointer;
}
.al-news #alert-box-news,
.al-maintenance #alert-box-maintenance {
display: block;
}
<html>
<head>
<script type='text/javascript'>
function has24HourPassed(key) {
var storeval = localStorage.getItem(key);
if (!storeval) return true; /* nothing stored in storage */
var T24_HOUR = 24 * 60 * 60 * 1000;
if ((new Date - new Date(storeval)) < T24_HOUR) return false;
localStorage.removeItem(key); /* 24 hours passed so we can remove stored date */
return true;
}
(function(d) {
if (has24HourPassed('al-news')) {
d.classList.add('al-news');
}
if (has24HourPassed('al-maintenance')) {
d.classList.add('al-maintenance');
}
})(document.documentElement);
</script>
</head>
<body>
<article class="alert-box" id="alert-box-news">
<h1>News Alerts</h1>
<p>text text text text text text text text text text text text text text</p>
<a class="alert-box-close" id="close-alert-box-news">
<img src="http://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
</a>
</article>
<article class="alert-box" id="alert-box-maintenance">
<h1>Site Maintenance</h1>
<p>text text text text text text text text text text text text text text</p>
<a class="alert-box-close" id="close-alert-box-maintenance">
<img src="http://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
</a>
</article>
<button>For this demo - to clear local storage</button>
</body>
</html>
私の答えは @ Loadingの答え の拡張です。ユーザーがアラートを閉じることを選択した場合でも、ページの読み込み時にコンテンツのフラッシュが発生するのは、DOMの読み込み後にlocalStorageの評価が行われるためです。
したがって、JSが有効になっていないブラウザでは問題になる可能性がありますが、デフォルトでアラートを非表示にすることをお勧めします。ただし、これは、JSが検出されたときにHTML要素にクラスを追加する modernizr.js を使用すると回避でき、それに応じて基本スタイルを変更できます。例:
.alert-box {
display: none;
}
.no-js .alert-box {
display: block;
/* Other styles */
}
私のソリューションはlocalStorageを使用し、オプションを文字列化されたオブジェクトとして保存することに依存しています。ボックスごとに保存される2つのキーは、hidden
(ボックスのステータスを保存するため)とtimestamp
(時間を保存するため)です。ボックスは閉じられます)。これらを使用して、(1)ユーザーがアラートを閉じることを選択したかどうか、および(2)アクションが24時間以内に実行されたかどうかを評価できます。
私があなたのコードに加えたいくつかの変更:
動作するコードを以下に示しますが、セキュリティ上の制限により、ここではlocalStorageは動作しません。機能デモの場合、 代わりに更新されたJSfiddleを参照してください 。
$(function() {
// Check for localStorage
if (typeof window.localStorage !== typeof undefined) {
// Loop through all alert boxes
$('.alert-box').each(function() {
var $t = $(this),
key = $t.attr('id');
// If key exists and it has not expired
if (window.localStorage.getItem(key)) {
var json = JSON.parse(window.localStorage.getItem(key));
if (json.hide && json.timestamp < Date.now() + 1000 * 60 * 60 * 24) {
$t.hide();
} else {
$t.show();
}
} else {
$t.show();
}
});
}
// Bind click events to alert boxes
$('.alert-box a.alert-box-close').click(function() {
var $alertBox = $(this).closest('.alert-box');
// Hide box
$alertBox.hide(800);
// Store option in localStorage, using the box's ID as key
if (typeof window.localStorage !== typeof undefined) {
window.localStorage.setItem($alertBox.attr('id'), JSON.stringify({
hide: true,
timestamp: Date.now()
}));
}
});
// For demo purposes only, clear localStorage to ease testing
$('#clear-localstorage').click(function() {
window.localStorage.clear();
});
});
.alert-box {
display: none;
width: 50vw;
position: relative;
margin: 20px auto;
border: 1px solid black;
}
.alert-box-close {
position: absolute;
top: -12px;
right: -12px;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<article class="alert-box" id="alert-box-news">
<h1>News Alerts</h1>
<p>text text text text text text text text text text text text text text</p>
<a class="alert-box-close" id="close-alert-box-news">
<img src="https://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
</a>
</article>
<article class="alert-box" id="alert-box-maintenance">
<h1>Site Maintenance</h1>
<p>text text text text text text text text text text text text text text</p>
<a class="alert-box-close" id="close-alert-box-maintenance">
<img src="https://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
</a>
</article>
<button id="clear-localstorage">Clear local storage (for testing)</button>
単にローカルストレージを使用する必要があります。
[〜#〜] html [〜#〜]
<article class="alert-box" id="alert-box-news">
<h1>News Alerts</h1>
<p>text text text text text text text text text text text text text text</p>
<a class="alert-box-close" id="close-alert-box-news">
<img src="https://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
</a>
</article>
<article class="alert-box" id="alert-box-maintenance">
<h1>Site Maintenance</h1>
<p>text text text text text text text text text text text text text text</p>
<a class="alert-box-close" id="close-alert-box-maintenance">
<img src="https://i.imgur.com/czf8yas.png" height="25" width="25" alt="">
</a>
</article>
Javascipt
$(document).ready(function() {
var nd = new Date();
var md = nd;
var newsclicked = false;
var maintenanceclicked = false;
setInterval(function() {
newsclicked = (localStorage.getItem("newsclicked")) ? new Date(localStorage.getItem("newsclicked")) : false;
maintenanceclicked = (localStorage.getItem("maintenanceclicked")) ? new Date(localStorage.getItem("maintenanceclicked")) : false;
if (maintenanceclicked === false) {
console.log(maintenanceclicked);
$("#alert-box-maintenance").show(800);
} else {
var mddiff = (md.getTime() - maintenanceclicked.getTime()) / (60 * 60 * 24 * 1000);
if (mddiff >= 1) {
$("#alert-box-maintenance").show(800);
} else {
$("#alert-box-maintenance").hide(800);
}
}
if (newsclicked === false) {
$("#alert-box-news").show(800);
} else {
var nddiff = (nd.getTime() - newsclicked.getTime()) / (60 * 60 * 24 * 1000);
if (nddiff >= 1) {
$("#alert-box-news").show(800);
} else {
$("#alert-box-news").hide(800);
}
}
}, 200);
$("#close-alert-box-news").on("click", function() {
nd = new Date();
localStorage.setItem("newsclicked", nd);
$("#alert-box-news").hide(800);
});
$("#close-alert-box-maintenance").on("click", function() {
md = new Date();
localStorage.setItem("maintenanceclicked", md);
$("#alert-box-maintenance").hide(800);
});
});
[〜#〜] css [〜#〜]
.alert-box {
width: 50vw;
position: relative;
margin: 20px auto;
border: 1px solid black;
}
.alert-box-close {
position: absolute;
top: -12px;
right: -12px;
cursor: pointer;
}
#alert-box-news,#alert-box-maintenance{
display:none; // by default have both elements hidden.
}
これが pdate のフィドルで、実際にテストします。 div
を閉じたら、ページを更新します