Simply put I'm trying to sync two slideshows created using widgetkit lib in a joomla website, eg. when user clicks next slide on one, the other one also runs nextSlide() function in the slideshow.js. Same for previous. The problems I'm having is widgetkit uses anonymous functions for creating those slideshows and I dont have global references to them after they are created. With my limited programming knowledge I cant seem to trigger the nextSlide function for other slideshows once inside click handler.
If anyone can take a look it would be most welcome.
EDIT:
Of course I forgot to link the example webpage
http://www.yootheme.com/widgetkit/examples/slideshow
Mine is similar with only 2 slideshows, but is still only on local server.
Taking a brief look at widgetkit here is one possible solution. Using jquery you can search for any objects that have a class of slides with a child of next and click all others. The code provided below isn't tested but should point you in the right direction. As long as you don't call stop propagation or prevent default then the original click handlers should still fire.
var slideshow_count = $('.slides .next').length;
var cascade_countdown = 0;
$('.slides .next').each(function() {
$(this).click(function() {
// stop an infinite loop if we're already cascading till we've done it for all the elements.
if(cascade_countdown != 0) {
cascade_countdown--;
return true;
}
// we don't include the slideshow we're clicking in this count
cascade_countdown = slideshow_count - 1;
var clicked_el = this;
$('.slides .next').each(function() {
// only click elements that aren't the initiator
if(this !== clicked_el) {
$(this).click();
}
});
});
});
Related
Background information
I am trying to make a functional chrome-extension popup-window that enables the user to add links (based on the open tab's URL) when he desires it, and deletes one link or delete all of the links in just one click. Down below are all of my files! I must say in advance that I am not very good (and not experienced) with using jQuery's library but if that's the only solution that I have, than I will use it in my code.
The problem
The buttons to delete all the links and the button to add one link does work perfectly without bugs. However, the button to which one link should be deleted doesn't work, I tried various ways including splicing. I am trying to remove the link from the DOM and from the chrome.storage.local, both actions do not work. In the following code you can see all of the files I have thus far. The code of when the 'X' button is pressed doesn't get executed (see these pictures): https://i.stack.imgur.com/gg1Dy.png and https://i.stack.imgur.com/4oGdI.png
The code
manifest.json:
gist.github.com/kobrajunior/78acda830c2d1c384333542422f1494d
popup.js:
functions to look at: addToDom and removeMe and the very first event listener when the DOM is fully loaded
gist.github.com/kobrajunior/4852f85ae18cfb9edbe542a820b8c107
For extra information (if needed), the popup.html:
gist.github.com/kobrajunior/1c26691734c19391c62dc336ed2e1791
Thank you in advance.
For the following lines in popup.js, you want to restore (show all the items/buttons) and bind listeners, however don't forget addToDom is called inside the callback of chrome.storage.local.get, that means by the time you assign value to allButtons, they're not added to DOM, that causes allButtons.length === 0 and you didn't bind anything in fact.
Try to move the binding logic inside the callback of restore (You may encounter other issues however that's not covered in this quesions).
document.addEventListener('DOMContentLoaded', function () {
restore();
var allButtons = document.getElementsByClassName('buttons');
function listenI(i) {
allButtons[i].addEventListener('click', () => removeMe(i));
}
for (var i = 0; i < allButtons.length; i++) {
listenI(i);
}
});
function restore() {
// get the tab link and title
chrome.storage.local.get({ urlList: [], titleList: [] }, function (data) {
urlList = data.urlList;
titleList = data.titleList;
// add the titles and url's to the DOM
for (var i = 0, n = urlList.length; i < n; i++) {
addToDom(urlList[i], titleList[i]);
}
});
}
I'm creating my portfolio and I'm trying to make my skill bars load when I go to "My skills" section. I want them to do it only once, either when someone scroll to this section or goes to it straight away from the navigation. This is my code:
var skills = $('#mySkills');
var skillsPositionTop = skills.position().top;
$(window).on("resize scroll", function (){
if (pageYOffset<skillsPositionTop-20 && pageYOffset>skillsPositionTop-80){
console.log ("here is my loading script");
}
});
It doesn't work when I use one instead of on, doesn't work when I created one more function on window with one inside my if statement.
I was trying exit the function with return or return false as well and here, on stack overflow I found something about flag, which I didn't fully understand but I tried different combinations with it.
Can someone please help me with it? I've seen there is a library for this type of effects, but there is no point of installing any just for one thing...
Edit. Console.log represens my loading code.
You can set a namespace at .on() for resize, scroll events, use .off() within if statement to remove namespaced events.
var skills = $('#mySkills');
var skillsPositionTop = skills.position().top;
$(window).on("resize.once scroll.once", function (){
if (pageYOffset<skillsPositionTop-20 && pageYOffset>skillsPositionTop-80) {
$(this).off("resize.once").off("scroll.once");
console.log ("here is my loading script");
}
});
I've noticed from a few different projects of mine that whenever I click something I add an onClick function to, it always takes two clicks to get them going when a page is freshly loaded. The general structure I use for them is:
function PageChange(){
var welc_p = document.getElementById("welcome");/**gathers page DIVs**/
var page01 = document.getElementById("page01");
var page02 = document.getElementById("page02");
var start = document.getElementById("start_btn");/**gathers buttons**/
var p1_back = document.getElementById("p1_back");
var p1_next = document.getElementById("p1_back");
var p2_back = document.getElementById("p2_back");
var p2_next = document.getElementById("p2_back");
start.onclick=function(){
page01.style.display="block";
welc_p.style.display="none";
window.location="#page01";
};
}/**function**/
then the way I call it in the html is
<div class="some_class" id="start_btn" onClick="PageChange()">!!!LETS GET STARTED!!!</div>
Here's a fiddle of it as well.
https://jsfiddle.net/Optiq/42e3juta/
this is generally how I structure it each time I want to create this functionality. I've seen tons of other posts on here about their items taking 2 clicks to activate but none of them were doing anything near what I was trying to accomplish and it seemed their problem was within their coding. Does anybody know why this is happening?
This is because you are attatching a event handler to your button on click of your button.
This means that one click of the button activates the event handler, not the code within start.onclick=function() {
Then, the second click works becasue the event handler has been activated, and now the code will run.
Try moving your code out of the function, then it will work with just one click
Just had the same issue, and found an easy solution based on the above answer.
Since your function needs two clicks to work, I just called the function above the function and it works fine. This way the function already gets called one time on load, then it gets called the second time when you click it.
yourFunction();
function yourFunction(){
-- content --
}
I also had the same 2 clicks required on intitial interaction and after many searches couldn't find the best solution for my specific nav menu. I tried this solution above but couldn't get it to work.
Stumbled upon this code from a youtube example and it solved my issue. I wanted to nest submenu's for multiple levels and modified it from its original implementation to work best for my responsive mobile menu.
var a;
function toggleFirstLevelMobileSubMenu(){
if(a==1){
document.getElementById("mobile-sub-menu-depth-1").style.display="none";
return a=0;
}
else {
document.getElementById("mobile-sub-menu-depth-1").style.display="flex";
return a=1;
}
}
var b;
function toggleSecondLevelMobileSubMenu(){
if(b==1){
document.getElementById("mobile-sub-menu-depth-2").style.display="none";
return b=0;
}
else {
document.getElementById("mobile-sub-menu-depth-2").style.display="flex";
return b=1;
}
}
Of course, in the CSS I had display: none set for both ID's.
First, the problem:- On first click instead of running js your browser runs the button aka the event.
Solution:- in order to resolve this we need to make sure our function is already before the event is run (this is one of the ways to solve the problem). To achive this we need to load the function aka call the function in some way.
So, i just simply called the function after function is completed.
Code answer-
Just add at the end of your code
PageChange();
I'm looking for some help to implent a timer for this script I'm linking to.
As it is now, it toggles different slides when hovering the list to the right, but I want the slider to automatically jump ahead to the next slide after a certain amount of time until it reaches the end and then goes back to the top.
The catch though is that it also needs to work as it is now, so that you can toggle via hovering and when you stop hovering it should remember the position and jump ahead to the next item.
I realize this is alot to ask for, but some pointer would be great, thanks alot!
DEMO: http://jsbin.com/acorah
Your code is taking a bit of a performance hit with that each() loop which I don't think you need. You're binding events inside the loop and you're limiting your possibilities by declaring your actions inside the bind() scope. You want to be able to call events on any object and not only a single element; $('.cn_item') in your case.
The idea is to keep track of your current slide with a class, let's say .cur.
Then you create an object where you declare all your methods. The main methods or actions are getCur() and goTo() and mostly everything else will use these. ie. next() is just a shortcut for goTo()
var actions = {
getCur: function(){ return idx; },
goTo: function(idx){
// The simplest case
$slides.hide().eq(idx).show();
},
next: function(){ this.goTo(this.getCur()+1); },
prev: function(){ this.goTo(this.getCur()-1); }
.
.
.
}
Now you can call actions on events by simply doing this:
$slides.click(function(){ actions.goTo($(this).index()); });
$next.click(function(){ actions.next(); });
And then you can setInterval() to add a timer.
setInterval(actions.next, 1000);
This tutorial might help. I basically cover everything involved in making a slider. I would change some things as of today, we learn new ways to code stuff everyday.
I am trying to make a simple searcher/highlighter and I am running into difficulties with inconsistent results/nothing happening when I test it out.
I think the biggest gap is my understanding of how the callback functions should work and what the selectors are able to match.
Ideally when one clicks on the tag, everything should fade out and only the dives with the matching tags in them should reappear. If nothing matches then the nothing found div should appear and the reset should fade veryhtign out and make all the divs (sans nomatch div) reappear unhighlighted.
Anyone provide some clarification on where I can improve?
Edit: See the link in the comments to see my code.
More clarification on problems:
Click on a tag (old, photography, guide) and then click on reset. All three parts should reappear but only two do.
Randomly The no results found will show up.
If you select a tag, then search for a different one, the fade ins and outs will be asynchronous.
The problem is that the .fadeout() was on each .workshopentry so would really be 3 fade outs. Therefore the animation complete callback function was being called 3 times as well! So the logic to determine which new entries to show and hide was being executed 3 times and causing the strange multiple fading.
I have updated the jsfiddle with a more robust solution.
Let me know if you need any more explanation of what the JavaScript is doing.
You need to copy your following code
if (toFadeIn.length < 1) { //No results found
toFadeIn.push(noResults);
}
$(toFadeIn).each(function(index, div){
div.fadeIn(1000);
});
inside the callback function of the workshop.fadeout.. like this :
workshop.fadeOut(1000, function() {
var tags = $('.left ul li', this);
tags.removeClass('searchMatch'); //reset the search results
tags.each(function() {
if ($(this).text().toLowerCase() === searchTerm.toLowerCase()) {
$(this).addClass('searchMatch');
toFadeIn.push($(this).parent().parent().parent());
}
});
if (searchTerm === "") {
toFadeIn.push(workshop);
}
if (toFadeIn.length < 1) { //No results found
toFadeIn.push(noResults);
}
$(toFadeIn).each(function(index, div){
div.fadeIn(1000);
});
});
You see? The fadeout callback was not yet called but you already started going through the toFadeIn array to show the search results. At that time it hadn't even searched through the entries yet.
It's only down to because we are mostly used to sequential code so callbacks take a little bit of head around. But it does work like that. You just keep on putting the code inside the callback ..and then again inside another callback and so on.