i have the following function written in javascript which operate a slide up/down box. but in firefox, it malfunctions. it just opens/closes once. after that no play.
i am getting the height() param from the box and storing it in hidden input. but firefox is unable to read the correct height of the box.
look at the code to understand better :
JS :
function boxCollapse() {
$("#boxHeight").attr("value", parseInt($("#accTipsBox").height()));
$("#accTipsBox").animate({height:'0px'});
$(".btnCollapse").css({display:'none'});
$(".btnExpand").css({display:'block'});
$("#accTipsBox").css({padding:'0px'});
}
function boxExpand() {
$("#accTipsBox").animate({height: $("#boxHeight").attr("value")});
$(".btnExpand").css({display:'none'});
$(".btnCollapse").css({display:'block'});
$("#accTipsBox").css({padding:'0px'});
}
HTML :
<section class="accBox grey">
<header>
<div class="title">DISCLAIMERS</div>
<a style="display: none;" class="btnExpand" href="javascript:void(0);"><img src="/resources/images/boxExpandGrey.jpg" alt="button"></a>
<a style="display: block;" class="btnCollapse" href="javascript:void(0);"><img src="/resources/images/boxCollapseGrey.jpg" alt="button"></a>
</header>
<div id="accTipsBox" style="height: 125px; padding: 0px;">
<input type="hidden" id="boxHeight" value="125">
<div class="accBoxContent">
<div><p></p><p></p><p></p></div>
</div>
</div>
</section>
I think this is what you were going for:
//bind a `click` event handler to all the elements with the `btnExpandCollapse` class
$('.btnExpandCollapse').on('click', function (event) {
//stop the default behavior of clicking the link (stop the browser from scrolling to the top of the page)
event.preventDefault();
//first select the parent of this element (`header` tag) and then get its sibling element that has the `accTipsBox` class, then take that element and slide it up or down depending on its current state
$(this).parent().siblings('.accTipsBox').slideToggle(500);
});
With some slight tweaks to your HTML:
<section class="accBox grey">
<header>
<div class="title">DISCLAIMERS</div>
<!-- Notice there is only one link now that does the job of both -->
<a class="btnExpandCollapse" href="#"><img src="/resources/images/boxExpandGrey.jpg" alt="button"></a>
</header>
<!-- Notice I changed the ID attribute to CLASS so this code will work for repeated structure -->
<div class="accTipsBox" style="height: 125px; padding: 0px;">
<div class="accBoxContent">
<div>
<p>1</p>
<p>2</p>
<p>3</p>
</div>
</div>
</div>
</section>
Here is a demo: http://jsfiddle.net/VGN64/
Here is some documentation:
.slideToggle(): http://api.jquery.com/slidetoggle
.siblings(): http://api.jquery.com/siblings
On a side-note, if you want to store data about a DOM element, use jQuery's $.data() method:
var $box = $("#accTipsBox");
$.data($box[0], 'height', $box.height());
You can then access this data like this
var height = $.data($('#accTipsBox')[0], 'height');
Notice that I appended [0] onto the end of the jQuery object to return just the DOM node associated with the object, this is required by the $.data() method: http://api.jquery.com/jquery.data. This is a very fast method of storing data associated with DOM elements.
Related
I have two divs on a page (id's MAY and JUNE) and two buttons on the page. The page startes off by showing the May div, with the June div hidden using css display: none
I am trying to create the correct javascript that will toggle between the two of them, but (after searching on here) I can only manage to get one to work.
Codepen showing issue is https://codepen.io/billteale/pen/zwBBez
<a href="#" id="button" >MAY</a>
<a href="#" id="button" >JUNE</a>
<!-- first div, shows on page load -->
<div id="MAY">
<div style="background-color: lightgrey"><h1 style="padding: 5px"><strong>May 2017</strong></h1>
</div>
<!-- second div, hidden originally -->
<div class="hidden" id="JUNE">
<div style="background-color: lightgrey"><h1 style="padding: 5px"><strong>June 2017</strong></h1>
</div>
...and the current js is
var button = document.getElementById('button'); // Assumes element with id='button'
button.onclick = function() {
var div = document.getElementById('MAY');
if (div.style.display !== 'none') {
div.style.display = 'none';
}
else {
div.style.display = 'block';
}
};
Eventually I will have four or more divs to toggle between, with each button showing its relevant div, and hiding the others.
Can anybody tell me how to add to the code I have here to make this work for multiple elements?
It can be done by setting the div id's in the anchor tag's href attribute, and showing the corresponding div while hiding the rest. It can be done for any number of div's with no extra script, Just add the new div id to the new anchor tags href. You should give a common class to all the div's like month to select them all.
$("a.btn").click(function() {
var id = $(this).attr("href");
$("div.month:visible").hide();
$(id).show();
});
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
MAY
JUNE
<!-- first div, shows on page load -->
<div id="MAY" class="month">
<div style="background-color: lightgrey">
<h1 style="padding: 5px"><strong>May 2017</strong></h1>
</div>
</div>
<!-- second div, hidden originally -->
<div class="month hidden" id="JUNE">
<div style="background-color: lightgrey">
<h1 style="padding: 5px"><strong>June 2017</strong></h1>
</div>
</div>
First you add a "div-toggle" class to each one of the divs you want to toggle. After that, you bind click events on your buttons, firing a function which takes an identifier as argument.
The function will run through your divs and set the one that has the argument id as visible, and hide the others.
This way you can add more divs to be toggled. You just have to mark them with the "div-toggle" class, set their id's and create their respective buttons.
var divs = document.getElementsByClassName('div-toggle');
function toggle(id) {
for (var i = 0; i < divs.length; i++) {
var div = divs[i];
if (div.id == id)
div.style.display = 'block';
else
div.style.display = 'none';
}
}
<a href="#" onclick="toggle('MAY')" >MAY</a>
<a href="#" onclick="toggle('JUNE')" >JUNE</a>
<!-- first div, shows on page load -->
<div class="div-toggle" style="display:block;" id="MAY">
<div style="background-color: lightgrey">
<h1 style="padding: 5px"><strong>May 2017</strong></h1>
</div>
</div>
<!-- second div, hidden originally -->
<div class="div-toggle" style="display:none;" id="JUNE">
<div style="background-color: lightgrey">
<h1 style="padding: 5px"><strong>June 2017</strong></h1>
</div>
</div>
div.style.visibility = "hidden"
this will completely hide your div. I'm pretty sure this is what you are asking for
also instead of that you can make a separate function and add o'clock to div
<div onclick="nameoffunction()"></div>
the function can take in a parameter and each div on click function can have the parameter of its id
Your div were messed up! The snippet is working now with the help of jQuery.
$("#JUNE").hide();
$("#MAY").show();
$('#button-may').on("click", function() {
$("#JUNE").hide();
$("#MAY").show();
});
$('#button-june').on("click", function() {
$("#JUNE").show();
$("#MAY").hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
MAY
JUNE
<!-- first div, shows on page load -->
<div id="MAY">
<div style="background-color: lightgrey">
<h1 style="padding: 5px"><strong>May 2017</strong></h1>
</div>
</div>
<!-- second div, hidden originally -->
<div class="hidden" id="JUNE">
<div style="background-color: lightgrey">
<h1 style="padding: 5px"><strong>June 2017</strong></h1>
</div>
</div>
UPDATED
I think I may have inadvertently made the question confusing. This is an update that is more specific with updated code based on comments and answer I have been given so far. Thank you to everyone that has taken the time to comment and answer.
How can I get the ID of a <div> with the class of .button when I have a click listener for .button. If .button or any of its children are clicked, it should return the ID for that particular div with the class of .button.
This is what I have so far: New JSFiddle
HTML
<div class="row">
<div id="b1" class="button">
<h2>Button 1</h2>
</div>
<div id="b2" class="button">
<h2>Button 2</h2>
</div>
<div id="b3" class="button">
<h2>Button 3</h2>
</div>
</div>
jQuery
var selected = "";
$('.button').on('click', function(e) {
selected = e.target.id;
$('.button').css('backgroundColor', '#becde5');
$('#' + selected).css('backgroundColor', '#3b71c6');
$('#selected').html(selected);
});
This is almost correct but does not propagate, if I click on a <h2> the function does not work. However if I click on the .button div itself it works.
Initial Question
I am trying to create a general function that can identify what child was selected from its parents click listener. The child may have its own children that would all be considered part of the same element so that if any of these children where selected they should also elicit the same response from the click listener.
This is an example of what I have working so far: JSFiddle
HTML consisting of three buttons that all have one child <h2> tag and share the <div class="row"> as their parent.
<div class="row">
<div class="b1 button">
<h2 class="b1">Button 1</h2>
</div>
<div class="b2 button">
<h2 class="b2">Button 2</h2>
</div>
<div class="b3 button">
<h2 class="b3">Button 3</h2>
</div>
</div>
jQuery that listens for a click on <div class="row">. It retrieves the first class name of the clicked element and stores it in a variable. The elicited response in this case is a change of the CSS style background-color though this is arbitrary and would change depending on the use of the function.
var selected = "";
$('.row').on('click', function(e) {
selected = e.target.className.split(" ")[0];
$('.b1, .b2, .b3').css('backgroundColor', '#becde5');
$("." + selected).css('backgroundColor', '#3b71c6');
$('#selected').html(selected);
});
The fact that I am adding a lot of classes to elements purely to identify them on a click seems like it would not scale very well and is generally a bad approach. This method also means that I would always have to put the class name that identifies what element was selected at the beginning of its HTML class attribute. This could potentially clash with other functions using the same method.
Is there a better way to identify what child element was selected from its parents click listener, where a child may have other children that also require the same response from the listener?
EDIT based on the edited question:
I think that what you really want is the id of the element that triggered the event.
But by using e.target you have the target element... which is not necessarily the element that triggered the event.
See in this updated Fiddle.
So simply use $(this) as the selector to retrieve the id... Using .attr("id").
;)
Answer to the initial question:
To determine what can be "selected", I used a "clickable" class.
To avoid using id or class as an identifier to determine what has been clicked,
a data attribute can be usefull.
I used data-id... But you can use whatever you want, like: data-selected or data-target, and assign whatever value to it.
In the below code, I made two exactly identical rows, except their data-id value.
var selected = "";
$('.clickable').on('click', function(e) {
e.stopPropagation(); // To prevent bubbling.
// Reset all bg colors
$('.button').css('backgroundColor', 'initial');
$('.row').css('backgroundColor', 'initial');
// Find exactly what was clicked
if ($(this).hasClass("row")) {
var row = $(this).data("id");
selected = row + " (whole)";
}
if ($(this).hasClass("button")) {
// Find in which row
var row = $(this).closest(".row").data("id");
var btn = $(this).data("id");
selected = btn + " in " + row;
}
// Pale all buttons
$('.button').css('backgroundColor', '#becde5');
// Change bg color of the selected element
$(this).css('backgroundColor', '#3b71c6');
$('#selected').html(selected);
});
.row {
display: table;
width: 100%;
color: white;
border-spacing: 20px;
}
.button {
display: table-cell;
border-radius: 12px;
background-color: #6fa1f2;
text-align: center;
}
#selected {
font-size: 30px;
color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span>Selected : <span id="selected">no selection</span></span><br>
<div class="row clickable" data-id="row1">
<div class="button clickable" data-id="btn1">
<h2>Button 1</h2>
</div>
<div class="button clickable" data-id="btn2">
<h2>Button 2</h2>
</div>
<div class="button clickable" data-id="btn3">
<h2>Button 3</h2>
</div>
</div>
<br>
<div class="row clickable" data-id="row2">
<div class="button clickable" data-id="btn1">
<h2>Button 1</h2>
</div>
<div class="button clickable" data-id="btn2">
<h2>Button 2</h2>
</div>
<div class="button clickable" data-id="btn3">
<h2>Button 3</h2>
</div>
</div>
no need to id the subject, since it was the one clicked, i.e. e.target which with jQuery you cant select like $(e.target) without any trouble
then you need .closest('.button') to search up to the parent .button (if any)
$('.row').on('click', function(e) {
$('.row > .button').css('backgroundColor', '#becde5');
$(e.target).closest('.button').css('backgroundColor', '#3b71c6');
console.log($(e.target).html());
});
.button {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="row">
<div class="button">
<h2>Button 1</h2>
</div>
<div class="button">
<h2>Button 2</h2>
</div>
<div class="button">
<h2>Button 3</h2>
</div>
</div>
If you avoid giving an identifier (classes, IDs, etc) you'd need to do some manual checking for tag type to see what you clicked on (so basically, an identifier as well)
Here's an example, and not very memory efficient method
jsfiddle example
$('.row, .row *').on('click', function(e) {
e.stopPropagation()
$('.button').removeClass('active')
$('.button').css('backgroundColor', '#becde5');
$(this).toggleClass('active')
$('#selected').html(e.target.tagName + ': ' + e.target.className);
});
If you bind a click to div.row and clicked the h2 tag inside the button, and want to manipulate the h2 tag, you could check its tagName- but that less scalable than your OP.
I have the following html generated by shortcodes generated by functions.php in a WordPress parent theme:
<div class="pricing-table-one left full-width ">
<div class="pricing-table-one-border left">
<div class="pricing-table-one-top pricing-table-green left" style="background:#95705b">
<span style="color:">Restaurant / Café</span>
<p style="color:"></p>
</div>
<div class="pricing-table-one-center pricing-table-white left">
<h5>ONTBIJT</h5>
</div>
<div class="pricing-table-one-center pricing-table-white left">
<h5>LUNCH</h5>
</div>
<div class="pricing-table-one-center pricing-table-white left">
<h5>BRUNCH</h5>
</div>
<div class="pricing-table-one-center pricing-table-white left">
<h5>DINER</h5>
</div>
<div class="pricing-table-one-center pricing-table-white left">
<h5>WEST-FRIESE KOFFIETAFEL</h5>
</div>
<div class="pricing-table-one-center pricing-table-white left">
<h5>SALADESCHOTELS</h5>
</div>
<div class="pricing-table-one-center pricing-table-white left">
<h5>EN NOG VEEL MEER</h5>
</div>
<div class="color-buttons color-button-blue pricing-button">
Voor meer informatie – Email ons
</div>
</div>
</div>
I need to make one of the titles in a cell or the div containing it a link to a pdf. I read here that I can do this on an id with jQuery like so:
$("div").click(function(){
window.location=$(this).find("a").attr("href"); return false;
});
But his is only working when you change the html. I prefer a Jquery or JavaScript solution only. On CSS Tricks I found another snippet that may help
$(".myBox").click(function() {
window.location = $(this).find("a").attr("href");
return false;
});
I only would need to change the a element to div and the class to the class of the div. However, I need this done with a few specific divs (some items inside the table, but not all) and it only has one sort of useful class:
<div class="pricing-table-one-center pricing-table-white left"><h5>BRUNCH</h5></div>
Perhaps by focussing on parent div with class "pricing-table-one" and then the div inside it. But then I still need the nth div or h5 tag..
Is this possible to achieve creating a link of BRUNCH or other h5 tags with this exising HTML code with JavaScript or jQuery or will I have to change to PHP code server side?
I upvoted his answer but, here's a quick snippet of what I mean. This is assuming you have no control over the html.
$(function () {
// pdf urls and header names
var pdfUrls = {
'BRUNCH': 'http://domain.nl/wp-content/uploads/2015/02/09/x.pdf',
'DINER': 'http://domain.nl/wp-content/uploads/2015/02/09/y.pdf'
};
// loop through each h5 tag within pricing-table-one
$('.pricing-table-one h5').each(function (i, el) {
var header = $(el).text();
// if a header url is found
if (pdfUrls[header]) {
$(el).wrap('');
}
});
});
Here's a fiddle: http://jsfiddle.net/pbzvszxo/
I am not getting your question exactly.
But, I thinks you want to wrap the div with <a>- it will make your div as link -
You can do something like below code.
$(function(){
$( ".pricing-table-one-center" ).wrap( "<a href='#'></a>" );
});
.wrap() - The wrap() method wraps specified HTML element(s) around each selected element.
I have a problem with my jQuery code, I want the page to slideToggle one div ones the other is clicked, the problem is that I don't want to write all the code again and again so I tried to create a code that works all the time, but I'm stuck. Box is the div which should be clicked and it should contain a class that's also used on the div that's gonna slideToggle. It should pull the class from the tab and then use it to slideToggle the right object. Please help :S (the elements are not placed close to each other which makes next or children not possible). If you have any questions - ASK!
The jQuery code of mine:
$(".box").click(function() {
var Klassen = $(this).attr("class");
$("Klassen").slideToggle(300);
});
HTML:
<!-- These should be clicked -->
<div data-toggle-target="open1" class="box ft col-lg-3">
<div class="mer">
Läs mer
</div>
<div class="bild"><img src="images/sakerhet.jpg"></div>
<h4>HöstlovsLAN</h4>
</div>
</a>
<div data-toggle-target="open2" class="box st col-lg-3">
<div class="mer">
Läs mer
</div>
<div class="bild"><img src="images/sakerhet.jpg"></div>
<h4>NyårsLAN</h4>
</div>
<div data-toggle-target="open3" class="box tt col-lg-3">
<div class="mer">
Läs mer
</div>
<div class="bild"><img src="images/sakerhet.jpg"></div>
<h4>Säkerhet</h4>
</div>
<!-- These should be toggled -->
<div class="infobox" id="open1">
<h1>HöstlovsLAN</h1>
</div>
<div class="infobox" id="open2">
<h1>NyårsLAN</h1>
</div>
<div class="infobox" id="open3">
<h1>Säkerhet</h1>
</div>
EDIT - NEW PROBLEM - STILL AIN'T WORKING!
The code didn't work in my situation and would like you to take a look at the JS-fiddle I created:
http://jsfiddle.net/Qqe89/
undefined has presented the solution.
I would warn you about using this approach, if you add any classes to the .box div then your code will break.
Instead consider using data attributes to target the div to be toggled:
<div data-toggle-target="open1" class="box green"></div>
<div id="open1">
Opens
</div>
Which can then target with
$('.box').click(function (e) {
$( '#' + $(this).data('toggleTarget') ).slideToggle(300);
});
jsFiddle with example using your html - crudely formatted sorry!
$(".box").click(function() {
var Klassen = $(this).attr("class");
$("."+Klassen).slideToggle(300);
});
class attribute may contain several classes ($(this).attr("class") OR this.className)
$("."+Klassen) will not work if there are several classes
"Klassen" does not correspond to any DOM element as there is no such tag in HTML.
i want to alert the user if there are changes inside the div, or if any of the children divs content has changed,
the div that i'm trying to detect is inside an object!
this is my code:
<object type="text/html" data="https://secure.brosix.com/webclient/?nid " style="width:710px;height:555px; border:none;">
</object>
<script>
$('#BrosixChatReceive').bind('contentchanged', function() {
// do something after the div content has changed
alert('woo');
});
$('#BrosixChatReceive').trigger('contentchanged');
</script>
code inside the Object "With no Changes"
<div class="BrosixChatReceive" id="BrosixChatReceive" style="width: 344px; height: 476px; "></div>
this is the code when changes has been made from the div inside the object:
<div class="BrosixChatReceive" id="BrosixChatReceive" style="width: 344px; height: 476px; ">
<div class="BrosixChatWith" id="chatwith-85905" style="display: block; ">
<div class="BrosixChatItemOther"><div class="BrosixChatItemTime">18:34:36</div>
<div class="BrosixContactUsername" style="font-weight:bold;">person1</div>
<div class="BrosixChatMessage">message 1</div>
</div>
<div class="BrosixChatItemOther"><div class="BrosixChatItemTime">18:36:02</div>
<div class="BrosixContactUsername" style="font-weight:bold;">person1</div>
<div class="BrosixChatMessage">message 2</div>
</div>
<div class="BrosixChatItemOther"><div class="BrosixChatItemTime">18:36:54</div>
<div class="BrosixContactUsername" style="font-weight:bold;">person1</div>
<div class="BrosixChatMessage">message 3</div>
</div>
</div>
<div class="BrosixChatWith" id="chatwith-91218" style="display: none; ">
<div class="BrosixChatItemOther"><div class="BrosixChatItemTime">18:35:07</div>
<div class="BrosixContactUsername" style="font-weight:bold;">person2</div>
<div class="BrosixChatMessage">message 1</div>
</div>
</div>
</div>
is there any way to detect this changes, and alert the user when this changes has been made?
"ALSO I have no way to change the code of the webpage inside the OBJECT"
so this has to be done without editing the content of the object.
Here's a function similar to the one I proposed in another answer :
function survey(selector, callback) {
var input = $(selector);
var oldvalue = input.html();
setInterval(function(){
if (input.html()!=oldvalue){
oldvalue = input.html();
callback();
}
}, 100);
}
survey('#yourdivid', function(){console.log('changed')});
The callback given to survey is called each time the div with id yourdivid is changed. The check is done every 100 ms.
But a better solution is usually to change the script modifying the div to get the alert directly.
As you mention "another webpage" I must warn you that this can't work if the content comes from another domain.