I have this function (transComplete) which performs the task of highlighting a relevant indicator showing the user which page they are on, each element of these controllers/indicators represents a page and will highlight appropriately.
This works independently however when I introduce a click function that allows to interact with indicators to move between pages it navigates correctly but does not highlight as needed (works only every two clicks) which leads me to believe its a logic issue in my code.
The boolean logic of true/false is the cause, the highlighting only occurs on the 'true' cases of the variable "isOnSecond" so I essentially need a solution that always highlights the relevant controller when clicked
The main function is below:
function transComplete() {
slideTransStep = 0;
crtSlideIndex = nextSlideIndex;
// for IE filters, removing filters re-enables cleartype
if (nextSlide.style.removeAttribute) {
nextSlide.style.removeAttribute("filter");
// show next slide
showSlide((crtSlideIndex >= totalSlides) ? 1 : crtSlideIndex + 1);
//Highlights a nav circle every two transitions as the boolean alternates
if (isOnSecond == true) {
//unhighlight all controls
for (var i = 0; i < slidesControllersCollection.length; i++) {
if (slidesControllersCollection[i].className === slideHighlightClass) {
slidesControllersCollection[i].className = "";
}
// highlight the control for the next slide
document.getElementById("slide-control-" + crtSlideIndex).className = slideHighlightClass;
}
isOnSecond = false;
}
else {
isOnSecond = true;
}
}
The onclick Function:
function clickSlide(control) {
showSlide(Number(control.id.substr(control.id.lastIndexOf("-")+1)),true);
}
I think you made your trans function when you were still iterating from one page to the very next, now that user can go any frame, you need to clear any highlight each time, then put it again on current one.
Or rather, for performance's sake, store the last highlighted, then highlight the new one.
But ... why not just drop the 'onSecond' logic ? It doesn't make much sense for the user to get a highlight one time over two only...
Anyway if you keep it the onSecond idea, logic would be :
if (lastHighlighted) lastHighlighted.className = "";
if (isOnSecond) {
lastHighLighted = document.getElementById("slide-control-" + crtSlideIndex);
lastHighLighted.className = slideHighlightClass;
} else {
lastHighLighted = null;
}
isOnSecond = ! isOnSecond;
But in fact i wonder if what you want is not the version without onSecond logic :
if (lastHighlighted) lastHighlighted.className = "";
lastHighLighted = document.getElementById("slide-control-" + crtSlideIndex);
lastHighLighted.className = slideHighlightClass;
(Rq declare lastHighlighted as a var so it can be in the scope of transComplete)
Related
I'm trying to implement a functionality where the user can only order a set amount of times (let's take 5 times for example) before an alert shows up saying that the product he is trying to order has ran out of stock.
He can still of course, order other product that haven't been clicked on 5 times.
The problem I'm facing is that I don't know how to keep count of each order button (an anchor acting as a button) specifically.
I tried implementing that functionality and it does show an alert, but it takes count of all order buttons clicked.
This is how my functions looks:
let counter = 0; //global variable
function order_func() {
let every_product= document.querySelectorAll(".all_prods");
for (let each_prod = 0; each_prod < every_product.length; each_prod++) {
every_product[each_prod].addEventListener("click", function (e) {
if(count_stuff < 10){
add_it(e, each_prod); //e to preventDefault() and console.log "each_prod"
count_stuff++;
}else{
out_of_stock(e); //shows the alert it takes the event as argument to prevent default behavior.
}
});
}
}
add_it() is just a function that console.log()'s the product.
I'm only using vanilla JS, I don't want to use any other libraries for this :)
you can use data attribute to store temp values in page. take a look on this example using JQuery.
<!-- index.html -->
Order
<script>
$('#order-btn').click(function() {
var maxCounts = this.data('maxCounts');
var count = this.data('count');
if (count >= maxCount) {
alert('you cant order any more');
return;
}
this.data('count',count++);
// other logic .e.g Ajax call
})
</script>
you can do it using vanilla JS also:
<script>
let counter = 0; //global variable
function order_func() {
let every_product= document.querySelectorAll(".all_prods");
for (let each_prod = 0; each_prod < every_product.length; each_prod++) {
every_product[each_prod].addEventListener("click", function (e) {
var count_stuff = e.target.dataset.count; // or this.dataset.count
var max_count = e.target.dataset.maxCounts; // or this.dataset.maxCounts
if(count_stuff < max_count){
add_it(e, each_prod);
e.target.dataset.count = count_stuff++;
}else{
out_of_stock(e);
}
});
}
}
</script>
I want to display dynamic information (score) in the window tab of a javascript games running in a browser (chrome) : my goal is to run several instances of the game in different tabs, running in parallel, and to be able to see the current scores in the tab titles. I tried :
document.title = score
... but it works only in the selected tab, the other one are not refreshed until selected (although the games are running well in background).
==> is there a way to force the update of the tab titles... even if not selected ?
I found couple of same questions on the http://stackoverflow.com but they did not work for me.
You can find your solution here: http://www.raymondcamden.com/2010/10/19/Using-JavaScript-to-update-the-browser-window-title-when-the-user-is-away
So, basically that kind of code will work:
var focused = true;
var baseTitle = "";
var chatsMissed = 0;
//I'm the fake function that represents some process. We randomly determine if a new chat happened
function fakeStuff() {
if(Math.random() > 0.5) {
if(!focused) {
chatsMissed++;
window.document.title = baseTitle + " ("+chatsMissed+")";
}
}
}
$(document).ready(function() {
//store the base title
baseTitle = window.document.title;
//When the window is focused...
$(window).focus(function() {
focused = true;
// window.document.title = baseTitle;
//chrome bug: http://heyman.info/2010/oct/7/google-chrome-bug-when-setting-document-title/
setTimeout(function() {
document.title = baseTitle;
}, 100);
chatsMissed = 0;
});
//When the window is blurred...
$(window).blur(function() {
focused = false;
});
//setup a process
window.setInterval('fakeStuff()',2000);
})
Unfortunately JSfiddle do not support title changing. But I tested, and it works.
Basics:
I have a webpage which loads several content divs to a page, then shows them sequentially when the user clicks on the "load more" link.
Example here: JSFiddle Example
$("#load-more").click(function(e) {
var t = $(this);
if (t.data('disabled')){
return;
}
var hiddenGroups = $('.group:not(:visible)');
if (hiddenGroups.length > 0){
hiddenGroups.first().show();
} else{
t.data('disabled', true);
}
});
I have two questions based on this example:
1) The "load more" link should hide its self when the final div is showing, but is not functioning correctly in my example.
however, I'd really like it to:
2) Hide the "load more" div, and instead show/change the functionality to "Hide Items" and hide the content divs in reverse order upon click.
This is how I would do it:
JSFIDDLE
The idea:
Set a variable instructing if you are toggling more or less
var load = 'more';
check if we are loading more or less
and a function to switch the direction and the button text, to stop copy/pasting the same javascript.
Although there are only two things happening in the function, i'm working on the assumption this might grow as your application grows - if this was not to grow then it may be worth getting rid of the function andjust adding the code with the rest
The full snippet:
var load = 'more';
$("#load-more").on('click',function (e) {
// show the next hidden div.group, then disable load more once all divs have been displayed
// if we are loading more
if (load == 'more') {
// get the amount of hidden groups
var groups = $('.group:not(:visible)');
// if there are some available
if (groups.length > 0) {
// show the first
groups.first().show();
// if that was the last group then set to load less
if (groups.length == 1) {
switchLoadTo('less');
}
}
// we are loading less
} else {
// get the groups which are currently visible
var groups = $('.group:visible');
// if there is more than 1 (as we dont want to hide the initial group)
if (groups.length > 1) {
// hide the last avaiable
groups.last().hide();
// if that was the only group available, set to load more
if (groups.length == 2) {
switchLoadTo('more');
}
}
}
});
function switchLoadTo(dir) {
load = dir;
$("#load-more").html('Load ' + dir);
}
http://jsfiddle.net/8Re3t/20/
See snippet below. Probably not the most optimized code, but you get the idea and can optimize it on implementation.
var load = true;
$("#load-more").click(function(e) {
// show the next hidden div.group, then disable load more once all divs have been displayed
var t = $(this);
if (t.data('disabled')){
return;
}
var hiddenGroups = $('.group:not(:visible)');
if(load) {
hiddenGroups.first().show();
} else {
$('.group:visible').last().hide();
}
if (hiddenGroups.length > 1){
jQuery("#load-more").html("Load");
load = true;
} else {
jQuery("#load-more").html("Hide");
load = false;
}
});
I have a SUBMIT and SAVE button for a form that are by default listening for Onclick events.
When the form is SUBMITTED OR SAVED - the page resets the scroll position to the TOP of the page.
Recently the users of the applications have requested that the page stay at the bottom of the page where the buttons are located for only a subset of forms.
(These buttons are used across hundreds of other forms so I cannot change the reset of the scrolling globally.)
So the solution that I am trying to implement involves a couple hidden input fields and a few event listeners.
I have added an onmousedown event for these buttons, like so -
// Submit and Save button listeners
var globalButtons;
if (v_doc.getElementsByClassName) {
globalButtons = v_doc.getElementsByClassName('globalbuttons');
}
// Internet Explorer does not support getElementsByClassName - therefore implement our own version of it here
else {
globalButtons = [];
var myclass = new RegExp('\\b'+'globalbuttons'+'\\b');
var elem = v_doc.body.getElementsByTagName("input");
for (var i = 0; i < elem.length; i++) {
var classes = elem[i].className;
if (myclass.test(classes)) {
globalButtons.push(elem[i]);
}
}
}
for (var gb = 0; gb < globalButtons.length; gb++) {
if (globalButtons[gb].name == 'methodToCall.route' ||
globalButtons[gb].name == 'methodToCall.save') {
if(globalButtons[gb].addEventListener) { //all browsers except IE before version 9
globalButtons[gb].addEventListener("mousedown", function(){flagSpecialScrollOnRefresh()},false);
}
else {
if(globalButtons[gb].attachEvent) { //IE before version 9
globalButtons[gb].attachEvent("onmousedown",function(){flagSpecialScrollOnRefresh()});
}
}
}
else { continue; }
}
This code is located in a function called attachButtonListeners
Next, I defined my handler like so and placed it into another function that gets called each time my page is being loaded -
function checkSpecialScrollCase() {
var spfrm = getPortlet();
var sp_doc = spfrm.contentDocument ? spfrm.contentDocument: spfrm.contentWindow.document;
var specialScrollExists = sp_doc.getElementById(docTypeButton).value;
if (specialScrollExists == "YES") {
sp_doc.getElementById(docTypeButton).value = 'NO';
}
// else - nothing to do in this case
}
docTypeButton = REQS_BUTTONS
And it references the following element at the bottom of my JSP page -
<input type="hidden" id="REQS_BUTTONS" value="NO"/>
<a name="anchorREQS"></a>
Notice the anchor tag. Eventually, I need to add the location.hash call into my handler so that I scroll to this location. That part is irrelevant at this point and here is why.
Problem -
My flagSpecialScrollOnRefresh function is NOT setting the value to YES when it should be.
I believe my onClick event is happening too fast for my onmousedown event from happening.
Evidence -
If I place an alert statement like so -
function flagSpecialScrollOnRefresh() {
var scfrm = getPortlet();
var sc_doc = scfrm.contentDocument ? scfrm.contentDocument: scfrm.contentWindow.document;
alert("BLAH!");
sc_doc.getElementById(docTypeButton).value = "YES";
}
And then I examine the element using Firebug - the value is getting SET!
Once I take out the alert - no go!
How do I ensure that my mousedown event gets executed first? Or is this even the problem here????
mousedown is part of a click event.
Whatever you are doing with click events now should be moved to the submit event on the form. That way you can use mousedown, mouseover, or even click on the buttons to do whatever you want.
I have a voting script with an arrow system (upvotes and downvotes).If user clicks upvote, the arrow changes to the green arrow, meaning vote registered. If they click again, I want the arrow to revert back to the original image. However, using my code, it changes the image on the first like, but doesn't revert back on a second click.
if (like.src = 'vote_triangle.png') {
like.src = 'vote_triangle_like.png';
} else {
like.src = 'vote_triangle.png';
}
Use a more lenient if statement like:
if (like.src.indexOf('vote_triangle.png')!=-1) {
like.src = 'vote_triangle_like.png';
} else {
like.src = 'vote_triangle.png';
}
I know it's a very old thread, but I would like to add my findings here for future reference.
I found the following code wasn't working:
function swapImage() {
var element = document.getElementById("myImage");
if (element.src == "image1.png") {
element.src = "image2.png";
} else {
element.src = "image1.png"
}
}
Showing alerts containing the element.src taught me it contained the full path to the image in my local machine. Thus, the if statement had been always evaluated to false.
To fix that in a logical manner, what I did was get the attribute of the element, as the following code shows.
function swapImage() {
var element = document.getElementById("myImage");
if (element.getAttribute("src") == "image1.png") {
element.src = "image2.png";
} else {
element.src = "image1.png";
}
}
By using the function getAttribute("attributeName"), I was able to retrieve the path contained in the src relatively to the project directory.
I would suggest, instead of using img soruce as conditional statement, use a global variable, change its state once the upvote is clicked by say +1 and for downvotes -1.
//when 0, show upvote image, make it a global by declaring before any function
var UpVote = 0;
//when upvote clicked, when greater than 0, show down vote img
UpVote = UpVote +1 ;
//conditional logic for img source
if(UpVote > 0){
like.src = 'vote_triangle.png';
}
else{
like.src = 'vote_triangle_like.png';
}