regular expression for finding CSS rules from css file - javascript

How do I get CSSRules from a stylesheet using regular expressions? I have tried but my expression doesn't work on rules that accecpt selectors like media queries or keyframes etc...
This is my expression
/([^}]{)([^}])[^{]*}/
...It works fine when finding CSS style rules.... But a keyframe or media rule won't work well... You can try it using match like so ->
const regex = new RegExp(/([^}]*{)([^}])*[^{]*}/, 'g');
var arr = document.head.querySelector('style').innerText.match(regex); // style tag that has enough CSS rules... including media queries
console.log(arr);
To summarize to purpose of the expression I'd say.... I am trying to get the result of 'document.styleSheets[0].cssRules[0].cssText'
here is an example
//
const regex = new RegExp(/([^}][^;][^{]*{)([^}])*[^{]*}/, 'g');
const arr = document.querySelector('.wb-monitor').innerText.match(regex);
const screen = document.querySelector('#screen');
//console.log(arr)
if(arr !== null){
arr.forEach(item => {
if(item.trim().length > 0){
screen.innerHTML += `<pre>${item}</pre>`;
}
});
} else {
screen.innerHTML = '<span>No Match Found!</span>';
}
container {
display: flex;
width: 100%;
background: #ddd;
height: 100%;
}
pre {
border-left: 3px solid blue;
background: rgb(93 88 88 / 60%);
padding: 8px;
}
.wb-monitor {
width: 0%;
overflow: hidden;
font-family: monospace;
margin-right: 2px;
background: grey;
}
#screen {
background: black;
color: white;
flex-grow: 1;
overflow: scroll;
}
<div class="container">
<!-- Dummy css -->
<div class="wb-monitor">
.header-basic-light {
padding: 20px 40px;
box-sizing: border-box;
box-shadow: 0 0 7px 0 rgba(0, 0, 0, 0.15);
height: 80px;
background-color: #fff;
}
.header-basic-light .header-limiter {
max-width: 1200px;
text-align: center;
margin: 0 auto;
}
.header-basic-light .header-limiter h1 {
float: left;
font: normal 28px Cookie, Arial, Helvetica, sans-serif;
line-height: 40px;
margin: 0;
}
#media all and (max-width: 600px) {
# keyframes me {
0% {
marin: 0;
}
100% {
margin: 100;
}
}
}
#media all and (max-width: 600px) {
.header-basic-light {
padding: 20px 0;
height: 85px;
}
.header-basic-light .header-limiter h1 {
float: none;
margin: -8px 0 10px;
text-align: center;
font-size: 24px;
line-height: 1;
}
.header-basic-light .header-limiter nav {
line-height: 1;
float: none;
}
.header-basic-light .header-limiter nav a {
font-size: 13px;
}
}
</div>
<div id="screen"></div>
</div>

Related

Change image when selecting device and return it back after selecting different device

Trying to change to different image through url when the device is selected. But after clicking and selecting for example android then selecting ios afterwards the android image is not returning to the previous one and you have to click it again to return to the original image.
This code is just an example what i am trying to do.
Code Example:
function device(select, value){
devicevalue=value;
document.getElementById("platform0").classList.add("platform");
document.getElementById("platform1").classList.add("platform");
document.getElementById("platform0").classList.remove("selectedPlatform");
document.getElementById("platform1").classList.remove("selectedPlatform");
document.getElementById(select).classList.add("selectedPlatform");
document.getElementById(select).classList.remove("platform");
}
function changecolorandroid(){
const img = document.getElementById('black-android');
if (img.dataset.image == "img1") {
img.src = "https://cdn-icons-png.flaticon.com/512/61/61120.png?w=826&t=st=1660038595~exp=1660039195~hmac=2d02a98f85838b7382aa93176eb51e58e99aec95155d52cb082063ffb6395bc3";
img.dataset.image = "img2";
return;
};
if (img.dataset.image == "img2"){
img.src = "https://www.freepnglogos.com/uploads/android-logo-png/android-logo-0.png";
img.dataset.image = "img1";
return;
};
}
function changecolorios(){
const pic = document.getElementById('black-ios');
if (pic.dataset.image == "pic1") {
pic.src = "https://www.freepnglogos.com/uploads/apple-logo-png/apple-logo-png-what-you-need-know-before-rebranding-11.png";
pic.dataset.image = "pic2";
return pic;
};
if (pic.dataset.image == "pic2"){
pic.src = "https://cdn3.iconfinder.com/data/icons/social-media-logos-glyph/2048/5315_-_Apple-512.png";
pic.dataset.image = "pic1";
return;
};
}
.devices{
display: flex;
justify-content: center;
box-sizing: border-box;
float: none;
}
.platform{
background: #FFFFFF;
width: 12em;
height: 3em;
border-radius: 1em;
padding-top: 1em;
margin: 1em;
box-shadow: 0 0 0.6em black;
cursor: pointer;
}
.platform:hover{
background:#FFFFFF;
transform: scale(1.1);
box-shadow: 0 0 0.5em #31271c;
}
.devices-pic{
width: 3em;
margin: 0 4em;
}
.devices-pic.ios{
margin: -0.5em 4.5em 0.2em 4.5em;
}
.devices-pic.android{
width: 30%;
margin: -0.5em 4em 0.2em 4em;
}
.selectedPlatform{
background: grey;
width: 12em;
height: 3em;
border-radius: 1em;
padding-top: 1em;
margin: 1em;
box-shadow: 0 0 0.6em white;
cursor: pointer;
}
<div class="devices">
<div class="platform" id="platform0" onclick="device('platform0', 'Android'); changecolorandroid();">
<img src="https://www.freepnglogos.com/uploads/android-logo-png/android-logo-0.png" class="devices-pic android" id="black-android" data-image="img1">
</div>
<div class="platform" id="platform1" onclick="device('platform1', 'Apple'); changecolorios();">
<img src="https://cdn3.iconfinder.com/data/icons/social-media-logos-glyph/2048/5315_-_Apple-512.png" class="devices-pic ios" id="black-ios" data-image="pic1">
</div>
</div>
After you click an image, you need to reset the other image to the origin state.
Also, you don't need the if conditions.
const pic = document.getElementById('black-ios');
const img = document.getElementById('black-android');
function device(select, value){
devicevalue=value;
document.getElementById("platform0").classList.add("platform");
document.getElementById("platform1").classList.add("platform");
document.getElementById("platform0").classList.remove("selectedPlatform");
document.getElementById("platform1").classList.remove("selectedPlatform");
document.getElementById(select).classList.add("selectedPlatform");
document.getElementById(select).classList.remove("platform");
}
function changecolorandroid(){
img.src = "https://cdn-icons-png.flaticon.com/512/61/61120.png?w=826&t=st=1660038595~exp=1660039195~hmac=2d02a98f85838b7382aa93176eb51e58e99aec95155d52cb082063ffb6395bc3";
img.dataset.image = "img2";
resetIosImage()
}
function changecolorios(){
pic.src = "https://www.freepnglogos.com/uploads/apple-logo-png/apple-logo-png-what-you-need-know-before-rebranding-11.png";
pic.dataset.image = "pic2";
resetAndriodImage()
}
function resetAndriodImage() {
img.src = "https://www.freepnglogos.com/uploads/android-logo-png/android-logo-0.png";
img.dataset.image = "img1";
}
function resetIosImage() {
pic.src = "https://cdn3.iconfinder.com/data/icons/social-media-logos-glyph/2048/5315_-_Apple-512.png";
pic.dataset.image = "pic1";
}
.devices{
display: flex;
justify-content: center;
box-sizing: border-box;
float: none;
}
.platform{
background: #FFFFFF;
width: 12em;
height: 3em;
border-radius: 1em;
padding-top: 1em;
margin: 1em;
box-shadow: 0 0 0.6em black;
cursor: pointer;
}
.platform:hover{
background:#FFFFFF;
transform: scale(1.1);
box-shadow: 0 0 0.5em #31271c;
}
.devices-pic{
width: 3em;
margin: 0 4em;
}
.devices-pic.ios{
margin: -0.5em 4.5em 0.2em 4.5em;
}
.devices-pic.android{
width: 30%;
margin: -0.5em 4em 0.2em 4em;
}
.selectedPlatform{
background: grey;
width: 12em;
height: 3em;
border-radius: 1em;
padding-top: 1em;
margin: 1em;
box-shadow: 0 0 0.6em white;
cursor: pointer;
}
<div class="devices">
<div class="platform" id="platform0" onclick="device('platform0', 'Android'); changecolorandroid();">
<img src="https://www.freepnglogos.com/uploads/android-logo-png/android-logo-0.png" class="devices-pic android" id="black-android" data-image="img1">
</div>
<div class="platform" id="platform1" onclick="device('platform1', 'Apple'); changecolorios();">
<img src="https://cdn3.iconfinder.com/data/icons/social-media-logos-glyph/2048/5315_-_Apple-512.png" class="devices-pic ios" id="black-ios" data-image="pic1">
</div>
</div>

Add line numbers to text area using javascript

I wanted to add line numbering to a textarea.
I get the number of lines by using
textAreaElement.value.split("\n").length;
and maintain a div with span elements that use the count as content on before to add line numbers.
.line-number {
width: 100%;
display: block;
text-align: right;
line-height:1.5em;
border-bottom: thin;
font-family:'CascadiaCode Nerd Font', monospace;
font-size: 2rem;
color: #fff;
opacity: 0.8;
padding: 0 0.4em;
}
.line-number::before {
counter-increment: line;
content: counter(line);
font-size: 1em;
user-select: none;
}
However this has a fixed height, I want to implement this for a text area with word wrap (no horizontal scrollbar), where every line can technically have multiple lines terminated by a "\n".
My line of thought was to prepare an array of heights for each lines but I have no idea how to get the height of each separate line.
update:
I switched to an editable div, but i want my line number to be of the same height as its corresponding div.
const lineEnum = {
state: false,
count: 0,
gutter: document.getElementsByClassName("line-numbers")[0],
update: (box) => {
let delta = box.children.length - lineEnum.count;
if (box.children.length == 0) delta++;
console.log({
delta: delta,
count: lineEnum.count,
length: box.children.length,
});
if (delta > 0 && lineEnum.state) {
const frag = document.createDocumentFragment();
while (delta > 0) {
const line_number = document.createElement("span");
line_number.className = "line-num";
frag.appendChild(line_number);
lineEnum.count++;
delta--;
}
lineEnum.gutter.appendChild(frag);
} else {
if (lineEnum.count + delta === 0) delta++;
while (delta < 0 && lineEnum.gutter.lastChild) {
lineEnum.gutter.removeChild(lineEnum.gutter.lastChild);
lineEnum.count--;
delta++;
}
}
},
init: (box) => {
if (lineEnum.state) return;
lineEnum.state = true;
lineEnum.update(box);
},
remove: (box) => {
if (!lineEnum.state || !lineEnum.gutter.firstChild) return;
lineEnum.gutter.innerHtml = "";
lineEnum.state = false;
},
};
const callback = (mutationList, observer) => {
let mutation = mutationList[mutationList.length - 1];
if (mutation.type === "childList") {
console.log(mutation);
lineEnum.update(mutation.target);
}
};
const observer = new MutationObserver(callback);
const config = { childList: true };
const editor = document.getElementsByClassName("code-input")[0];
observer.observe(editor, config);
lineEnum.init(editor);
.window-body{
position: fixed;
height: 100%;
top: 25px;
width: 100%;
display: flex;
}
.line-numbers {
width: 5em;
padding: 0;
height: 100%;
word-break: break-all;
overflow: hidden;
display: inline-block;
counter-reset: line;
background-color: gray;
opacity: 0.8;
}
.line-num {
width: 100%;
display: block;
text-align: middle;
line-height:1.5em;
border-bottom: thin;
font-family:'Arial', monospace;
font-size: 2rem;
color: #fff;
opacity: 0.8;
padding: 0 1em;
}
.line-num::before {
counter-increment: line;
content: counter(line);
font-size: 1em;
user-select: none;
}
.code-input{
margin: 0;
border: 0;
padding: 0;
outline: 0;
list-style: none;
display: inline-block;
flex-grow: 1;
height: 100%;
word-break: break-all;
overflow: hidden;
border:none;
font-family:'Arial', monospace;
font-size:2rem;
background: white;
white-space:pre-wrap;
line-height:1.5em;
word-wrap: break-word;
resize:none;
}
<div class="window-body">
<div class="line-numbers"></div>
<div class="code-input" contenteditable="true"></div>
</div>
Man I wasted so much time on using javascript when css magic would just have done the trick.
Here is how I did it,
body {
background-color: #000;
height: 100vh;
width: 100vw;
margin: 0px;
}
.editor-wrapper {
height: 100vh;
width: 100vw;
overflow-y: auto;
counter-reset: line;
}
.editor{
margin: 0;
border: 0;
padding: 0;
outline: 0;
list-style: none;
height: 100%;
width: 100%;
word-wrap: break-word;
word-break: break-all;
font-size:2rem;
line-height: 1.5em;
font-feature-settings: common-ligatures;
-ms-font-feature-settings: common-ligatures;
color:rgba(255, 255, 255, 0.7);
resize:none;
}
.editor div {
padding-left: 5rem;
position: relative;
}
.editor div::before {
counter-increment: line;
content: counter(line);
font-size: 1em;
user-select: none;
width: 5rem;
text-align: right;
left: 0;
position: absolute;
}
<div class="editor-wrapper">
<div class="editor" contenteditable="true">
<div></div>
</div>
</div>
You can use a background image like so:
.lined-textarea {
background: url(http://i.imgur.com/2cOaJ.png);
background-attachment: local;
background-repeat: no-repeat;
padding-left: 35px;
padding-top: 10px;
border-color: #ccc;
font-size: 13px;
line-height: 16px;
resize: none;
}
<textarea rows="8" cols="30" class="lined-textarea"></textarea>
If it's a code block with line numbers you want then https://www.prowaretech.com/Computer/JavaScript/AddLineNumbersToPre demonstrates this well.
function addLineClass (pre) {
var lines = pre.innerText.split("\n"); // can use innerHTML also
while(pre.childNodes.length > 0) {
pre.removeChild(pre.childNodes[0]);
}
for(var i = 0; i < lines.length; i++) {
var span = document.createElement("span");
span.className = "line";
span.innerText = lines[i]; // can use innerHTML also
pre.appendChild(span);
pre.appendChild(document.createTextNode("\n"));
}
}
Along with the CSS using the essential part:
pre span.line::before {
content: counter(linecounter);
See https://jsfiddle.net/Abeeee/12cx5ruf/6/ for a running example

Vertical JavaScript Menu - Not All Subsections Displaying

Currently, I'm helping to build a website for a family member as part of a modeling club they have.
The website is at http://testindyamps.weebly.com/ .
It's a website on a host that utilizes various templates for themes (I haven't had much help so far from people on said site).
I'm not 100% sure if this ist he best place to post the question, but I thought I'd give it a shot.
The main issue is that it's utilizing a sidebar navigation where when you click the menus, it expands downward to show the subpages. In this case, not all the subpages are showing. (For example, clicking on "Articles" and then "Books" shows only the first few of a dozen or so pages.
I've tried editing the JS code itself, which so far has had no affect. I've tried editing some of the CSS, however, it doesn't seem to have an affect either.
If it helps, I can share osme of the CSS code or JS code for the site itself. Any help would be appreciated.
Thank you.
UPDATE: Added the code as requested.
Update 2: Added HTML: fixed to correct URL (using a test site instead of the "actual" site for the navigation).
jQuery(function($) {
// Mobile sidebars
$.fn.expandableSidebar = function(expandedClass) {
var $me = this;
$me.on('click', function() {
if(!$me.hasClass(expandedClass)) {
$me.addClass(expandedClass);
} else {
$me.removeClass(expandedClass);
}
});
}
// Interval loop
$.fn.intervalLoop = function(condition, action, duration, limit) {
var counter = 0;
var looper = setInterval(function(){
if (counter >= limit || $.fn.checkIfElementExists(condition)) {
clearInterval(looper);
} else {
action();
counter++;
}
}, duration);
}
// Check if element exists
$.fn.checkIfElementExists = function(selector) {
return $(selector).length;
}
// Check if desktop display
$.fn.isDesktop = function() {
return $(window).width() > 1024;
}
var briskController = {
init: function(opts) {
var base = this;
base._addClasses();
setTimeout(function(){
base._attachEvents();
}, 1000);
},
_addClasses: function() {
var base = this;
// Add fade in class to nav + logo + banner
$('body').addClass('fade-in');
// Keep subnav open if submenu item is active
$('.sidebar-nav .active').parents('.has-submenu').children('.dropdown').addClass('open');
// Add placeholder text to inputs
$('.wsite-form-sublabel').each(function(){
var sublabel = $(this).text();
$(this).prev('.wsite-form-input').attr('placeholder', sublabel);
});
},
_cloneLogin: function() {
var loginDetach = $('#member-login').clone(true);
$('.mobile-nav .wsite-menu-default > li:last-child').after(loginDetach);
},
_stickyNav: function() {
var sticky,
collapse,
uncollapse,
desktopsticky = $('body.nav-position-top.sticky-nav-on:not(.wsite-checkout-page):not(.wsite-native-mobile-editor), body.nav-position-top-right.sticky-nav-on:not(.wsite-checkout-page):not(.wsite-native-mobile-editor)').length,
mobilesticky = $('body.sticky-nav-on:not(.wsite-checkout-page):not(.wsite-native-mobile-editor)').length;
var stickyInit = function() {
if (!$.fn.isDesktop() || desktopsticky) {
// Add sticky desktop nav
sticky = new Waypoint.Sticky({
element: $('.header')[0]
});
}
if ($.fn.isDesktop() && desktopsticky) {
// Collapse header on scroll
collapse = new Waypoint({
element: $('body.nav-position-top.sticky-nav-on:not(.wsite-checkout-page):not(.wsite-native-mobile-editor)')[0],
handler: function(direction) {
$('body').addClass('collapse');
},
offset: -10
});
uncollapse = new Waypoint({
element: $('body.nav-position-top'),
handler: function(direction) {
$('body').removeClass('collapse');
},
offset: -5
});
}
}
stickyInit();
$(window).resize(function() {
if (sticky) { sticky.destroy() }
if (collapse) { collapse.destroy() }
if (uncollapse) { uncollapse.destroy() }
stickyInit();
});
},
_sidebarNav: function() {
// Fixed sidebar nav unless menu height exceeds viewport height
var sidebarCheck = function() {
if ($.fn.isDesktop() && $('body').hasClass('sticky-nav-on') && $('.header .container').height() + $('.header .contact').height() <= $(window).height() - 45) {
$('body.nav-position-sidebar .header').addClass('stuck');
}
else {
$('body.nav-position-sidebar .header').removeClass('stuck');
}
}
sidebarCheck();
$(window).resize(function() {
sidebarCheck();
});
},
_sidebarCart: function(){
$('#wsite-mini-cart').addClass('cart-init');
$('.wsite-nav-cart a').click(function() {
$('.cart-init').toggleClass('cart-visible');
});
$('.wrapper, .header').click(function() {
$('.cart-init').removeClass('cart-visible');
});
},
_attachEvents: function() {
var base = this;
// Hamburger nav toggle
$('.hamburger').on('click', function(e) {
e.preventDefault();
$('body').toggleClass('nav-open');
});
// Initialize sticky nav
base._stickyNav();
// Initialize sidebar nav
base._sidebarNav();
// Copy login
$.fn.intervalLoop('.mobile-nav #member-login', base._cloneLogin, 800, 5);
// Subnav toggle
$('li.has-submenu span.icon-caret, .dropdown-link').on('click', function() {
var $me = $(this);
if ($me.parent().hasClass('open')) {
$me.parent().removeClass('open');
$me.find('.open').removeClass('open');
}
else {
$('.open').removeClass('open');
$me.parents('.has-submenu').children('.dropdown').addClass('open');
}
setTimeout(function(){
base._sidebarNav();
}, 800);
});
// Sidebar Cart Link
$.fn.intervalLoop('.cart-init', base._sidebarCart, 1000, 5);
// Store category dropdown
$('.wsite-com-sidebar').expandableSidebar('sidebar-expanded');
// Search filters dropdown
$('#wsite-search-sidebar').expandableSidebar('sidebar-expanded');
// Init fancybox swipe on mobile
if ('ontouchstart' in window) {
$('body').on('click', 'a.w-fancybox', function() {
base._initSwipeGallery();
});
}
},
_initSwipeGallery: function() {
var base = this;
setTimeout(function(){
var touchGallery = document.getElementsByClassName('fancybox-wrap')[0];
var mc = new Hammer(touchGallery);
mc.on("panleft panright", function(ev) {
if (ev.type == "panleft") {
$("a.fancybox-next").trigger("click");
} else if (ev.type == "panright") {
$("a.fancybox-prev").trigger("click");
}
base._initSwipeGallery();
});
}, 500);
}
}
$(document).ready(function(){
briskController.init();
});
});
/* Header */
.header {
position: relative;
width: 100%;
color: #fill;
background: #bg;
border-bottom: 1px solid fade(#fill, 5);
box-sizing: border-box;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
z-index: 12;
.hamburger,
.contact,
.desktop-nav,
.sidebar-nav {
display: none;
}
}
body.nav-open {
overflow: hidden;
#media #tablet-up {
overflow: auto;
}
}
body:not(.nav-position-sidebar),
body.nav-position-top,
body.nav-position-top-right {
#media #tablet-up {
.header {
position: relative;
padding: 10px 40px;
border-bottom: none;
.transition(~'padding 280ms ease');
.container {
display: table;
overflow-y: hidden;
width: 100%;
height: 80px;
.transition(~'height 280ms ease');
}
.logo {
display: table-cell;
text-align: left;
vertical-align: middle;
max-height: 80px;
overflow: hidden;
a {
padding: 5px 20px 5px 0;
}
}
.desktop-nav {
display: table-cell;
}
.nav {
li {
display: inline-block;
}
a {
padding: 10px 20px;
}
}
.membership-cart {
display: table-cell;
width: 5%;
text-align: right;
white-space: nowrap;
span {
display: inline-block;
}
}
}
&.collapse {
.header {
padding: 5px 40px;
border-bottom: 1px solid fade(#fill, 5);
.container {
height: 40px;
}
}
}
&.full-width-nav-off .header .container {
max-width: 1200px;
margin: 0 auto;
padding: 0 40px;
box-sizing: border-box;
}
}
}
body.nav-position-top-right {
.desktop-nav {
text-align: right;
}
}
.stuck {
position: fixed !important;
top: 0;
}
body.nav-position-sidebar {
#media #tablet-up {
.header {
position: absolute;
top: 0;
left: 0;
width: 260px;
min-height: 100vh;
padding: 40px;
border-bottom: none;
display: flex;
flex-direction: row;
> .nav-wrap {
width: 100%;
min-height: calc(~'100vh - 80px');
display: flex;
flex-direction: column;
> .container {
flex: 1 0 auto;
}
}
.sidebar-nav {
display: block;
}
.nav {
li {
display: block;
}
a {
display: block;
padding: 10px 0;
}
}
.logo {
margin: 0 auto 30px;
}
.membership-cart > span {
display: block;
}
}
.contact {
display: block;
}
.wsite-phone {
display: block;
font-size: 15px;
color: fade(#fill, 40);
padding: 40px 0 0;
text-align: left;
&:before {
content: '';
display: block;
width: 60%;
padding-bottom: 40px;
border-top: 1px solid fade(#fill, 20);
}
}
.wrapper {
background: #bg;
padding-left: 260px;
box-sizing: border-box;
}
}
}
.logo {
* {
display: block;
}
a {
color: #primary;
&:hover {
opacity: 0.6;
background: transparent;
.transition(opacity 200ms ease);
}
}
#wsite-title {
font-family: #font1;
font-size: 30px;
font-weight: 500;
line-height: 1;
text-transform: uppercase;
letter-spacing: 0.08em;
}
img {
overflow: hidden;
max-width: 300px;
max-height: 70px;
}
.wsite-logo {
overflow: hidden;
max-width: 100%;
max-height: 70px;
}
}
/* Nav */
.nav {
vertical-align: middle;
a {
display: block;
color: #fill;
font-family: #font1;
font-size: 15px;
font-weight: 500;
line-height: 1;
letter-spacing: 0.05em;
text-transform: lowercase;
&:hover {
opacity: 0.6;
background: transparent;
.transition(opacity 200ms ease);
}
}
.active {
color: darken(#primary, 10%) !important;
}
#wsite-nav-cart-a {
padding-right: 0;
}
#wsite-nav-cart-num {
position: relative;
display: inline-block;
background: mix(#primary, #bg, 60%);
color: #fill;
min-width: 25px;
padding: 7px 2px;
text-align: center;
border-radius: 100%;
z-index: 2;
#media #tablet-up {
margin: 0 -6px;
}
}
}
.mobile-nav {
display: none;
}
/* Subnav */
#wsite-menus {
> .wsite-menu-wrap {
margin-top: 10px;
}
> .wsite-menu-wrap > .wsite-menu .wsite-menu {
margin: 0 -1px;
}
.wsite-menu {
position: relative;
background: #bg;
.box-shadow(inset 0px 0px 0px 1px fade(#fill, 3));
li a {
padding: 12px 20px;
background: transparent;
color: #fill;
font-family: #font1;
font-size: 14px;
font-weight: normal;
line-height: normal;
text-transform: lowercase;
letter-spacing: 0.05em;
border: none;
&:hover {
opacity: 0.6;
background: transparent;
.transition(opacity 200ms ease);
}
}
}
.wsite-menu-arrow {
display: none;
}
}
/* Sidebar and Mobile Subnav */
.sidebar-nav,
.mobile-nav {
li {
position: relative;
border-color: fade(#fill, 80);
}
.wsite-menu {
padding-left: 5px;
color: fade(#fill, 50);
border-color: fade(#fill, 50);
a {
color: fade(#fill, 50);
}
}
.wsite-menu-wrap {
display: block !important;
overflow: hidden;
max-height: 0;
.transition(all 600ms ease-in-out);
}
.wsite-menu-wrap li.wsite-nav-current > a.wsite-menu-subitem {
background: rgba(0, 0, 0, 0.95);
border: none;
}
.wsite-menu-wrap .wsite-menu-arrow {
display: none;
}
.dropdown {
display: table;
width: 100%;
&:hover {
.icon-caret {
opacity: 0.6;
background: transparent;
}
}
> .icon-caret,
> .dropdown-link {
display: table-cell !important;
vertical-align: top;
a {
display: inline-block !important;
}
}
.icon-caret {
width: 15px;
cursor: pointer;
.transition(all 200ms ease-in-out);
&:before {
content: '';
position: relative;
display: block;
width: 5px;
height: 5px;
border: solid transparent;
border-width: 0 1px 1px 0;
border-color: inherit;
.transform(~'rotate(45deg)');
}
}
&.open span.icon-caret:before {
top: 5px;
.transform(~'rotate(-135deg)');
}
&.open + .wsite-menu-wrap {
width: 100%;
max-height: 1000px;
}
}
}
.sidebar-nav {
.has-submenu > .dropdown span.icon-caret {
padding: 12px 0 8px 10px;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body class="no-header-page">
<div class="header">
<div class="nav-wrap">
<div class="container">
<a class="hamburger" aria-label="Menu" href="#"><span></span></a>
<div class="logo">{logo}</div>
<div class="nav desktop-nav">{menu}</div>
<div class="nav sidebar-nav"><div class="nav-wrap">{menu}</div></div>
<div class="nav membership-cart">{membership}{minicart}</div>
</div>
<div class="nav contact">{phone:text}</div>
</div>
</div>
<div class="wrapper">
<div class="main-wrap">
{{#sections}}
<div class="container">{content}</div>
{{/sections}}
</div>
<div class="footer-wrap">
<div class="footer">{footer}</div>
</div>
</div>
<div class="nav mobile-nav">
<a class="hamburger" aria-label="Menu" href="#"><span></span></a>
{menu}
</div>
<script type="text/javascript" src="/files/theme/plugins.js"></script>
<script type="text/javascript" src="/files/theme/custom.js"></script>
</body>
</html>
The reason not all elements are showing is because of this:
.sidebar-nav .dropdown.open + .wsite-menu-wrap, .mobile-nav .dropdown.open + .wsite-menu-wrap {
width: 100%;
max-height: 1000px;
}
The element is expanded by changing the max-height from 0px to 1000px. The elements in your menu exceed 1000px and they get cut off.
This is actually a pretty comman problem when using CSS transitions to expand elements. CSS transitions only work on height if height is set to an exact value. You can read more about it here: https://css-tricks.com/using-css-transitions-auto-dimensions/
The max-height trick offers a work-around. But it has its draw-back - if the elements expands beyond the value of max-height it gets cut off.
The simplest solution is to simply increase the value of max-height, until all your elements show. This will work, but it' s not ideal if in the future the element expands even more.
More sophisticated (and arguably better) solutions can be found in the css-tricks web page above.
Still, are you sure it's a good idea do display such an enormous amount of of links in an accordion menu? Wouldn't it be better to rethink the navigation, perhaps have a separate page with all the books?

To Do List Delete Button within HTML <li> element

I am trying to get a delete button working on my To Do List project. I have tried a lot of different things but I am not having any luck. I believe the issue stems from the fact that I am trying to reference a button in an HTML li tag that is created by Javascript/jQuery when a user enters a new task in the To Do List. I probably am messing up the syntax relation between the two. Any help would be greatly appreciated. Thanks ahead of time.
Here is the HTML
<!DOCTYPE html>
<html>
<head>
<title>Project 4 - To Do List</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div id="page">
<h1 id="header"></h1>
<h2>To Do List <span id="counter"></span></h2>
<h3>"If you can dream it, you can do it" - Walt Disney</h3>
<div id="newItemButton"><button href="#" id="showForm">New Entry</button></div>
<form id="newItemForm">
<input type="text" id="itemDescription" placeholder="Enter goal" />
<input type="submit" id="add" value="Submit"/>
</form>
<ul>
<!--<li id="one">Exercise</li>
<li id="two">Study</li>
<li id="three">Practice a New Language</li>
<li id="four">Work on Personal Project</li>-->
</ul>
</div>
<div class="about">
<a id="link" href="x">About</a>
</div>
<script src="jquery-1.11.0.js"></script>
<script src="javascript_jquery.js"></script>
</body>
<footer>
<div id="footer">To do List Icons made by <a id="link" href="http://www.freepik.com" title="Freepik">Freepik</a> from <a id="link" href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> is licensed by <a id="link" href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a>
</div>
<div id="footer">Trash Icons made by <a id="link" href="https://www.flaticon.com/authors/dave-gandy" title="Dave Gandy">Dave Gandy</a> from <a id="link" href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> is licensed by <a id="link" href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a></div>
</footer>
</html>
Here is the Javascript/jQuery. The focus of my issue is on the Delete function at the bottom and probably the .append part under "Check as Complete."
/*eslint-env jquery*/
/* eslint-env browser */
$(document).ready(function() {
// SETUP
var $list, $newItemForm, $newItemButton;
var item = ''; // item is an empty string
$list = $('ul'); // Cache the unordered list
$newItemForm = $('#newItemForm'); // Cache form to add new items
$newItemButton = $('#newItemButton'); // Cache button to show form
// ITEM COUNTER
function updateCount() { // Create function to update counter
var items = $('li[class!=complete]').length; // Number of items in list
$('#counter').text(items); // Added into counter circle
}
updateCount(); // Call the function
// SETUP FORM FOR NEW ITEMS
$newItemButton.show(); // Show the button
$newItemForm.hide(); // Hide the form
$('#showForm').on('click', function() { // When click on add item button
$newItemButton.hide(); // Hide the button
$newItemForm.show(); // Show the form
});
// ADDING A NEW LIST ITEM
$newItemForm.on('submit', function(e) { // When a new item is submitted
e.preventDefault(); // Prevent form being submitted
var text = $('input:text').val(); // Get value of text input
$list.append('<li>' + text + '</li>'); // Add item to end of the list
$('input:text').val(''); // Empty the text input
updateCount(); // Update the count
});
//Check as Complete
$list.on('click', 'li', function() {
var $this = $(this);
var complete = $this.hasClass('complete');
if (complete !== true) {
item = $this.text(); // Get the text from the list item
$this.remove(); // Remove the list item
$list // Add back to end of list as complete
.append('<li class=\"complete\">' + item + '<button type="button" class="trashbutton" src="/images/icon-trash.png" alt="Trash Icon"></button>' + '</li>')
.hide().fadeIn(300); // Hide it so it can be faded in
complete = true;
}
updateCount();
});
/*//Check as Incomplete
$list.on('click', 'li', function() {
var $this = $(this);
var complete = $this.hasClass('complete');
if (complete === true) {
item = $this.text();
$this.remove();
$list
.append('<li>' + item + '</li>')
.hide().fadeIn(300);
}
updateCount();
});*/
// Delete
$list.on('click', 'li', function() {
var $this = $(this);
var readyToDelete = $this.hasClass('trashbutton');
if(readyToDelete === true) {
$this.animate({
opacity: 0.0,
paddingLeft: '+=180'
}, 500, 'swing', function() {
$this.remove();
});
}
updateCount;
});
});
Here is the CSS just in case.
#import url(http://fonts.googleapis.com/css?family=Oswald);
body {
background-color: whitesmoke;
font-family: 'Oswald', 'Futura', sans-serif;
margin: 0;
padding: 0;
}
#page {
background-color: black;
margin: 0 auto 0 auto;
position: relative;
text-align: center;
}
/* Responsive page rules at bottom of style sheet */
h1 {
background-image: url('/images/icon.png');
background-repeat: no-repeat;
background-position: center center;
text-align: center;
text-indent: -1000%;
height: 75px;
line-height: 75px;
width: 117px;
margin: auto auto auto auto;
padding: 30px 10px 20px 10px;
}
h2 {
color: #fff;
font-size: 24px;
font-weight: normal;
text-align: center;
text-transform: uppercase;
letter-spacing: .3em;
display: inline-block;
margin: 0 0 23px 0;
}
h2 span {
background-color: #fff;
color: green;
font-size: 12px;
text-align: center;
letter-spacing: 0;
display: inline-block;
position: relative;
border-radius: 50%;
top: -5px;
height: 22px;
width: 26px;
padding: 4px 0 0 0;
}
h3 {
color: white;
}
ul {
border:none;
padding: 0;
margin: 0;
}
li {
background-color: yellowgreen;
color: black;
border-top: 1px solid grey;
border-bottom: 1px solid grey;
font-size: 24px;
letter-spacing: .05em;
list-style-type: none;
text-shadow: 1px 1px 1px grey;
text-align: left;
height: 50px;
padding-left: 1em;
padding-top: 10px;
padding-right: 1em;
}
/* unvisited link */
#link:link {
color: yellowgreen;
}
/* visited link */
#link:visited {
color: green;
}
/* mouse over link */
#link:hover {
color: darkseagreen;
}
/* selected link */
#link:active {
color: forestgreen;
}
.about {
text-align: center;
}
#footer {
background:none;
color: black;
text-align: center;
}
.complete {
background-color: #999;
color: white;
border-top: 1px solid #666;
border-bottom: 1px solid #b0b0b0;
text-shadow: 2px 2px 1px #333;
}
.trashbutton {
background-image: url('/images/icon-trash.png');
background-position: center;
background-repeat: no-repeat;
background-size: 12px 12px;
margin: auto !important;
position: relative;
top: 35%;
transform: translateY(-50%);
}
/* FORM STYLES */
form {
padding: 0 20px 20px 20px;
}
input[type='text'], input[type='password'], textarea {
background-color: whitesmoke;
color: black;
font-size: 24px;
width: 96%;
padding: 4px 6px;
border: 1px solid #999;
border-radius: 8px;}
input[type='submit'], a.add, button, a.show {
background-color: yellowgreen;
color: black;
border-radius: 8px;
border: none;
padding: 8px 10px;
margin-top: 10px;
font-family: 'Oswald', 'Futura', sans-serif;
font-size: 18px;
text-shadow: 1px 1px 1px grey;
text-decoration: none;
text-transform: uppercase;}
input[type='submit'], button {
float: right;
}
input[type='submit']:hover {
background-color: green;
color: #fff;
cursor: pointer;
}
/* form example */
#newItemButton {
padding: 10px 20px 75px 20px;
display: none;
}
#newItemForm {
padding-top: 20px;
}
#itemDescription {
width: 325px;
}
#newItemForm input[type='submit'] {
margin-top: 0;
text-align: center;
}
/* Attributes example */
#group {
margin: 10px;
border: 2px solid #fff;
}
/* Small screen:mobile */
#media only screen and (max-width: 500px) {
body {
background-color: #403c3b;
}
#page {
max-width: 480px;
}
}
#media only screen and (min-width: 501px) and (max-width: 767px) {
#page {
max-width: 480px;
margin: 20px auto 20px auto;
}
}
#media only screen and (min-width: 768px) and (max-width: 959px) {
#page {
max-width: 480px;
margin: 20px auto 20px auto;
}
}
/* Larger screens act like a demo for the app */
#media only screen and (min-width: 960px) {
#page {
max-width: 480px;
margin: 20px auto 20px auto;
}
}
#media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
h1{
background-image: url('/images/icon.png');
background-size: 100px 100px;
}
}
Some screenshots of what works so far. You can see the tasks as incomplete in green, completed in grey, and the trash button shows up when the task is grey.
When app first loads
One incomplete task and one complete task. Notice trash button that does not work.
NOTE: I should mention that, while heavily altered, the HTML and JS code is derived from an example from Jon Duckett's Javascript and jQuery book. This is my first time ever working with jQuery and the purpose of this assignment is to learn the basics.
Here is how you can get it working:
Change $list.on('click', 'li', function() { to $list.on('click', 'li > button', function() { (your list items doesn't have 'trashbutton' class).
Update code you use to delete element since after clicking on a button you have to delete parent element (li), not the button itself.
Take a look at this in action:
$(document).ready(function() {
// SETUP
var $list, $newItemForm, $newItemButton;
var item = ''; // item is an empty string
$list = $('ul'); // Cache the unordered list
$newItemForm = $('#newItemForm'); // Cache form to add new items
$newItemButton = $('#newItemButton'); // Cache button to show form
// ITEM COUNTER
function updateCount() { // Create function to update counter
var items = $('li[class!=complete]').length; // Number of items in list
$('#counter').text(items); // Added into counter circle
}
updateCount(); // Call the function
// SETUP FORM FOR NEW ITEMS
$newItemButton.show(); // Show the button
$newItemForm.hide(); // Hide the form
$('#showForm').on('click', function() { // When click on add item button
$newItemButton.hide(); // Hide the button
$newItemForm.show(); // Show the form
});
// ADDING A NEW LIST ITEM
$newItemForm.on('submit', function(e) { // When a new item is submitted
e.preventDefault(); // Prevent form being submitted
var text = $('input:text').val(); // Get value of text input
$list.append('<li>' + text + '</li>'); // Add item to end of the list
$('input:text').val(''); // Empty the text input
updateCount(); // Update the count
});
//Check as Complete
$list.on('click', 'li', function() {
var $this = $(this);
var complete = $this.hasClass('complete');
if (complete !== true) {
item = $this.text(); // Get the text from the list item
$this.remove(); // Remove the list item
$list // Add back to end of list as complete
.append('<li class=\"complete\">' + item + '<button type="button" class="trashbutton" src="/images/icon-trash.png" alt="Trash Icon"></button>' + '</li>')
.hide().fadeIn(300); // Hide it so it can be faded in
complete = true;
}
updateCount();
});
/*//Check as Incomplete
$list.on('click', 'li', function() {
var $this = $(this);
var complete = $this.hasClass('complete');
if (complete === true) {
item = $this.text();
$this.remove();
$list
.append('<li>' + item + '</li>')
.hide().fadeIn(300);
}
updateCount();
});*/
// Delete
$list.on('click', 'li > button', function() {
var $this = $(this);
var readyToDelete = $this.hasClass('trashbutton');
if(readyToDelete === true) {
$this.parent().animate({
opacity: 0.0,
paddingLeft: '+=180'
}, 500, 'swing', function() {
$(this).remove();
});
}
updateCount;
});
});
#import url(http://fonts.googleapis.com/css?family=Oswald);
body {
background-color: whitesmoke;
font-family: 'Oswald', 'Futura', sans-serif;
margin: 0;
padding: 0;
}
#page {
background-color: black;
margin: 0 auto 0 auto;
position: relative;
text-align: center;
}
/* Responsive page rules at bottom of style sheet */
h1 {
background-image: url('/images/icon.png');
background-repeat: no-repeat;
background-position: center center;
text-align: center;
text-indent: -1000%;
height: 75px;
line-height: 75px;
width: 117px;
margin: auto auto auto auto;
padding: 30px 10px 20px 10px;
}
h2 {
color: #fff;
font-size: 24px;
font-weight: normal;
text-align: center;
text-transform: uppercase;
letter-spacing: .3em;
display: inline-block;
margin: 0 0 23px 0;
}
h2 span {
background-color: #fff;
color: green;
font-size: 12px;
text-align: center;
letter-spacing: 0;
display: inline-block;
position: relative;
border-radius: 50%;
top: -5px;
height: 22px;
width: 26px;
padding: 4px 0 0 0;
}
h3 {
color: white;
}
ul {
border:none;
padding: 0;
margin: 0;
}
li {
background-color: yellowgreen;
color: black;
border-top: 1px solid grey;
border-bottom: 1px solid grey;
font-size: 24px;
letter-spacing: .05em;
list-style-type: none;
text-shadow: 1px 1px 1px grey;
text-align: left;
height: 50px;
padding-left: 1em;
padding-top: 10px;
padding-right: 1em;
}
/* unvisited link */
#link:link {
color: yellowgreen;
}
/* visited link */
#link:visited {
color: green;
}
/* mouse over link */
#link:hover {
color: darkseagreen;
}
/* selected link */
#link:active {
color: forestgreen;
}
.about {
text-align: center;
}
#footer {
background:none;
color: black;
text-align: center;
}
.complete {
background-color: #999;
color: white;
border-top: 1px solid #666;
border-bottom: 1px solid #b0b0b0;
text-shadow: 2px 2px 1px #333;
}
.trashbutton {
background-image: url('/images/icon-trash.png');
background-position: center;
background-repeat: no-repeat;
background-size: 12px 12px;
margin: auto !important;
position: relative;
top: 35%;
transform: translateY(-50%);
}
/* FORM STYLES */
form {
padding: 0 20px 20px 20px;
}
input[type='text'], input[type='password'], textarea {
background-color: whitesmoke;
color: black;
font-size: 24px;
width: 96%;
padding: 4px 6px;
border: 1px solid #999;
border-radius: 8px;}
input[type='submit'], a.add, button, a.show {
background-color: yellowgreen;
color: black;
border-radius: 8px;
border: none;
padding: 8px 10px;
margin-top: 10px;
font-family: 'Oswald', 'Futura', sans-serif;
font-size: 18px;
text-shadow: 1px 1px 1px grey;
text-decoration: none;
text-transform: uppercase;}
input[type='submit'], button {
float: right;
}
input[type='submit']:hover {
background-color: green;
color: #fff;
cursor: pointer;
}
/* form example */
#newItemButton {
padding: 10px 20px 75px 20px;
display: none;
}
#newItemForm {
padding-top: 20px;
}
#itemDescription {
width: 325px;
}
#newItemForm input[type='submit'] {
margin-top: 0;
text-align: center;
}
/* Attributes example */
#group {
margin: 10px;
border: 2px solid #fff;
}
/* Small screen:mobile */
#media only screen and (max-width: 500px) {
body {
background-color: #403c3b;
}
#page {
max-width: 480px;
}
}
#media only screen and (min-width: 501px) and (max-width: 767px) {
#page {
max-width: 480px;
margin: 20px auto 20px auto;
}
}
#media only screen and (min-width: 768px) and (max-width: 959px) {
#page {
max-width: 480px;
margin: 20px auto 20px auto;
}
}
/* Larger screens act like a demo for the app */
#media only screen and (min-width: 960px) {
#page {
max-width: 480px;
margin: 20px auto 20px auto;
}
}
#media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
h1{
background-image: url('/images/icon.png');
background-size: 100px 100px;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="page">
<h1 id="header"></h1>
<h2>To Do List <span id="counter"></span></h2>
<h3>"If you can dream it, you can do it" - Walt Disney</h3>
<div id="newItemButton"><button href="#" id="showForm">New Entry</button></div>
<form id="newItemForm">
<input type="text" id="itemDescription" placeholder="Enter goal" />
<input type="submit" id="add" value="Submit"/>
</form>
<ul>
<!--<li id="one">Exercise</li>
<li id="two">Study</li>
<li id="three">Practice a New Language</li>
<li id="four">Work on Personal Project</li>-->
</ul>
</div>
<div class="about">
<a id="link" href="x">About</a>
</div>
<script src="jquery-1.11.0.js"></script>
<script src="javascript_jquery.js"></script>
It would be easier for you to accomplish your task by giving the trashbutton class a click event to remove its parent li from the list. This can be accomplished with the following code.
// Delete
$('.trashbutton').click(function (e) {
e.preventDefault();
$(this).parent().animate({
opacity: 0.0,
paddingLeft: '+=180'
}, 500, 'swing', function() {
$(this).parent().remove();
});
}
updateCount();
})

jQuery appending 300 divs in for loop has extra top and bottom margin

Not really sure why there's extra space above and below my boxes that I'm appending in a simple for loop.
HTML:
<body>
<div id="header">
Snake
</div>
<div id="game-container"></div>
</body>
CSS: (I tried a lot of go-tos)
* {
box-sizing: border-box;
margin: 0;
padding: 0;
border: 0;
}
html, body {
border: 0;
padding: 0;
margin: 0;
}
#header {
text-align: center;
font-size: 5em;
color: rgb(0, 50, 105);
}
#game-container {
width: 280px;
padding: 0;
margin: 0 auto;
}
.one-square {
width: 14px;
height: 14px;
border: 1px solid grey;
display: inline-block;
margin: 0;
padding: 0;
}
JQUERY:
$(document).ready(function(){
var div = '<div class="one-square"></div>';
for(var i = 0; i < 300; i++){
$('#game-container').append(div);
}
});
Clearly I'm missing something obvious. Quick codepen to demonstrate: http://codepen.io/anon/pen/WrperX
Just add line-height:0px; to your #game-conatiner div.
#game-container {
width: 280px;
padding: 0;
margin: 0 auto;
line-height:0px; /* ADDED */
}
Working Fiddle
Explanation: While your div has some line-height by default which has height more than your one-square div's so it has space above and below. Adding line-height:0px it will remove it.
Change
.one-square {
display: inline-block;
}
To:
.one-square {
display: block;
float: left;
}
See this updated code-pen
Add line-height: 0em; for the #game-container.
#game-container {
width: 280px;
padding: 0px;
margin: 0px auto;
line-height: 0em;
}
Hope this will solve your problem.

Categories

Resources