I have a javascript/jQuery cookie confirmation box on my site as shown here: http://jsfiddle.net/x7rAk/1/
var checkCookies = document.cookie;
var cookieNotice = '<div id="continue_box" class="cookie_box"><p>This website uses cookies to improve the user experience. For more information on cookies please see this link. By clicking continue, you agree to the use of cookies.</p><p class="cookies_accept"><span class="cookie_button" id="continue"><img src="/images/tick.png"/><span> Continue</span></span></p></div>';
$('body').ready(function() {
$('body').prepend($(cookieNotice).fadeIn(2000));
});
var continueButton = 'span#continue.cookie_button';
var closeButton = 'span#close.cookie_button';
var closeNotice = '<div id="close_box" class="cookie_box" style="display:none"><p>You have agreed to the use of cookies. This allows us to bring you a better service by remembering your preferences.</p><p class="cookies_accept"><span class="cookie_button" id="close"><img src="/images/cross.png"/><span> Close</span></span></p></div>';
$('#continue_box.cookie_box').ready(function() {
$(continueButton).click(function() {
$('#continue_box.cookie_box').fadeOut(1000, function() {
$('body').prepend($(closeNotice).fadeIn(1000));
});
});
});
$(closeButton).click(function() {
$('#close_box.cookie_box').fadeOut(2000);
});
This is missing images and fonts etc. but it works exactly the same as on my site.
If you run the code, you will see that the box doesn't disappear when you click close.
First of all, how do I fix it, and secondly why does mine not work (I like to know why so I don't have to waste your time again :) ).
Thank you,
Connor
P.S. On my site it checks whether you have a cookie called cookiesAgree before showing it so the code is normally more sophisticated.
This should work
$(document).on("click", closeButton, function() {
$('#close_box.cookie_box').fadeOut(2000);
});
The content is being added dynamically, so you need to register the event handler.
Related
There have already been answers to this question but I am still unsure exactly how it works.
I am using the following HTML in my footer.php:
<div id="popup">
<div>
<div id="popup-close">X</div>
<h2>Content Goes Here</h2>
</div>
</div>
and the following Javascript:
$j(document).ready(function() {
$j("#popup").delay(2000).fadeIn();
$j('#popup-close').click(function(e) // You are clicking the close button
{
$j('#popup').fadeOut(); // Now the pop up is hiden.
});
$j('#popup').click(function(e)
{
$j('#popup').fadeOut();
});
});
Everything works great, but I want to only show the pop up once per user (maybe using the cookie thing all the forum posts go on about) but I do not know exactly how to incorporate it into the JS above.
I know that I will have to load the cookie JS in my footer with this:
<script type="text/javascript" src="scripts/jquery.cookies.2.2.0.min.js"></script>
But that is all I understand, can anyone tell me exactly how the JS/jQuery should look with the cookie stuff added?
Thanks
James
*Note : This will show popup once per browser as the data is stored in browser memory.
Try HTML localStorage.
Methods :
localStorage.getItem('key');
localStorage.setItem('key','value');
$j(document).ready(function() {
if(localStorage.getItem('popState') != 'shown'){
$j('#popup').delay(2000).fadeIn();
localStorage.setItem('popState','shown')
}
$j('#popup-close, #popup').click(function() // You are clicking the close button
{
$j('#popup').fadeOut(); // Now the pop up is hidden.
});
});
Working Demo
This example uses jquery-cookie
Check if the cookie exists and has not expired - if either of those fails, then show the popup and set the cookie (Semi pseudo code):
if($.cookie('popup') != 'seen'){
$.cookie('popup', 'seen', { expires: 365, path: '/' }); // Set it to last a year, for example.
$j("#popup").delay(2000).fadeIn();
$j('#popup-close').click(function(e) // You are clicking the close button
{
$j('#popup').fadeOut(); // Now the pop up is hiden.
});
$j('#popup').click(function(e)
{
$j('#popup').fadeOut();
});
};
You could get around this issue using php. You only echo out the code for the popup on first page load.
The other way... Is to set a cookie which is basically a file that sits in your browser and contains some kind of data. On the first page load you would create a cookie. Then every page after that you check if your cookie is set. If it is set do not display the pop up. However if its not set set the cookie and display the popup.
Pseudo code:
if(cookie_is_not_set) {
show_pop_up;
set_cookie;
}
Offering a quick answer for people using Ionic. I need to show a tooltip only once so I used the $localStorage to achieve this. This is for playing a track, so when they push play, it shows the tooltip once.
$scope.storage = $localStorage; //connects an object to $localstorage
$scope.storage.hasSeenPopup = "false"; // they haven't seen it
$scope.showPopup = function() { // popup to tell people to turn sound on
$scope.data = {}
// An elaborate, custom popup
var myPopup = $ionicPopup.show({
template: '<p class="popuptext">Turn Sound On!</p>',
cssClass: 'popup'
});
$timeout(function() {
myPopup.close(); //close the popup after 3 seconds for some reason
}, 2000);
$scope.storage.hasSeenPopup = "true"; // they've now seen it
};
$scope.playStream = function(show) {
PlayerService.play(show);
$scope.audioObject = audioObject; // this allow for styling the play/pause icons
if ($scope.storage.hasSeenPopup === "false"){ //only show if they haven't seen it.
$scope.showPopup();
}
}
You can use removeItem() class of localStorage to destroy that key on browser close with:
window.onbeforeunload = function{
localStorage.removeItem('your key');
};
The code to show only one time the popup (Bootstrap Modal in the case) :
modal.js
$(document).ready(function() {
if (Cookies('pop') == null) {
$('#ModalIdName').modal('show');
Cookies('pop', '365');
}
});
Here is the full code snipet for Rails :
Add the script above to your js repo (in Rails : app/javascript/packs)
In Rails we have a specific packing way for script, so :
Download the js-cookie plugin (needed to work with Javascript Cokkies) https://github.com/js-cookie/js-cookie (the name should be : 'js.cookie.js')
/*!
* JavaScript Cookie v2.2.0
* https://github.com/js-cookie/js-cookie
*
* Copyright 2006, 2015 Klaus Hartl & Fagner Brack
* Released under the MIT license
*/
;(function (factory) {
var registeredInModuleLoader = false;
if (typeof define === 'function' && define.amd) {
define(factory);
registeredInModul
...
Add //= require js.cookie to application.js
It will works perfectly for 365 days!
You might be using an API for fetching user from database, so use any unique data like id or email or name to identify user then use localstorage method suggested by #Shaunak D. Just replace key with user's unique field and value with popup state.
Like:
ID : popup_state
Sorry for the mistakes in the reply. I am not on my pc today 😅😛
I want to be able to hide and unhide a lengthy menu with a button click, and that I have been able to do. But I don't want visitors to have to hide the menu every time they visit a new page, so I would like their last click to be remembered. This I have not been able to do. Any help is appreciated. I am even open to a better way to do this.
The code I thought would work, but doesn't, is:
$(document).ready(function(){
$("button").click(function(){
$("div.themenu").toggle(100);
});
});
$(function(){
if($.cookie){
$("#themenu").toggle(!(!!$.cookie("toggle-state")) || $.cookie("toggle-state") === 'true');
}
$('#menubutton').on('click', function(){
$("#themenu").toggle();
$.cookie("toggle-state", $("#themenu").is(':visible'), {expires: 1, path:'/'});
});
});
The code for the button they click is:
<button id="menubutton" class="myButton">Show / Hide Menu</button>
And the long, long menu is shown like this:
<div class="themenu">Long Long Menu Code</div>
Just for fun: here's an alternative solution which doesn't require a cookie, but sets a URL parameter:
//on page load
if (location.href.match('menu=show'))
$("#themenu").toggle();
//for every link click, block & redirect with menu=show if menu is visible
$(document.body).on('mousedown', 'a', function(e) {
e.preventDefault();
var menuParam = (location.href.match('?') ? '&' : '?') + 'menu=show';
location.href = $("#themenu").is(':visible') ? this.href + menuParam: this.href;
});
localStorage is a good place to store this kind of state. Setting is as easy as localStorage.menu = 'hidden' or localStorage.menu = 'visible', checking can be done with (localStorage && localStorage.menu==='hidden'). People with REALLY old browsers won't get the feature but that's a very small slice of users. This setting will live across visits to the site but only in the same browser. There is an issue with some browsers in 'private browsing' mode. They sometimes make localStorage cause an error when modified.
I want to use intro.js with more than two pages.
Is it a simple way to do it?
Yes, you can. If you look at code for intro.js example with multiple pages https://github.com/usablica/intro.js/tree/master/example/multi-page you can see that first page has code that redirects to second page after user click the button:
<script type="text/javascript">
document.getElementById('startButton').onclick = function() {
introJs().setOption('doneLabel', 'Next page').start().oncomplete(function() {
window.location.href = 'second.html?multipage=true';
});
};
</script>
And on the second page we use regex to check if user is going through intro. You will need to add code like that to each page, with url address to the page that should be shown next.
If you want to have more than one "intro flows" (since the question title said multiple), you can give them names or numbers. Then, instead of adding multipage=true you can use multipage=beta_version or multipage=1 and use reqex to check if user should see intro, and if yes, which one.
<script type="text/javascript">
if (RegExp('multipage', 'gi').test(window.location.search)) {
document.getElementById('startButton').onclick = function() {
introJs().setOption('doneLabel', 'Next page')
.start().oncomplete(function() {
if (RegExp('multipage=2', 'gi').test(window.location.search)) {
window.location.href = 'third.html?multipage=2';
}
else {
window.location.href = 'unicorn.html?multipage=3';
}
});
};
}
</script>
That might be not the nicest code ever :), but ( like Rich said ) without more information I can only guess this is what you want to do? But hopefully, it will give a general idea.
if (RegExp('multipage', 'gi').test(window.location.search)) {
introJs().setOption('doneLabel', 'Next Page →').start().oncomplete(function() {
window.location.href = 'nextpage?multipage=true';
});
}
I was able to use intro.js for a complex multipage use (more complete than their official multipage example). See the issue I opened about it associated to my React solution on Codesandbox.
TL;DR: Trying to fire a manual javascript click event on the chat button of twitch, won't send the message. Don't understand why the event doesn't do the same as a normal click and don't know how to make it work.
So I am trying to make a custom bot for twitch.tv, only reading his info from the HTML directly. I've got it perfectly working up to the point at where it can recognize commands and put text in the textbox. Now the problem I have is, as soon as I try to fire a manual click event on the "chat" button, it just doesn't seem to work. My guess is it has something to do with ember.js, and I frankly don't know anything about that. Anyway, here is the part of the code that doesn't work. EDIT: this works if I enter it as single in the console, doesn't work in context of the rest of my code though.
$('.send-chat-button').click();
What happens here is that I acquire a piece of html that contains the chat submit button, which is this:
<button class="button primary float-right send-chat-button" data-bindattr-3945="3945">
<span>
Chat
</span>
</button>
When I try to manually fire a click event on this, nothing happens. However, when I fire a manual click event on buttonContain.children[0] and buttonContain.children1 (which are, respectively, the settings and list of viewers buttons), it does work. They look like this:
<a data-ember-action="3943" class="button glyph-only float-left" title="Chat Settings"></a>
I'm guessing the difference is in the data-ember-action and the data-bindattr-*, but I don't know how to make it work. Anyone here knows why the click() event doesn't work and directly clicking does?
EDIT: If you have any questions about my question, feel free to ask.
EDIT2: I experimented a little more, and I can remove all HTML attributes from the button, and clicking on it will still work. I have no idea what is going on :(.
EDIT3: Okay, so it seems it only stops working when i remove the
Span within the button
Still no idea what is going on. (Yes, have also tried to fire the click event on the span)
EDIT4: As requested, here is all the code from my side. Note that I'm trying to click a button from twitch itself, of which ember side I do not own any code. This code is used by pasting it in the console on a twitch.tv stream and then starting it by calling initiateMessageProcessing. I'm sorry for the lot of hardcoded values, those are twitch' fields that I need. For now I'm just looking for a proof of concept.
var frequency = 5000;
var myInterval = 0;
var lastMessageId = 0;
function initiateMessageProcessing() {
if (myInterval > 0) {
clearInterval(myInterval);
}
myInterval = setInterval("checkMessages()", frequency);
}
function checkMessages() {
var chat = document.getElementsByClassName("chat-lines")[0];
processMessages(extractUnprocessedMessages(chat.children));
lastMessageId = parseInt(chat.lastElementChild.getAttribute("id").substring(5, 10));
}
function extractUnprocessedMessages(chat) {
var unprocessedMessages = [];
var chatId = 0;
for ( i = 0; i < chat.length; i++) {
chatId = parseInt(chat[i].getAttribute("id").substring(5, 10));
if (chatId > lastMessageId) {
unprocessedMessages.push(chat[i]);
}
}
return unprocessedMessages;
}
function processMessages(unprocessedMessages) {
var messageElement;
for ( i = 0; i < unprocessedMessages.length; i++) {
messageElement = unprocessedMessages[i].children[0].getElementsByClassName("message")[0];
if (messageElement != undefined && messageElement != null) {
if (messageElement.innerHTML.search("!test") !== -1) {
sendMessage('Hello world!');
}
}
}
}
function sendMessage(message) {
fillTextArea(message);
var button = $('.send-chat-button').get(0);
var event = new MouseEvent('click', {
bubbles : true
});
button.dispatchEvent(event);
}
function fillTextArea(message){
var textArea;
var chatInterface = document.getElementsByClassName("chat-interface")[0];
var textAreaContain = chatInterface.children[0];
textArea = textAreaContain.children[0].children[0];
textArea.value = message;
}
EDIT5: Eventlistener screenshot:
EDIT6: Edited source code to use $('.send-chat-button').click();
I have tried this, does not work in the current code, it does work if I manually fire this single command in the console when there is text in the chat. But sadly does not work in my code.
EDIT7: used Ember.run, still doesn't work.
EDIT8: used dispatchmouseevent, still doesn't work in context of code
It seems that the target site attaches event listeners without help of JQuery. If it is so, you cannot trigger it using jquery .click() method.
You can try directly mocking the browser event like this:
var button = $('.send-chat-button').get(0);
var event = new MouseEvent('click', {bubbles: true});
button.dispatchEvent(event);
This code will not work in IE8 and lower, but I guess it is not your case.
I know this post is quite old but I had been looking for an answer on this for a while and nothing really worked, after trying out A LOT of stuff I found it works when you focus the chatbox first then focus the button then triggering the click event!!! uuuhm yeah...
$('.chat_text_input').focus();
$('.send-chat-button').focus().trigger('click');
I have no idea why this works (and why it doesn't in any other way), but leaving any of the focusses out makes it fail or bug out.
Programmatically clicking a DOM element to make some action done is somewhat a wrong approach.
You should have define a method myAction() which will be called in two ways. First, from your ember action triggerMyAction() and second, after listening to a custom event, "myEvent".
Instead of $('.send-chat-button').click(); you will code $('something').trigger("myEvent") then.
Something like:
Em.Controller.extend({
myAction:function(){
//do your stuff
},
onMyEvent:function(){
$('something').on('myEvent',this.myAction);
}.on('didInsertElement'),
actions:{
triggerMyAction:function(){
this.myAction();
}
}
})
I am trying to fire a script when the contents of a div are altered, specifically when a div receives the next set of results from a js loaded paginator.
I have this:
<script script type="text/javascript" language="javascript">
document.addEventListener("DOMCharacterDataModified", ssdOnloadEvents, false);
function ssdOnloadEvents (evt) {
var jsInitChecktimer = setInterval (checkForJS_Finish, 111);
function checkForJS_Finish () {
if ( document.querySelector ("#tester")
) {
clearInterval (jsInitChecktimer);
//do the actual work
var reqs = document.getElementById('requests');
var reqVal = reqs.get('value');
var buttons = $$('.clicker');
Array.each(buttons, function(va, index){
alert(va.get('value'));
});
}
}
}
</script>
This works well when the doc loads (as the results take a few seconds to arrive) but I need to narrow this down to the actual div contents, so other changes on the page do not fire the events.
I have tried:
var textNode = document.getElementById("sitepage_content_content");
textNode.addEventListener("DOMCharacterDataModified", function(evt) {
alert("Text changed");
}, false);
But the above does not return anything.
Can what I am trying to do be done in this way? If yes where am I going wrong?
Using Social Engine (Zend) framework with MooTools.
I did this in the end with a little cheat :-(
There is a google map loading on the page that sets markers to match the location of the results. So I added my events to the end this code namely: function setMarker() {}.
I will not mark this as the correct answer as it is not really an answer to my question, but rather a solution to my problem, which is localised to the Social engine framework.
I will add a Social engine tag to my original question in the hope it may help someone else in the future.
Thanks guys.