jQuery loop pausing in a particular spot - javascript

I have a strange issue with a script that I've created. My jQuery/Javascript skills aren't great (I'm still learning) and am hoping someone could help me understand why this is happening.
I'm developing an online store and have a strip of 4 divs floated next to each other across the top with notices I'd like to highlight for my customers.
The site is responsive, so for mobile I wanted to reduce this to one notice at a time, and fade out and fade in each notice.
I also didn't want to simply use CSS media queries to show and hide a desktop and mobile version as I feel that might work against me, SEO-wise, if I was to repeat the content twice. Therefore I've put together a jQuery script to grab the content of the first set of divs, put them into an array, and fade in and out each notice in a loop.
I thought I'd done it however noticed something strange in both Firefox and Chrome: it loops through once fine, but then stops completely when displaying "100% happiness guarantee" the second time, and I'm at a loss as to why.
I've created a JSFiddle with the code I'm using here:
http://jsfiddle.net/qewwmnge/
$(document).ready(function() {
// Transform the highlights div into a 1 line bar for mobile devices
// Read the highlights div content into an array
var highlights = new Array();
$("#highlights").find("div").each(function(){
highlights.push($(this).html());
});
$text = $('#highlights-mobile div'),
delay = 5;
// Set the initial highlight item on page load
$text.html( highlights[0] );
// Loop through the array and fade in each highlight
function loop ( delay ) {
$.each( highlights, function ( i, elm ){
if ($text.html() != highlights[i]) { // Skip the first fade in on the first loop so it doesn't repeat itself
$text.delay( delay*1E3).fadeOut();
$text.queue(function(){
$text.html( highlights[i] );
$text.dequeue();
});
$text.fadeIn();
$text.queue(function(){
if ( i == highlights.length -1 ) {
loop(delay);
}
$text.dequeue();
});
}
});
}
loop( delay );
});
If anyone could tell me what I'm doing wrong I'd really appreciate it!

Your jQuery code contain queue/dequeue logic, there is no need to do that.
It's better to use simple jquery for same thing. See this demo JSFiddle
$(function () {
var $highlights = $("#highlights-mobile div");
var divsHTML = new Array();
$("#highlights").find("div").each(function(){
divsHTML.push($(this).html());
});
var position = -1;
!function loop() {
position = (position + 1) % divsHTML.length;
$highlights.html(divsHTML[position])
.fadeIn(1000)
.delay(1000)
.fadeOut(1000,loop);
}();
});
#highlights, #highlights-mobile {
background-color: #E8E8E8;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
position: relative;
display: block;
box-sizing: border-box;
overflow: auto;
text-align: center;
margin-bottom: 20px;
}
#highlights h4, #highlights-mobile h4 {
text-align: center;
font-weight: bold;
padding: 0;
margin: 0;
font-size: 1.2em;
}
#highlights-mobile {
padding: 10px;
}
#highlights-mobile a, #highlights a {
color: #444;
text-decoration: none;
}
#highlights div {
text-align: center;
padding: 10px;
border-right: 1px solid #CDCDCD;
color: #444;
overflow: auto;
display: inline-block;
}
#media (min-width: 768px) {
#highlights {
display: block;
}
#highlights div:last-child {
border-right: none;
}
}
#media (min-width: 768px) {
#highlights div {
text-align: center;
padding: 10px;
border-right: 1px solid #CDCDCD;
color: #444;
overflow: auto;
display: inline-block;
}
#highlights div:last-child {
border-right: none;
}
#highlights h4 {
text-align: center;
font-weight: bold;
padding: 0;
margin: 0;
font-size: 1.2em;
}
#highlights a {
color: #444;
text-decoration: none;
}
#highlights-mobile {
display: none;
}
}
#media (max-width: 767px) {
#highlights {
display: none;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="highlights-mobile">
<div style="display: block;">
</div>
</div>
<div id="highlights">
<div>
<h4>Professionally refurbished</h4>Old school gear, good as new
</div>
<div>
<h4>Free shipping</h4>On orders over $250, nation wide
</div>
<div>
<h4>100% happiness guarantee</h4>Easy returns and a 60 day warranty
</div>
<div>
<h4>5% off your order</h4>When you pay with Bitcoin
</div>
</div>

Related

How make a textarea with tags in react that have clickable dropdown

Id like to make a component in react that allows me to have a textarea with tags that can be inserted when clicked from a dropdown. Id also like this textarea to be able to mix text aswell. I have currently been trying to use tagify with react but I cant seem to figure out a way to the tagify's function that adds the tag to be accessed by the onClick that is connected to the dropdown.
Any ideas?
I believe you can get your answer in this URL of other question asked on StackOverflow https://stackoverflow.com/a/38119725/15405352
var $container = $('.container');
var $backdrop = $('.backdrop');
var $highlights = $('.highlights');
var $textarea = $('textarea');
var $toggle = $('button');
// yeah, browser sniffing sucks, but there are browser-specific quirks to handle that are not a matter of feature detection
var ua = window.navigator.userAgent.toLowerCase();
var isIE = !!ua.match(/msie|trident\/7|edge/);
var isWinPhone = ua.indexOf('windows phone') !== -1;
var isIOS = !isWinPhone && !!ua.match(/ipad|iphone|ipod/);
function applyHighlights(text) {
text = text
.replace(/\n$/g, '\n\n')
.replace(/[A-Z].*?\b/g, '<mark>$&</mark>');
if (isIE) {
// IE wraps whitespace differently in a div vs textarea, this fixes it
text = text.replace(/ /g, ' <wbr>');
}
return text;
}
function handleInput() {
var text = $textarea.val();
var highlightedText = applyHighlights(text);
$highlights.html(highlightedText);
}
function handleScroll() {
var scrollTop = $textarea.scrollTop();
$backdrop.scrollTop(scrollTop);
var scrollLeft = $textarea.scrollLeft();
$backdrop.scrollLeft(scrollLeft);
}
function fixIOS() {
// iOS adds 3px of (unremovable) padding to the left and right of a textarea, so adjust highlights div to match
$highlights.css({
'padding-left': '+=3px',
'padding-right': '+=3px'
});
}
function bindEvents() {
$textarea.on({
'input': handleInput,
'scroll': handleScroll
});
$toggle.on('click', function() {
$container.toggleClass('perspective');
});
}
if (isIOS) {
fixIOS();
}
bindEvents();
handleInput();
#import url(https://fonts.googleapis.com/css?family=Open+Sans);
*, *::before, *::after {
box-sizing: border-box;
}
body {
margin: 30px;
background-color: #f0f0f0;
}
.container, .backdrop, textarea {
width: 460px;
height: 180px;
}
.highlights, textarea {
padding: 10px;
font: 20px/28px 'Open Sans', sans-serif;
letter-spacing: 1px;
}
.container {
display: block;
margin: 0 auto;
transform: translateZ(0);
-webkit-text-size-adjust: none;
}
.backdrop {
position: absolute;
z-index: 1;
border: 2px solid #685972;
background-color: #fff;
overflow: auto;
pointer-events: none;
transition: transform 1s;
}
.highlights {
white-space: pre-wrap;
word-wrap: break-word;
color: transparent;
}
textarea {
display: block;
position: absolute;
z-index: 2;
margin: 0;
border: 2px solid #74637f;
border-radius: 0;
color: #444;
background-color: transparent;
overflow: auto;
resize: none;
transition: transform 1s;
}
mark {
border-radius: 3px;
color: transparent;
background-color: #b1d5e5;
}
button {
display: block;
width: 300px;
margin: 30px auto 0;
padding: 10px;
border: none;
border-radius: 6px;
color: #fff;
background-color: #74637f;
font: 18px 'Opens Sans', sans-serif;
letter-spacing: 1px;
appearance: none;
cursor: pointer;
}
.perspective .backdrop {
transform:
perspective(1500px)
translateX(-125px)
rotateY(45deg)
scale(.9);
}
.perspective textarea {
transform:
perspective(1500px)
translateX(155px)
rotateY(45deg)
scale(1.1);
}
textarea:focus, button:focus {
outline: none;
box-shadow: 0 0 0 2px #c6aada;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="backdrop">
<div class="highlights"></div>
</div>
<textarea>This demo shows how to highlight bits of text within a textarea. Alright, that's a lie. You can't actually render markup inside a textarea. However, you can fake it by carefully positioning a div behind the textarea and adding your highlight markup there. JavaScript takes care of syncing the content and scroll position from the textarea to the div, so everything lines up nicely. Hit the toggle button to peek behind the curtain. And feel free to edit this text. All capitalized words will be highlighted.</textarea>
</div>
<button>Toggle Perspective</button>
Reference- https://codepen.io/lonekorean/pen/gaLEMR for example

Issue with ToDO list app and list item length

I'm working on a Q/A bare bones todolist app and notice that when a list item that is really long is added to the list, it pushes the button out.
Is there a way I can make the LI element larger when the textnode hits the button margin instead of pushing the button out of the LI element. Below is a screenshot. I'll post my source code below, but maybe this is a question that is a quick fix?
My source code can be found here - Issue with floating buttons right of my to do list
A) If I understood you well, you can easily fix it with CSS-Grid:
li {
display: grid;
grid-template-columns: 3fr 100px;
grid-template-areas: 'text button';
}
li > span {
grid-area: text;
}
li > button {
grid-area: button;
height: 30px;
}
https://jsfiddle.net/axqwhj29/
Play with the example linked above resizing the result area to check if that's what you are looking for.
B) Also, but I don't recommend you, if you really don't wanna change your li hight and you have a maximum text width (ex: 25 characters), you can clip parts of your message in a phone vertical view and if the user flips to horizontal show the whole text automatically.
https://jsfiddle.net/qfy3mz01/
Hope this help :)
Okay I have wrapped the text inside the li with span element and and added I add grid display to li and give every element inside the li a width and then I have added word-break: break-word; so the line will break when the text of the span reach the width limit and don't affect the delete button and I've deleted height from li so the li will grow with the lines on it
var addItemButton = document.getElementById('addItem')
var onEnter = document.getElementById('newNote')
//below event listener adds an item to the list on click
addItemButton.addEventListener('click', function() {
let item = document.getElementById('newNote').value
let node = document.createElement("li")
let span = document.createElement("span")
let textnode = document.createTextNode(item)
span.appendChild(textnode)
node.appendChild(span)
if (item) {
document.getElementById('list-body').appendChild(node)
}
let node2 = document.createElement('BUTTON')
let textnode2 = document.createTextNode('Delete')
node2.appendChild(textnode2)
node.appendChild(node2)
node2.addEventListener('click', function() {
node2.parentNode.parentNode.removeChild(node)
});
document.getElementById('newNote').value = ''
});
onEnter.addEventListener('keyup', function(event) {
if (event.keyCode === 13) {
// Cancel the default action, if needed
event.preventDefault();
// Trigger the button element with a click
addItemButton.click();
}
})
function applyButton() { //onload for dummy data or data from db
let getListObjects = document.querySelectorAll("li")
for (let i = 0; i < getListObjects.length; i++) {
let node2 = document.createElement('BUTTON')
let textnode2 = document.createTextNode('Delete')
node2.appendChild(textnode2)
getListObjects[i].appendChild(node2)
let y = getListObjects[i].querySelector('button')
y.addEventListener('click', function() {
y.parentNode.parentNode.removeChild(getListObjects[i])
});
}
}
.container {
height: 100%;
width: 40%;
margin: 0 auto;
}
.container2 {
display: grid;
grid-template-columns: repeat(2, 1fr);
background-color: grey;
border: 1px solid grey;
}
#main-grid {
width: 100%;
}
#newNote {
height: 25px;
}
#inputIdForGrid {
justify-content: left;
align-items: center;
display: flex;
padding-left: 0.3em;
padding-top: 0.5em;
padding-bottom: 0.5em;
}
button {
padding: 10px 18px;
background-color: green;
border: none;
color: white;
font-size: 14px;
align-self: center;
justify-self: end;
}
#addItem {
margin-left: 1em;
padding: 0.5em;
color: white;
font-size: 1.5em;
float: right;
}
ul {
list-style-type: none;
padding: 0px;
margin: 0px;
}
li {
padding: 5px 15px;
display: grid;
grid-template-columns: 2.5fr .5fr;
}
span {
word-break: break-word;
grid-column: 1 / 2;
display: flex;
align-items: center;
}
li:nth-child(2n) {
background-color: grey;
}
li>button {
background-color: red;
}
h1 {
text-align: center
}
<body onload="applyButton()">
<h1>Vanilla JS ToDo List - No Jquery, No Bootstrap</h1>
<div class='container'>
<div id='main-grid'>
<div class="container2">
<div id='inputIdForGrid'>
<input type='text' placeholder="Enter List Items Here" id='newNote'>
</div>
<div>
Hi
</div>
</div>
<ul id='list-body'>
<li><span>run all around town. walk all around town. drive all around town</span></li>
<li><span>Buy Apples</span></li>
<li><span>Hit Gym and Lift Bro</span></li>
<li><span>Stretch</span></li>
</ul>
</div>
</div>
</body>
P.S. I've edited your js code so it will generate span and add the text inside it

Hold ul visible when parent loses hover (pure css if possible)

I'm quite new with css. I want hold the ul visible when hovering from parent to ul. I don't know how do it.
HTML Markup
<drop-down class="dropdown">
<span>Dropdown menu<i class="fa fa-cog"></i></span>
<ul>
<li>
Github<i class="fa fa-github"></i>
</li>
<li>
BitBucket<i class="fa fa-bitbucket"></i>
</li>
<li>
Dropbox<i class="fa fa-dropbox"></i>
</li>
<li>
Google drive<i class="fa fa-google"></i>
</li>
</ul>
</drop-down>
CSS
drop-down {
background-color: #e9e9e9;
border: 1px solid #d2c2c2;
border-radius: 2px;
display: flex;
flex-flow: column nowrap;
height: 40px;
justify-content: center;
position: relative;
width: 160px;
}
drop-down:hover { cursor: pointer; }
drop-down > span {
align-items: center;
color: #555;
display: flex;
font-family: 'segoe ui';
font-size: .9rem;
justify-content: space-between;
padding: 0px .75rem;
pointer-events: none;
}
drop-down > span > i {
color: inherit;
}
drop-down ul {
background-color: #e9e9e9;
border: 1px solid #d2c2c2;
border-radius: 2px;
box-shadow: 0px 2px 5px 1px rgba(0,0,0,.15);
display: block;
right: 10%;
list-style: none;
padding: .5rem 0;
position: absolute;
opacity: 0;
pointer-events: none;
visibility: hidden;
top: 160%;
transition: all .2s ease-out;
width: 100%;
z-index: 999;
}
drop-down ul > li {
color: #555;
display: block;
}
drop-down ul > li:hover {
background-color: #007095;
color: rgba(255,255,255,.9);
}
drop-down ul > li > a {
align-items: center;
color: inherit;
display: flex;
font-family: 'segoe ui';
font-size: .95rem;
justify-content: space-between;
padding: .5rem .75rem;
text-decoration: none;
}
drop-down ul > li > a > i {
color: inherit;
}
drop-down:focus {
outline: none;
}
drop-down:hover ul {
pointer-events: auto;
opacity: 1;
top: 120%;
visibility: visible;
}
You can see it running at this fiddle: http://jsfiddle.net/vt1y9ruo/1/
I can do it with javascript, but I don't want use it for something small.
Here's a working fiddle: http://jsfiddle.net/vt1y9ruo/8/
It works by inserting an invisible bridge between the button and the list.
drop-down:hover ul, #ulwrap:hover ul {
pointer-events: auto;
opacity: 1;
top:120%;
visibility: visible;
}
#ulwrap {
display: block;
height:0;
width:100%;
position:absolute;
}
drop-down:hover #ulwrap, #ulwrap:hover {
height:100px;
}
if you want to do this using the hover feature of css, the gap between the button and the list is what's killing you. either remove this gap or use js
on a side note there is no harm in using js for something small, this is what its used for, just make it nice and reusable
Well, pure css solution (many thanks #JBux) is a little dirty (mark up). I finally go for JS solution and for this, created a custom tag:
const helper = new Helper(); // helper functions
var ddProto = Object.create(HTMLElement.prototype);
ddProto.properties = {
list: null,
options: null,
value: null,
icon: null,
index: -1,
};
ddProto.initEvents = function() {
var self = this;
// mouse over button
this.addEventListener('mouseover', function(e) {
if(!helper.hasClass(this, 'dropdown-active'))
helper.addClass(this, 'dropdown-active');
});
// mouseleave over button
this.addEventListener('mouseleave', function(e){
var rect = this.getBoundingClientRect();
var left = e.pageX;
var bottom = e.pageY;
// if mouse is out of X axis of button and if mouse is
// out (only of top) of Y axis of button, hide ul
if(left < rect.left || left >= rect.right || bottom < rect.top) {
helper.delClass(this, 'dropdown-active');
}
});
// list loses hover
this.properties.list.addEventListener('mouseleave', function(e) {
if(helper.hasClass(self, 'dropdown-active'))
helper.delClass(self, 'dropdown-active');
});
// elements click
[].forEach.call(this.properties.options, function(e) {
e.addEventListener('click', function(event){
event.preventDefault();
// set the text of selected value to button
helper.text(self.properties.value, e.innerText);
// set the position of selected value
self.properties.index = helper.position(e.parentNode);
// set the <i> class name to the button (fontawesome)
self.properties.icon.className = this.children[0].className;
// hide ul
helper.delClass(self,'dropdown-active');
},true);
});
};
ddProto.value = function() {
return this.properties.value;
};
ddProto.index = function() {
return this.properties.index;
}
ddProto.createdCallback = function() {
this.properties.list = this.querySelector('ul');
this.properties.options = this.querySelectorAll('ul > li > a');
this.properties.value = this.querySelector('span');
this.properties.icon = this.querySelector('span > i');
this.initEvents();
};
document.registerElement('drop-down', {prototype: ddProto});
Working fiddle: http://jsfiddle.net/m2dtmr24/2/
Thank you so much.
The thing you could check is the + selector (more here)
In short it lets you add styles to elements right next to each other. The actual css might look something like this:
.dropdown{
display: none;
}
.button:hover+.dropdown{
display: block;
}
This will only work when .dropdown is directly below .button in the DOM
The animation might be harder, but you could achieve something similar by for example using transition on opacity, and toggle opacity instead of display

JavaScript induced style changes are not permanent

Okay, I change the appearance of links using JavaScript. When I change the content of a hard-coded link, it sticks in that the changed color and underlining remains when the cursor is not hovering above it. However, when the content of a DIV has been changed using JavaScript, the style changes do not stick.
Here is the HTML code:
<!doctype html>
<html>
<head>
<title>Bla bla</title>
<meta charset="UTF-8">
<link href="style/kim.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="scripts/Kim.js"></script>
</head>
<body>
<div class="wrapper">
<div class="main">
<div class="nav">
<div class="topNav">
<ul>
<li onClick="changeNav('design')">Design</li>
<li onClick="changeNav('code')">Programming</li>
<li onClick="changeNav('science')">Science</li>
<li onClick="changeNav('Kim')">Kim</li>
</ul>
</div>
<div id="subNav">
<script>changeNav("design");</script>
</div>
</div>
<div class="content">
<p id="mainText">Test</p>
</div>
</div>
</div>
</body>
</html>
Here is the JS code:
var topNavNames = ["design", "code", "science", "Kim"];
var subNavCode = ["<ul><li onClick=\"loadPHP('design/websites.php', 'sub0')\">Websites</li><li onClick=\"loadPHP('design/graphics.php', 'sub1')\">Graphics</li><li onClick=\"loadPHP('design/flash.php', 'sub2')\">Flash</li></ul>",
"<ul><li onClick=\"loadPHP('code/interactive.php', 'sub0')\">Interactive applets</li><li onClick=\"loadPHP('code/statistics.php', 'sub1')\">Statistics</li><li onClick=\"loadPHP('code/wings.php', 'sub2')\">Wings</li><li onClick=\"loadPHP('code/3D.php', 'sub3')\">3D</li></ul>",
"<ul><li onClick=\"loadPHP('science/3D.php', 'sub0')\">3D</li><li onClick=\"loadPHP('science/ssd.php', 'sub1')\">Sexual Size Dimorphism</li><li onClick=\"loadPHP('science/shape.php', 'sub2')\">Wing shape</li><li onClick=\"loadPHP('science/phylogenetics.php', 'sub3')\"><i>Drosophila</i> phylogenetics</li><li onClick=\"loadPHP('science/communitygenetics.php', 'sub4')\">Community Genetics</li><li onClick=\"loadPHP('science/biodiversity.php', 'sub5')\">Biodiversity</li></ul>",
"<ul><li onClick=\"loadPHP('Kim.php', 'sub0')\">Who is Kim?</li><li onClick=\"loadPHP('animals/horses.php', 'sub1')\">Horses</li><li onClick=\"loadPHP('animals/birds.php', 'sub2')\">Birds</li><li onClick=\"loadPHP('private/outdoors.php', 'sub3')\">Outdoors</li><li onClick=\"loadPHP('contact.php', 'sub4')\">Contact</li></ul>"];
function changeNav(target) {
for (var i = 0; i<topNavNames.length; i++) {
if (target == topNavNames[i]) {
document.getElementById("subNav").innerHTML=subNavCode[i];
document.getElementById(topNavNames[i]).style.color="#F7EDAA";
document.getElementById(topNavNames[i]).style.borderBottom="thin solid #F7EDAA";
}
else {
document.getElementById(topNavNames[i]).style.color="#EEE";
document.getElementById(topNavNames[i]).style.borderBottom="thin solid #111";
}
}
}
function loadPHP(url, target) {
for (var i = 0; i<10; i++) {
if(document.getElementById(target)!=null) {
if (("sub"+i) == target) {
document.getElementById(target).style.color="#F7EDAA";
document.getElementById(target).style.borderBottom="thin solid #F7EDAA";
}
else {
document.getElementById(target).style.color="#EEE";
document.getElementById(target).style.borderBottom="thin solid #111";
}
}
}
}
if I subsequently remove the:
else {
document.getElementById(target).style.color="#EEE";
document.getElementById(target).style.borderBottom="thin solid #111";
}
from the loadPHP function, it changes the style, but does not reset it when the next link is clicked.
I observed this behavior in FireFox, Internet Exploder and Chrome.
Added: CSS code:
body {
background-color: #111111;
color: #DDD;
font-family: "Gill Sans", "Gill Sans MT", "Myriad Pro", "DejaVu Sans Condensed", Helvetica, Arial, sans-serif;
}
.wrapper {
overflow: auto;
}
.banner {
float: left;
position: relative;
width: 100px;
}
.main {
position: relative;
width: 80%;
left: 25px;
font-size: 14px;
font-weight: normal;
}
a {
text-decoration: none;
color: #EEE;
}
a:hover {
border-bottom: thin solid #F7EDAA !important;
color: #F7EDAA !important;
}
.topNav {
height: 45px;
position: relative;
left: 100px;
font-size: large;
border: thin solid #111;
}
#subNav {
height: 45px;
position: relative;
left: 100px;
top: 2px;
border: thin solid #111;
}
.topNav li, #subNav li {
float: left;
margin: 10px 15px;
}
.topNav ul, #subNav ul {
list-style: none;
padding: 0px 0px;
margin: 0px 0px;
position: relative;
left: -100px;
}
.content {
position: relative;
left: 15px;
padding: 0px 0px;
margin: 0px 0px;
}
.content p {
padding: 5px 5px;
margin: 10px 15px;
left: -100px;
}
In my opinion you´re using the wrong technology to achieve your goal. What you need to do is to write your styles in a css stylesheet, and then add or remove classes to your elements using js if you want. (You can also do this through something called specificity, a little far ahead from the scope of your question)
Also think that if there is some bug in your script, or a third party script called in your page, JS may break and it won´t process your styling changes.
So, add the basic styling to your elements through css in the initial markup, so you will be sure that your elements will have always a basic styling, and then if you want use the equivalent to .addClass or removeClass jQuery methods.
In that way you will be always sure that your frontend will have always a safe styling, won´t break if js is not loaded, and separation of concerns will be properly implemented.
Regards.
I figured it out. The following code does not do the right thing:
function loadPHP(url, target) {
for (var i = 0; i<subNavNames.length; i++) {
if (target == subNavNames[i]){
document.getElementById(target).className="selected";
} else {
document.getElementById(target).className="notSelected";
}
}
While this code does produce the right result:
function loadPHP(url, target) {
for (var i = 0; i<subNavNames.length; i++) {
if (target == subNavNames[i]) {
document.getElementById(subNavNames[i]).className="selected";
} else {
document.getElementById(subNavNames[i]).className="notSelected";
}
}
The difference is that in the first example, and in the example of the original question, I use the variable passed on in the method (target), to find the element. In the second, I use the appropriate element from a array that I have added to the list. I am not sure WHY this behaves differently, but it does.

Optimize jQuery code

I've written this jQuery code that fades in a overlay with some links over an image. What i found out is that it is painfully slow when I add like 10 of these images. I would really appreciate some tips and tricks on how to make this code faster.
If you have some tips for my HTML and CSS that would be great too ;)
jQuery code
$(document).ready(function() {
var div = $(".thumb").find("div");
div.fadeTo(0, 0);
div.css("display","block");
$(".thumb").hover(
function () {
$(this).children(".download").fadeTo("fast", 1);
$(this).children(".hud").fadeTo("fast", 0.7);
},
function () {
div.fadeTo("fast", 0);
}
);
});
All the code
<style type="text/css">
a:active {
outline:none;
}
:focus {
-moz-outline-style:none;
}
img {
border: none;
}
#backgrounds {
font: 82.5% "Lucida Grande", Lucida, Verdana, sans-serif;
margin: 50px 0 0 0;
padding: 0;
width: 585px;
}
.thumb {
margin: 5px;
position: relative;
float: left;
}
.thumb img {
background: #fff;
border: solid 1px #ccc;
padding: 4px;
}
.thumb div {
display: none;
}
.thumb .download {
color: #fff;
position: absolute;
top: 0;
left: 0;
z-index: 999;
padding: 0 10px;
}
.thumb .download h3 {
font-size: 14px;
margin-bottom: 10px;
margin-top: 13px;
text-align: center;
}
.thumb .download a {
font-size: 11px;
color: #fff;
text-decoration: none;
font-weight: bold;
line-height: 16px;
}
.thumb .download a:hover {
text-decoration: underline;
}
.thumb .download .left, .thumb .download .right {
width: 44%;
margin: 0;
padding: 4px;
}
.thumb .download .left {
float: left;
text-align: right;
}
.thumb .download .right {
float: right;
text-align: left;
}
.thumb img, .thumb .hud {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
.thumb .hud {
width: 100%;
height: 110px;
position: absolute;
top: 0;
left: 0;
background: #000;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var div = $(".thumb").find("div");
div.fadeTo(0, 0);
div.css("display","block");
$(".thumb").hover(
function () {
$(this).children(".download").fadeTo("fast", 1);
$(this).children(".hud").fadeTo("fast", 0.7);
},
function () {
div.fadeTo("fast", 0);
}
);
});
</script>
<div id="backgrounds">
<div class="thumb">
<div class="download">
<h3>Download wallpaper</h3>
<p class="left">
1024x768
1280x800
1280x1024
</p>
<p class="right">
1440x900
1680x1050
1920x1200
</p>
</div>
<div class="hud"></div>
<img alt="image" src="thumb.jpg"/>
</div>
</div>
I got it to respond a little better by simply changing the following within the hover(..):
function () {
$(".download", this).fadeTo("fast", 1);
$(".hud", this).fadeTo("fast", 0.7);
},
function () {
$(".download, .hud", this).fadeTo("fast", 0);
}
The biggest difference comes from only applying the hoverout effect to the event target, no need to reapply to all your divs on the page.
I've put your code into a test page and to be perfectly honest, even with thirty or so .thumb divs it seemed ok - certainly responsive enough to use from my end. Sliding the mouse over a bunch of them means I have to wait for the rollover effect to go through them all which takes a while until it gets to the one I've actually stopped on, but surely that was what you wanted given that you're using 'hover' rather than 'click' (which would certainly remove any speed issues).
I'm not using actual images in my test page, just getting the alt text, so my best current guess would be to make sure all images you're loading are as small filesize as you can possibly make them.
Pre-Select MORE
Good job preselecting the div. Try this way so that it pre-selects the fade in elements as well instead of doing it on hover:
$().ready(function() {
var div = $(".thumb").find("div");
div.fadeTo(0, 0);
div.css("display","block");
$(".thumb").each(function() {
var download = $(this).children(".download");
var hud = $(this).children(".hud");
$(this).hover(
function () {
download.fadeTo("fast", 1);
hud.fadeTo("fast", 0.7);
},
function () {
div.fadeTo("fast", 0);
}
);
});
});
try removing the
:focus {
-moz-outline-style:none;
}
and see what happens

Categories