window resize determine controls parent is smaller or greater - javascript

I need a script to determine when the parent element width of the conrol is resized. This is determined on the windows resize event all i need is to know weither the parent is smaller or larger than before instantaneously. please leave a working example - would be apreciated thanks
JavaScript:
(function ($) {
$.fn.quicklist = function () {
var _this = this;
var config = {
quicklistParentWidth: $(_this).parent().width(),
}
var parentWidth = config.quicklistParentWidth;
$(window).resize(function (event) {
var currWidth = config.quicklistParentWidth;
$(_this).parent().css('width', config.quicklistParentWidth);
if (currWidth > parentWidth) {
$('#width').text('greater');
} else if(parentWidth < currWidth) {
$('#smaller').text('smaller');
}
parentWidth = currWidth;
});
};
})(jQuery);
$(document).ready(function () {
$('#quicklist').quicklist();
});
HTML:
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr style="height:34px">
<td style="background:url(images/classic/quicklink_bar.png) 0px 0px; background-repeat:repeat-x; width:100%;">
<ul id="quicklist">
<li>List Goes here</li>
</ul>
</td>
<td style="background:url(images/classic/quicklink_bar.png) 0px 0px; background-repeat:repeat-x; ">
<a id="link" href="#">Link</a>
</td>
</tr>
</table>
<span id="width"></span>

Here's a working version in javascript. http://jsfiddle.net/ZhG8N/
<div style="width:50%; background:#F00">not yet resized
<div id="child"></div>
</div>
<script>
var parent = document.getElementById('child').parentNode,
lastSize = parent.offsetWidth,
newSize, timer;
window.onresize = function(){
newSize = parent.offsetWidth;
if(lastSize > newSize){
parent.innerHTML = 'smaller';
}
else if(lastSize< newSize){
parent.innerHTML = 'wider';
}
lastSize = newSize;
}
</script>

Related

Accordion JS hyperlink propagation

I am working on a website with multiple accordions on each page with download links. I found a beautiful accordion by Ahmet Aksungur, but the hyperlinks don’t work with his code. I’ve tried adding preventDefault() and stopPropagation() -- $.on('click', 'a', function (e) { e.stopPropegation();}) -- – this work great (once!) – but the problem is that after the initial download, none of the accordions or download links work.
Could anyone suggest a way to stopPropagation on an event and allow normal function of the rest of the accordions. Thanks.
codepen: https://codepen.io/doncroy/pen/abZBZyL
'''
<script>
(function () {
"use strict";
var jQueryPlugin = (window.jQueryPlugin = function (ident, func) {
return function (arg) {
if (this.length > 1) {
this.each(function () {
var $this = $(this);
if (!$this.data(ident)) {
$this.data(ident, func($this, arg));
}
});
return this;
} else if (this.length === 1) {
if (!this.data(ident)) {
this.data(ident, func(this, arg));
}
return this.data(ident);
}
};
});
})();
(function () {
"use strict";
function Accordion($roots) {
var element = $roots;
var accordion = $roots.first("[data-accordion]");
var accordion_target = $roots.find("[data-accordion-item]");
var accordion_content = $roots.find("[data-accordion-content]");
$(accordion_target).click(function () {
$(this).toggleClass("opened");
$(this).find(accordion_content).slideToggle("slow");
$(this).siblings().find(accordion_content).slideUp("slow");
$(this).siblings().removeClass("opened");
});
}
$.fn.Accordion = jQueryPlugin("Accordion", Accordion);
$("[data-accordion]").Accordion();
function Ripple_Button($root) {
var elements = $root;
var ripple_btn = $root.first("[data-ripple]");
$(ripple_btn).on("click", function (event) {
event.preventDefault();
var $div = $("<div/>"),
btnOffset = ripple_btn.offset(),
xPos = event.pageX - btnOffset.left,
yPos = event.pageY - btnOffset.top;
$div.addClass("ripple-effect");
$div.css({
height: ripple_btn.height(),
width: ripple_btn.height(),
top: yPos - $div.height() / 2,
left: xPos - $div.width() / 2,
background: ripple_btn.data("ripple") || "#ffffff26"
});
ripple_btn.append($div);
window.setTimeout(function () {
$div.remove();
}, 2000);
});
}
$.fn.Ripple_Button = jQueryPlugin("Ripple_Button", Ripple_Button);
$("[data-ripple]").Ripple_Button();
})();
</script>
'''
'''
<div class="container">
<div class="aks-accordion" itemscope itemtype="https://schema.org/FAQPage" data-accordion="">
<div class="aks-accordion-row">
<div class="aks-accordion-item" itemscope itemprop="mainEntity" itemtype="https://schema.org/Question" data-accordion-item="" data-ripple="#2c612c26">
<div class="aks-accordion-item-row">
<div class="aks-accordion-item-icon">
<svg class="aks-accordion-item-icon-open" viewBox="0 0 512 512">
<path d="M492,236H276V20c0-11.046-8.954-20-20-20c-11.046,0-20,8.954-20,20v216H20c-11.046,0-20,8.954-20,20s8.954,20,20,20h216
v216c0,11.046,8.954,20,20,20s20-8.954,20-20V276h216c11.046,0,20-8.954,20-20C512,244.954,503.046,236,492,236z" />
</svg>
<svg class="aks-accordion-item-icon-close" viewBox="0 0 512 512">
<path d="M492,236H20c-11.046,0-20,8.954-20,20c0,11.046,8.954,20,20,20h472c11.046,0,20-8.954,20-20S503.046,236,492,236z" />
</svg>
</div>
<div class="aks-accordion-item-title">
<h4 itemprop="name">Dropdown Title</h4>
</div>
</div>
<div class="aks-accordion-item-content" itemscope itemprop="acceptedAnswer" itemtype="https://schema.org/Answer" data-accordion-content="">
<li><div id="#" onclick='recordVisit(this.id, "link")'><i class="fas fa-file-download"></i>PLACEHOLDER</div></li>
<li><div id="#" onclick='recordVisit(this.id, "link")'><i class="fas fa-file-download"></i>PLACEHOLDER</div></li>
<li><div id="#" onclick='recordVisit(this.id, "link")'><i class="fas fa-file-download"></i>PLACEHOLDER</div></li>
</div>
</div>
</div>
</div>
</div>
'''
I found the answer. The problem with the stopPropagation() written into the JS was that it affected the accordions globally. The solution was to use an inline onclick event on each of the links.
<li><div id="#" onclick='recordVisit(this.id, "link"); event.stopPropagation();'><i class="fas fa-file-download"></i>PLACEHOLDER</div></li>

Prevent image slideshow grows more than container cell

I'm making a little html-jquery program that generate dynamically a table where on each cell there are an slideshow. The slideshow get the images that you select from a folder inside your computer.
The problem is that when I select the folder the slideshow gets the height to 100vh for each cell with slideshow. I can't understand how prevent that the slideshow grows more than the containing cell.
HTML
<body style="height:100vh;">
<div class="row">
<div class="container-fluid">
Rows: <input id="sRows" type="number" name="" value="2">
Columns: <input id="sCol" type="number" name="" value="2">
<button id="btnGen" type="button" name="button">Generate!</button>
</div>
</div>
<div id="slideshowContiner" class="w3-table-all" >
</div>
</body>
CSS
#slideshowContiner {
table-layout: fixed;
height: 100%;
}
.slider{
max-width:100%;
max-height: 100%;
}
.mySlide{
width:100%;
height:auto;
}
For Javascript code maybe is too long for read, finally the created structure is, inside the #slideshowContiner is something like that:
<div id="slideshowContiner" class="w3-table-all">
<tr></tr>
<td style="background-color:#6a833c">
<input webkitdirectory="" mozdirectory="" msdirectory="" odirectory="" directory="" multiple="" type="file" name="file">
<div class="w3-content w3-section slider" style="">
<img class="mySlide" style="display: none;" src="blob:null/">
<img class="mySlide" style="display: none;" src="blob:null/">
<img class="mySlide" style="display: none;" src="blob:null/">
</div>
</td>
</div>
Jquery (TL:DR;)
$( document ).ready(function() {
var randomColor = function (){
return '#'+ ('000000' + Math.floor(Math.random()*16777215).toString(16)).slice(-6);
}
var sliders = []
var myIndex = 0;
function carousel() {
var i;
var slides = elem.children( ".mySlide" ).css("display", "none")
console.log(slides, this);
}
function createSlider(files){
var slider = $('<div class="w3-content w3-section slider" style=""></div>')
for (var i = 0; i < files.length; i++) {
prev = $('<img class="mySlide" style="">').attr("src", URL.createObjectURL(files[i]))
slider.append(prev)
}
sliders.push(slider)
// slider.data("id", inn++)
var myIndex = 0;
slider.data("slideshow", function(){
console.log(myIndex);
var slides = slider.children( ".mySlide" ).css("display", "none")
myIndex++;
if (myIndex > slides.length) {myIndex = 1}
console.log(slides[myIndex]);
$(slides[myIndex-1]).css("display", "block")
setTimeout(slider.data("slideshow"), 2000)
})
return slider
}
var sContainer = $("#slideshowContiner")
var sRows = $("#sRows")
var sCol = $("#sCol")
var btnGen = $("#btnGen")
function genGrid(){
sContainer.html("")
for (var i = 0; i < sRows.val(); i++) {
var newRow = sContainer.append('<tr></tr>')
// var newRow = sContainer.append('<div class="row flex-fill d-flex " style="border: 1px solid;"></div>')
for (var x = 0; x < sCol.val(); x++) {
var newCol = $('<td style="background-color:'+randomColor()+'"></td>')
newRow.append(newCol);
var input = $('<input webkitdirectory mozdirectory msdirectory odirectory directory multiple/>')
.attr('type', "file")
.attr('name', "file")
.on("change", function() {
cell = $(this).data("cell")
var s = createSlider(this.files)
cell.append(s)
// carousel(s)
var init = s.data("slideshow")();
})
.data("cell", newCol);;
newCol.append($(input))
}
}
}
genGrid()
btnGen.click(genGrid)
JsFiddle.
Note: on this fiddle the style="height:100vh;" are on the root div, on the original code are on the body tag.
You could set each image to a fixed height using a static unit such as px in your class, and use a few media queries to control their dimensions in different resolutions. This way you can expect what they will look like.

Show/hide text area box + swap between image onclick

I am creating form page where I wanted to hide text area box when clicked on image as well as to swap the image and vice-versa. Right now I am able to hide/show div but image is not displayed when text area box is hidden and also does not return to first image. There are 2 scripts one for div show/hide and another to swap image.
1. image: output before click
2. image: after hitting on an image
<script>
function showhide(id){
if (document.getElementById){
obj = document.getElementById(id);
if (obj.style.display == "none"){
obj.style.display = "";
} else {
obj.style.display = "none";
}
}
}
var onImg= "testim.png, valm.png";
var offImg= "testip.png, valp.png";
</script>
<div style="margin-top: 10px; text-align: center;">
<ul id="text_type_tab" name="text_type_tab">
<li id="PR_TEXT_TAB" class="tab_active"> <img src="testim.png" onclick="this.src = (this.src.endsWith(offImg)? onImg : offImg);" align="middle"/></li>
</ul>
</div>
<table id="hidden_content" width="80%" align="center" style="margin-bottom: 10px; margin-left: 10px; margin-right: 10px">
<tr>
<td colspan="2">
<textarea id="textInputField1" name="textInputField1" style="resize:vertical; width: 900px;" rows="15" cols="105" wrap="pre" onblur="onTextSubmitFunction('Apply')"></textarea>
</td>
</tr>
</table>
Please help.
Thanks a lot, in advance!
[1]: http://i.stack.imgur.com/7PwdK.png
[2]: http://i.stack.imgur.com/5j6FE.png
Pointer 1
Change the below variable to the absolute link of your image
var onImg= "testim.png, valm.png"; //this should be one link
var offImg= "testip.png, valp.png"; //this should be one link
(Just to be on the safe side for testing test)
example
var onImg= "https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcSHrNNGyEGlgXtd5u4fq1eQ18z8TMXHCZqf_4zI9yz6uo7N8KeXuFVRr-tR";
var offImg= "https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcR8x25Dihzxt-pilDC6-SAVJ8JEVB4VItyjJhRFFuAGNFPx5YBbR5rQST01";
Pointer 2
change
<li id="PR_TEXT_TAB" class="tab_active"> <img src="testim.png" onclick="this.src = (this.src.endsWith(offImg)? onImg : offImg);" align="middle"/></li>
</ul>
to this
<li id="PR_TEXT_TAB" class="tab_active"> <img src="testim.png" onclick="this.src = (this.src.endsWith(offImg)? onImg : offImg);" align="middle"/></li>
</ul>
that is it should be </a></li> instead of </li></a>
Pointer 3
Change this
<a href="javascript:showhide('textInputField1');">
to this
<a href="#" onclick="javascript:showhide('textInputField1')">
Attach it directly to the onclick event since href attribute simply points to a location.
here is a snippet
- <script>
function showhide(id){
if (document.getElementById){
obj = document.getElementById(id);
obj.style.display == "none"?obj.style.display = "":obj.style.display = "none";
// if (obj.style.display == "none"){
// obj.style.display = "":;
// }
//else {
// obj.style.display = "none";
//}
}
}
var onImg= "https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcSHrNNGyEGlgXtd5u4fq1eQ18z8TMXHCZqf_4zI9yz6uo7N8KeXuFVRr-tR";
var offImg= "https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcR8x25Dihzxt-pilDC6-SAVJ8JEVB4VItyjJhRFFuAGNFPx5YBbR5rQST01";
</script>
<div style="margin-top: 10px; text-align: center;">
<ul id="text_type_tab" name="text_type_tab">
<li id="PR_TEXT_TAB" class="tab_active"> <img src="https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcR8x25Dihzxt-pilDC6-SAVJ8JEVB4VItyjJhRFFuAGNFPx5YBbR5rQST01" onclick="this.src = (this.src.endsWith(offImg)? onImg : offImg);" align="middle"/></li>
</ul>
</div>
<table id="hidden_content" width="80%" align="center" style="margin-bottom: 10px; margin-left: 10px; margin-right: 10px">
<tr>
<td colspan="2">
<textarea id="textInputField1" name="textInputField1" style="resize:vertical; width: 900px;" rows="15" cols="105" wrap="pre" onblur="onTextSubmitFunction('Apply')"></textarea>
</td>
</tr>
</table>

Sticky headers not maintaining width when scrolling

I have some table headers which I planned on making sticky (fixed) as the user scrolls down the page, but they currently shrink when the sticky is activated, I would like them to inherit the widths of the headers, but they shrink to the size of the text at the moment.
My JS:
$(document).ready(function() {
var stickyNavTop = $('.th').offset().top;
SOLUTION:
$(".th th").each(function(){$(this).width($(this).width());});
$('.th').width($('.th').width());
var stickyNav = function(){
var scrollTop = $(window).scrollTop();
if (scrollTop > stickyNavTop) {
$('.th').addClass('sticky');
} else {
$('.th').removeClass('sticky');
}
};
stickyNav();
$(window).scroll(function() {
stickyNav();
});
});
My HTML:
<table class="mGrid" cellspacing="0" rules="all" border="1" id="1"
style="width:98%;border-collapse:collapse;">
<tr class="th">
<th scope="col">Membership No.</th>
<th scope="col">Surname</th>
<th scope="col">Other Name(s)</th>
</tr>
<tr>
<td>
<div id="2" class="formInput">
<label for="2">Membership No.</label>
<input name="2" type="text" value="AH6973" id="2"
class="required" style="width:60px;" />
</div>
</td>
<td>
<div id="3" class="formInput">
<label for="3">Surname</label>
<input name="3" type="text" value="CARTER" id="3"
style="width:100px;" />
</div>
</td>
<td>
<div id="4" class="formInput">
<label for="4">Other Name(s)</label>
<input name="4" type="text" value="RAYMOND" id="4"
style="width:150px;" />
</div>
</td>
</tr>
</table>
my CSS:
.sticky {
position: fixed;
width: 100%;
top: 0;
z-index: 100;
border-top: 0;
color: #fff !important;
background: #666;
border-left: solid 1px #525252;
font-size: 1.0em;
}
(This is modelled to be the same as the header style, it's just the width shrinks to fit the width of the text at the moment. I tried to edit the header style but it's apparently read-only "'HeaderStyle' property is read-only and cannot be set."
Just add this line before your function definition:
$('th').width($('th').width());
Full JavaScript code:
$(document).ready(function() {
var stickyNavTop = $('.th').offset().top;
$('th').width($('th').width());
var stickyNav = function(){
var scrollTop = $(window).scrollTop();
if (scrollTop > stickyNavTop) {
$('.th').addClass('sticky');
} else {
$('.th').removeClass('sticky');
}
};
stickyNav();
$(window).scroll(function() {
stickyNav();
});
});
here is a common solution, it auto detects each sub-element's width and height and reflect when scrolling, it is something like following:
var $this = $(this),
top = $this.offset().top,
left = $this.offset().left,
width = $this.width(),
height = $this.height(),
widthArr = [],
heightArr = [];
$this.find("*").each(function(i, e) {
widthArr.push($(this).width());
heightArr.push($(this).height());
});
$(window).scroll(function() {
if($(window).scrollTop() >= top) {
$this.css({
position: "fixed",
top: 0,
left: left,
"z-index": 100,
width: width,
height: height
});
$this.find("*").each(function(i, e) {
$(this).width(widthArr[i]);
$(this).height(heightArr[i]);
});
} else {
// to be implemented
}
});
My solution to avoid column width changes : cloning the header. (Thanks to #Matt for the line: $('th').width($('th').width()); and his solution.)
JS
var stickyNavTop = jQuery('thead tr:first-child').offset().top;
// init state
var stickState = (jQuery(window).scrollTop() > stickyNavTop);
var stickyNav = function() {
var scrollTop = jQuery(window).scrollTop();
// state has changed?
if (stickState != (scrollTop > stickyNavTop)) {
// remember/catch new state
stickState = (scrollTop > stickyNavTop);
if (stickState) {
jQuery('thead tr:first-child th').each(
function() { jQuery(this).width( jQuery(this).width() ); }
);
// cloning the header : the original columns won't move
jQuery('thead tr:first-child')
.clone()
.prependTo(jQuery('thead'))
.addClass('sticky');
} else {
jQuery('tr.sticky').remove();
}
}
};
jQuery(window).scroll(function() {
stickyNav();
});
stickyNav();
CSS
.sticky {
position: fixed;
top: 0;
z-index: 100;
}

Div tabs with Javascript

I organized my tabs this way:
<ul id="tabs">
<li class="selected">DIV1</li>
<li class>DIV2</li>
<li class>DIV3</li>
</ul>
<div id="tabs_content">
<div id="div1" style="display: block;"><textarea name="div1" rows="7" cols="108"></textarea></div>
<div id="div2" style="display: none;"><textarea name="div2" rows="7" cols="108"></textarea></div>
<div id="div3" style="display: none;"><textarea name="div3" rows="7" cols="108"></textarea></div>
</div>
I would like that when I press one of the link inside the <li> element,
the corrispondend Div become visible with display: block and the others are changed to display: none
Also I would like to do the same with the "selected" class on the clicked <li> element.
Is this possible?
I tried with:
function selectTab(src)
{
document.getElementById('div1').style.display = 'none';
document.getElementById('div2').style.display = 'none';
document.getElementById('div3').style.display = 'none';
document.getElementById(src).style.display = 'block';
}
It works if I pass the ID by reference with onclick="" but I would like to avoid this.
Solution:
function selectTab(source, parent)
{
document.getElementById('div1').style.display = 'none';
document.getElementById('div2').style.display = 'none';
document.getElementById('div3').style.display = 'none';
document.getElementById(source).style.display = 'block';
var elements = [].slice.apply(document.getElementsByClassName('selected'));
for (var i = 0; i < elements.length; i++) {
elements[i].className = '';
}
parent.className = 'selected';
}
Possibly this is what you want, cross-browser (IE5.5+)
CSS
.selected {
background-color: green;
}
.hide {
display: none;
}
HTML
<ul id="tabs">
<li class="selected">DIV1
</li>
<li class>DIV2
</li>
<li class>DIV3
</li>
</ul>
<div id="tabs_content">
<div id="div1">
<textarea name="div1" rows="7" cols="108"></textarea>
</div>
<div id="div2" class="hide">
<textarea name="div2" rows="7" cols="108"></textarea>
</div>
<div id="div3" class="hide">
<textarea name="div3" rows="7" cols="108"></textarea>
</div>
</div>
javascript
var tabs = document.getElementById("tabs"),
tabs_content = document.getElementById("tabs_content"),
divs = tabs_content.getElementsByTagName("div"),
divsLength = divs.length,
lis = tabs.getElementsByTagName("li"),
lisLength = lis.length;
tabs.onclick = function (evt) {
var e = evt || window.event,
target = e.target || e.srcElement,
href,
id,
index,
div;
if (target.tagName.toUpperCase() === "A") {
for (index = 0; index < lisLength; index += 1) {
lis[index].className = "";
}
target.parentNode.className = "selected";
href = target.attributes.href.nodeValue;
if (href && href.charAt(0) === "#") {
id = href.slice(1);
for (index = 0; index < divsLength; index += 1) {
div = divs[index];
if (id === div.id) {
div.className = "";
} else {
div.className = "hide";
}
}
}
}
};
jsfiddle
Your selectTab function needs to be necessarily bound to the click event on those list elements. There's no other way you can do it. Your code is good enough. You can simplify things using JQuery as well, as some other answer here points out.
Okay, do this:
In your HTML, add "tab" class to each of the tags.
<li class="selected"><a class="tab" href="#div1">DIV1</a></li>
<li class><a class="tab" href="#div2">DIV2</a></li>
<li class><a class="tab" href="#div3">DIV3</a></li>
In your jquery,
$('.tab').click(function(){
var displaydiv = $(this).attr('href');
$('#div1').hide();
$('#div2').hide();
$('#div3').hide();
$(this).show();
$('"'+displaydiv+'"').show();
$(this).parent().attr('class','selected');
})
<ul id="tabs">
<li class="selected"><a onclick="showTab(this);" href="#div1">DIV1</a></li>
<li><a onclick="showTab(this);" href="#div2">DIV2</a></li>
<li><a onclick="showTab(this);" href="#div3">DIV3</a></li>
</ul>
<div id="tabs_content">
<div id="div1" style="display: block;"><textarea name="div1" rows="7" cols="108"></textarea></div>
<div id="div2" style="display: none;"><textarea name="div2" rows="7" cols="108"></textarea></div>
<div id="div3" style="display: none;"><textarea name="div3" rows="7" cols="108"></textarea></div>
</div>
Use the following javascript:
function showTab(a)
{
var id = a.href.replace('#','');
var tabs = document.getElementById('tabs_content').getElementsByTagName('div');
var index = -1;
for(var i=0,n=tabs.length;i<n;i+=1)
{
var t = tabs[i];
if(t.id === id)
{
t.style.display = 'block';
index = i;
}
else
{
t.style.display = 'none';
}
}
var links = document.getElementById('tabs').getElementsByTagName('li');
for(var i=0,n=links.length;i<n;i+=1)
{
links[i].setAttribute('class', index === i ? 'selected' : '');
}
}
Of course you could also first cache your menu and tabs, that way you can keep a variable. This is the proper way:
function Menu()
{
var self = this;
self.links = document.getElementById('tabs').getElementsByTagName('a');
self.tabs = document.getElementById('tabs_content').getElementsByTagName('div');
self.selectedIndex = 0;
self.n = self.links.length;
for(var i=0;i<self.n;i+=1)
{
// Set onclick for every link in the tabs-menu
self.links[i].onclick = function(ind){return function(){self.update(ind);};}(i);
}
self.update = function(ind)
{
// Hide previous tab
self.links[self.selectedIndex].parentNode.setAttribute('class', '');
self.tabs[self.selectedIndex].style.display = 'none';
// Select and show clicked tab
self.selectedIndex = ind;
self.links[self.selectedIndex].parentNode.setAttribute('class', 'selected');
self.tabs[self.selectedIndex].style.display = 'block';
};
}
setTimeout(function(){new Menu();},1);
Check out the jsfiddle for the Menu class in action: http://jsfiddle.net/3vf4A/1/. Note that even if Javascript is disabled, the a-tag will still get you to the correct area by scrolling to it automatically.

Categories