The two functions when a user clicks the next button will call the next() and fbsharing() function.
next swaps between 4 divs that will display only one at a time (WORKING)
fbsharing (will display a customised share button in a div id=fbshare (FAIL)
here is my jsfiddle : http://jsfiddle.net/U3jdm/
<div id="content" style="width:60%; float:left; padding: 10px 10px 10px 10px;">
<div id="ncholder">
<div id="ncframe"></div>
<div class="PortSwap" id="swap0">
111111111111
</div>
<div class="PortSwap" id="swap1">
2222222222
</div>
<div class="PortSwap" id="swap2">
333333333
</div>
<div class="PortSwap" id="swap3">
4444444444
</div>
</div>
<div id="ncnav" style="width:83%; float:left; padding: 30px 10px 10px 10px;">
<div style="width:30%; float:right; color:#66ce9d; font-size:18px; font-weight:bold;">
<div style="width:30px; height:30px; float:left;"><img src="leftnav.png" alt="Previous" onClick="(function(){prev(); fbSharing();})();"/></div>
<div style="width:30px; height:30px; float:right;"><img src="rightnav.png" alt="Next" onClick="(function(){next(); fbSharing();})();"/></div>
</div></div>
<div id="fbshare" style="color:#ed1a64; font-size:18px; font-weight:bold;"> </div>
</div>
<script>
$(function () {
"use strict";
$('.PortSwap').hide().eq(0).addClass('active').show();
});
function prev() {
var current = $('.PortSwap.active'),
prev = current.prev('.PortSwap');
console.log(prev.length, prev);
if (prev.length) {
current.hide().removeClass('active');
prev.addClass('active').show();
}
}
function next() {
var current = $('.PortSwap.active'),
next = current.next('.PortSwap');
if (next.length) {
current.hide().removeClass('active');
next.addClass('active').show();
}
}
function fbSharing() {
var test = document.getElementByClassName("PortSwap active");
var share;
var testid = test.id;
if (testid = 'swap0') {
share ="1111111";
}
else if (test.ID = 'swap1') {
share ="2222";
}
else if (test.ID = "swap2") {
share ="33333";
}
else if (test.ID = "swap3") {
share ="44444";
}
document.getElementById("fbshare").innerHTML=share;
}
</script>
Hi, Thanks for spotting my mistake on the getelementsclassname.
For a working demo of the two functions being executed onclick, here it is:
http://jsfiddle.net/79B8z/1/
I found 2 errors.
1. There is no function named getElementByClassName its getElementsByClassName (with an s)
2. document.getElementsByClassName returns a collection of HTMLElement you need the first one so you might have to use an array index notation.
Finally,
It should look like,
var test = document.getElementsByClassName("PortSwap active")[0]
JS Fiddle
To start two functions onclick just use
onclick="next(), fbsharing()"
I think thats what you mean..
Related
I have a list like this.
Inside each .list item there is a html button :
<div class="list">
<button>.list</button>
</div>
Also, each item can be inside a .bloc element
<div class="list"><button>.list</button></div>
<div class=bloc>
<div class="list"><button>.list</button></div>
</div>
When I click on the button, I would like the previous .list item to have the .active class like so :
Well it’s pretty easy with jquery and i've done that, it’s work pretty well :
$('.list button').on('click', function() {
$(this).closest('.list').prev('.list').addClass('active');
});
BUT i have some specific cases :
Sometimes the list items can be hidden and a list with hidden class can’t have .active class :
Or more complicated. You have to go up on each item one by one and put the active class to the first which does not have the hidden class :
I did the mechanics for items without class hidden, but I'm afraid I'm going in the wrong direction because the number of cases is getting bigger and bigger. Ain't there a smarter way ? :o
$('.list button').on('click', function() {
if ($(this).closest('.list').prev().length === 0) {
if ($(this).closest('.bloc').length) {
$(this).closest('.bloc').prev('.list').addClass('active');
$(this).closest('.bloc').prev('.bloc').find('.list:last-child').addClass('active');
} else {
$(this).closest('.list').next('.list').addClass('active');
}
}
if ($(this).closest('.list').prev('.bloc').length) {
$(this).closest('.list').prev('.bloc').find('.list:last-child').addClass('active');
}
$(this).closest('.list').prev('.list').addClass('active');
}
Rather than use .closest .prev and .next you can use the overload to .index which will give you the index within an existing collection.
var idx = collection.index(element);
select all your .list items into a jquery object/collection
when clicking get the index within that collection
subtract 1 to get the previous .list item within that collection
The basic scenarios are covered with $(".list") :
// collate the list first
var list = $(".list");
// add click handler
list.click(function() {
// confirm there are no duplicates
// comapred with $(this).index() which is the index within the parent
console.log(list.index(this), $(this).index())
$(".active").removeClass("active");
var idx = list.index(this);
if (idx > 0)
list.eq(idx-1).addClass("active");
});
.list { border:1px solid #CCC; height: 20px; }
.bloc { border:1px solid #444; padding: 5px; }
.active { border:1px solid red; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='wrapper'>
<div class='bloc'>
<div class='list'></div>
<div class='list'></div>
</div>
<div class='list'></div>
<div class='list'></div>
</div>
All the other use-cases are then just a case of providing the correct selector up-front, with otherwise exactly the same code
var list = $(".wrapper>.bloc:not(.hidden)>.list:not(.hidden),.wrapper>.list:not(.hidden)");
I've tried to recreate some of your scenarios, but if there's one that's missing, please comment and I'll ensure it fits (within the remit of the question).
Giving:
var list = $(".wrapper>.bloc:not(.hidden)>.list:not(.hidden),.wrapper>.list:not(.hidden)")
list.click(function() {
$(".active").removeClass("active");
var idx = list.index(this);
if (idx > 0)
list.eq(idx-1).addClass("active");
});
.list { border:1px solid #CCC; height: 20px; }
.bloc { border:1px solid #444; padding: 5px; }
.active { border:1px solid red; }
.hidden { background-color: #ccc; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='wrapper'>
<div class='bloc'>
<div class='list'></div>
<div class='list'></div>
</div>
<div class='list hidden'></div>
<div class='bloc'>
<div class='list hidden'></div>
<div class='list hidden'></div>
</div>
<div class='list'></div>
<div class='bloc'>
<div class='list hidden'></div>
<div class='list'></div>
</div>
<div class='list'></div>
<div class='list'></div>
<div class='bloc hidden'>
<div class='list'></div>
<div class='list'></div>
</div>
<div class='list'></div>
<div class='list'></div>
</div>
I have two div's within a parent div. I need to change the classes for the child div which I clicked. For that I am writing a method to check which child was clicked and respectively I am trying to hide the other child div.
But I am not able to add classes or remove classes since the index is showing always as undefined. I am feeling there is some problem with the return statement.
function changeClass() {
const list = document.getElementById('my_div').children;
const indx = this.getIndexOfParent(list);
for (let i = 0; i < list.length; i++) {
if (indx === 0) {
list[indx + 1].classList.add("d-none d-sm-block");
list[indx].classList.remove("col-6 d-none d-sm-block");
} else if (indx === 1) {
list[indx - 1].classList.add("d-none d-sm-block");
list[indx].classList.remove("col-6 d-none d-sm-block");
}
list[indx].classList.add("d-xs-block");
}
}
function getIndexOfParent(child_list) {
for (var i = 0, len = child_list.length; i < len; i++) {
((index) => {
child_list[i].onclick = () => {
return index;
};
})(i);
}
}
.row {
background: #f8f9fa;
margin-top: 20px;
}
.row > div {
border: solid 1px black;
padding: 10px;
}
<div class="container">
<div class="row">
<div onclick="changeClass()" class="col-md-6 col-6">
child-div-1
</div>
<div onclick="changeClass()" class="col-md-6 col-6">
child-div-2
</div>
</div>
</div>
All I want is that, when I click on child-div-1 it should hide child-div-2 and vice versa only for small screens (which is why I am handling it by col-6 and d-xs-block classes)
Can anyone help me to solve the below problem.
You have added onclick within the for loop. Instead add the class to the clicked child div and remove the class from it's sibling div.
document.querySelectorAll('div.row > div')
.forEach((div) => {
div.addEventListener('click', function({
target
}) {
target.classList.add('d-none', 'd-sm-block');
const sibDiv = Array.prototype.filter.call(target.parentNode.children, div => div != target)[0];
sibDiv.classList.remove('col-6', 'd-none', 'd-sm-block');
});
});
.row {
background: #f8f9fa;
margin-top: 20px;
}
.row>div {
border: solid 1px black;
padding: 10px;
}
<div class="container">
<div class="row">
<div class="col-md-6 col-6">
child-div-1
</div>
<div class="col-md-6 col-6">
child-div-2
</div>
</div>
</div>
-- Edit --
The return statement will return the value of index to the callback function, you also need to add return to the callback function, so whatever result the callback function get will return to the function getIndexOfParent.
function getIndex() {
let i = 0;
((index) => { // No return, logs undefined
return index;
})(i);
}
console.log(getIndex());
function getIndex() {
let i = 0;
return ((index) => { // with return
return index;
})(i);
}
console.log(getIndex());
I made a pen for solving this problem.
Check the pen here
the solution is easy you simply have to write this line
e.stopPropagation();
this will stop the event from triggering on parent divs
basically what you are describing is called event bubbling.
you can read about it more on medium
A solution suggested by #musicnothing in an older thread displays a content div below the row of inline divs, this works good when the div.wrapblock is clicked itself.
http://jsfiddle.net/SYJaj/7/
function placeAfter($block) {
$block.after($('#content'));
}
$('.wrapblock').click(function() {
$('#content').css('display','inline-block');
var top = $(this).offset().top;
var $blocks = $(this).nextAll('.wrapblock');
if ($blocks.length == 0) {
placeAfter($(this));
return false;
}
$blocks.each(function(i, j) {
if($(this).offset().top != top) {
placeAfter($(this).prev('.wrapblock'));
return false;
} else if ((i + 1) == $blocks.length) {
placeAfter($(this));
return false;
}
});
});
The issue I'm having.
I need to trigger the same effect, but by adding the click event to a link within the wrapblock itself.
My code is nearly identical.
What I have changed is the click event handle, from $('.wrapblock').click(function() to $('.more').on('click', function() I also needed to add .closest(".wrapblock") for the content div to position itself outside of the wrapblock.
$('.more').on('click', function() {
...
if ($blocks.length == 0) {
placeAfter($(this).closest(".wrapblock"));
return false;
}
Everything can be seen and tested http://jsfiddle.net/7Lt1hnaL/
Would be great if somebody could shed some light on how I can calculate which block it needs to follow with the offset method, thanks in advance.
As you can see in the latest fiddle example, the content div is not displaying below the row of divs.
I also apologise, I wanted to post on the thread in discussion but I only have a minor posting reputation which doesn't let me, thanks.
var $chosen = null;
var $allBlocks = [];
$(function(){
$allBlocks = $('.wrapblock');
})
$(window).on('resize', function() {
if ($chosen != null) {
$('#content').css('display','none');
$('body').append($('#content'));
$chosen.trigger('click');
}
});
$('.more').on('click', function() {
$chosen = $(this);
var position = $chosen.parent('.wrapblock').position();
$('#content').css('display','inline-block');
$allBlocks.filter(function(idx, ele){
return $(ele).position().top == position.top;
})
.last()
.after($('#content'));
});
.wrapblock
{
background: #963a3a;
display: inline-block;
width: 90px;
height: 90px;
color: white;
font-size: 14px;
text-align: left;
padding: 10px;
margin: 10px;
vertical-align:top;
position:relative;
}
#content
{
display:none;
vertical-align:top;
width:100%;
background: #5582c1;
font-size: 12px;
color: white;
padding: 10px;
}
.more {
position:absolute;
bottom:15px;
right:15px;
cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<div class="wrapblock">1
<span class="more" data-ref="1">more</span>
</div>
<div class="wrapblock">2
<span class="more" data-ref="2">more</span>
</div>
<div class="wrapblock">3
<span class="more" data-ref="3">more</span>
</div>
<div class="wrapblock">4
<span class="more" data-ref="4">more</span>
</div>
<div class="wrapblock">5
<span class="more" data-ref="5">more</span>
</div>
<div class="wrapblock">6
<span class="more" data-ref="6">more</span>
</div>
<div class="wrapblock">7
<span class="more" data-ref="7">more</span>
</div>
<div class="wrapblock">8
<span class="more" data-ref="8">more</span>
</div>
<div class="wrapblock">9
<span class="more" data-ref="9">more</span>
</div>
<div id="content">Some Content</div>
Seems to do what you want. Basically, it just filters down the set of all blocks to the row of the block you clicked on using the assumption that they'll all have the same vertical offset (top), then takes the last one, because jQuery will keep them in document order, so that'll be the last one in the layout row.
Oh, and I updated the fiddle http://jsfiddle.net/7Lt1hnaL/1/
GOAL script returns 20,13,12,11
Hi I am trying to make these two operations into a single operation on Load.
when loaded the page returns 3,2,10,1
so I have added a button to trigger a +10 function.
which returns 13,12,20,11
Both these functions work independently, however i need the the entire thing to work together so that it returns 20,13,12,11 on load
I don't want any buttons>>>>
<script src="js/jquery-1.4.1.min.js"></script>
<!--CSS-->
<style type="text/css">
.box {
border: 1px solid #000;
padding: 2px;
margin: 2px;
}
</style>
<!--JAVASCRIPT-->
<!-- (A) ADDS +10 to div No-->
<script type='text/javascript'>
$(document).ready(function(){
$("#increase").click(function(event){
$("div.box").each(function(idx,elem){
$(this).text( parseInt($(this).text(),10) +10 );
});
return false;
});
});
</script>
<div id="containerSort">
<!-- (B) SORTS div -->
<script type='text/javascript'>
$(function(){
var $divs = $("div.box");
$( "#numBnt" ).one("load", function() {
console.log('loaded')
var numericallyOrderedDivs = $divs.sort(function (a, b) {
return $(a).find("h7").text() < $(b).find("h7").text();
});
$("#containerSort").html(numericallyOrderedDivs);
});
});
</script>
<!--HTML-->
<div class="box"><h7>1</h7></div>
<div class="box"><h7>2</h7></div>
<div class="box"><h7>3</h7></div>
<div class="box"><h7>10</h7></div>
<img src="http://myscot.com/ImagesMain/myscotLogoResp120.jpg" id="numBnt"/>
</div>
<button id="increase">+10</button>
window.addEventListener("load", function(){...}) how would I combine the 2 functions to the event listener?
There are 2 ways to solve your problem
Call button's click event on page load.
Create a function which will wrap everything and assign it as eventListener.
Note:
$(function(){}) is a short hand for $(document).ready() and its a bad practice to have multiple document.ready functions.
H7 is not a valid header tag as mentioned by #Niet the Dark Absol. Browser might consider it as a custom element and process similar to span tag. (This is just a guess).
Below code:
$("div.box").each(function(idx, elem) {
$(this).text(parseInt($(this).text(), 10) + 10);
});
this will make multiple DOM operation. Its bad practice to manipulate DOM in a loop.
Following is a sample code. Also I have updated your code a bit.
JSFiddle.
$(document).ready(function() {
$("#increase").trigger("click");
});
$("#increase").click(function() {
var valArr = getValues();
valArr = addNumber(valArr);
valArr = sortValues(valArr);
createAndRenderHTML(valArr, "#containerSort");
});
function getValues() {
var returnArray = [];
$("div.box").each(function(id, el) {
returnArray.push(parseInt($(el).text(), 10));
});
return returnArray;
}
function addNumber(arr) {
return arr.map(function(item) {
return parseInt(item, 10) + 10;
});
}
function sortValues(arr) {
return arr.sort(function(a, b) {
return a > b ? -1 : a < b ? 1 : 0
});
}
function createAndRenderHTML(arr, el) {
var _html = arr.map(function(item) {
return "<div class='box'> <h7>" + item + "</h7></div>"
}).join("");
$(el).html(_html);
}
.box {
border: 1px solid #000;
padding: 2px;
margin: 2px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js"></script>
<div id="containerSort">
<!--HTML-->
<div class="box">
<h7>1</h7>
</div>
<div class="box">
<h7>2</h7>
</div>
<div class="box">
<h7>3</h7>
</div>
<div class="box">
<h7>10</h7>
</div>
<img src="http://myscot.com/ImagesMain/myscotLogoResp120.jpg" id="numBnt" />
</div>
<button id="increase">+10</button>
I've created a custom function goToNext() it's just supposed to alert the id of the next element that i've clicked on.
I want to call this custom function inside another click function.
For now when I click on first element it alerts id_2 (next from the first, so it's ok) but if you click the second element it doesn't return id_3 (like it's supposed to be) but it return id_2 same if you click on the last element (supposed to alert the first)
this is my jsfiddle example here
function goToNext() {
var get_next_id = $('.btn').next().attr("id");
alert(get_next_id);
}
$('.btn').click(function() {
goToNext();
});
.btn {
width: 50px;
height: 50px;
margin: 10px auto;
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="btn" id="id-1">
1
</div>
<div class="btn" id="id-2">
2
</div>
<div class="btn" id="id-3">
3
</div>
Try this
function goToNext($btn){
var get_next_id = $btn.next().attr("id");
alert(get_next_id);
}
$('.btn').click(function(){
goToNext($(this));
});
You have to use this
function goToNext(thisObj){
var get_next_id = $(thisObj).next().attr("id");
if(get_next_id!=undefined)
alert(get_next_id);
else
alert($(thisObj).parents().find("div:first").attr("id"));
}
$('.btn').click(function(){
goToNext(this);
});
.btn{
width:50px;
height:50px;
margin:10px auto;
background-color:yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class ="btn" id="id-1">
1
</div>
<div class ="btn" id="id-2">
2
</div>
<div class ="btn" id="id-3">
3
</div>
You need to use reference this
function goToNext(e){
var get_next_id = $(e).next().attr("id");
alert(get_next_id);
}
$('.btn').click(function(){
goToNext(this);
});
Updated Fiddle