element.scrollTop/left is really slow in Safari, why? - javascript

When the given HTML code below is loaded in Safari 6.0.8, the scroll function executes in ~1500 ms. In Chrome that number is ~50 ms and in FireFox ~5 ms.
I've identified the scroll methods to be the culprits, but I can't figure out why Safari is so damn slow executing them. Is it an implementation detail of Safari, or am I doing something wrong?
<html>
<head>
<style>
.container {
width: 20%;
height: 100px;
background: #FF9800;
position: relative;
}
</style>
</head>
<body>
<div id="top">
<!-- 500 of these will be generated and added to the #top element -->
<div class="container">
<div style="position: absolute; left: -1px; top: -1px; right: 0px; bottom: 0px; overflow: scroll; z-index: -1; visibility: hidden;">
<div style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px; overflow: scroll; z-index: -1; visibility: hidden;">
<div style="position: absolute; left: 0px; top: 0px; width: 294.796875px; height: 110px;"></div>
</div>
<div style="position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px; overflow: scroll; z-index: -1; visibility: hidden;">
<div style="position: absolute; left: 0px; top: 0px; width: 200%; height: 200%;"></div>
</div>
</div>
</div>
</div>
<script>
//Generates the 500 container elements.
var numElements = 499;
var containerOriginal = document.querySelector(".container");
for(var i = 0; i < numElements; i++) {
var container = containerOriginal.cloneNode(true);
document.getElementById("top").appendChild(container);
}
//Why is this function so slow in Safari?
function scroll(el, et, sl, st) {
var containers = document.querySelectorAll(".container");
for(var i = 0; i < containers.length; i++) {
var container = containers[i];
var expand = container.children[0].children[0];
var shrink = container.children[0].children[1];
expand.scrollLeft = el;
expand.scrollTop = et;
shrink.scrollLeft = sl;
shrink.scrollTop = st;
}
}
//Execute the actual test on document ready.
document.addEventListener('DOMContentLoaded', function () {
console.time("test");
scroll(9, 9, 144, 101);
console.timeEnd("test");
}, false);
</script>
</body>
</html>

To my best guess of why this is so slow is because you are trying to load many elements. What I would suggest instead of
var expand = container.children[0].children[0];
var shrink = container.children[0].children[1];
putting a class on these children elements you are wanting to get and getting them that way.

Related

Dropdown mobile menu sliding in from top by pressing the Icon

I want my mobile dropdown menu to slide in from top when the user clicks the "header-downbar-menu" icon and slide out to the top when the user clicks it again. For now the button can only show the menu but I don't know how to properly write JS for this part...
var DropdownMenuDown = false;
function OpenDropdownMenu() {
if (DropdownMenuDown == false) {
document.getElementById("header-dropdown-menu").style.top = "0px";
}
}
.header-dropdown {
width: 100%;
position: relative;
}
.header-dropdown-menu {
width: 100%;
height: 80vh;
background-color: white;
position: absolute;
top: -80vh;
}
<div class="header-downbar-menu" onclick="OpenDropdownMenu()">
<div class="bar1"></div>
<div class="bar2"></div>
<div class="bar3"></div>
</div>
<div class="header-dropdown">
<div id="header-dropdown-menu" class="header-dropdown-menu">
</div>
</div>
I can't make the var "DropdownMenuDown" work
I'd recommend you using toggle for this.
Look here:
function showMenu() {
var topmenu = document.querySelector('.topmenu');
topmenu.classList.toggle('show-me');
}
body {
margin: 0;
}
#bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #AEAEAE;
}
.topmenu {
position: absolute;
height: 60px;
top: -60px;
width: 100%;
background-color: red;
z-index: 99;
}
.show-me {
top: 0 !important;
}
button {
position: absolute;
top: 60px;
left: 0;
}
<div id="bg">
<div class="topmenu">
</div>
<button onclick="showMenu()">Menu pls!</button>
</div>
i just have read your question. i think you are not aware of the selector of document. in your case, the code should be like this.
var DropdownMenuDown = false;
function OpenDropdownMenu() {
if (DropdownMenuDown == false) {
document.getElementByClassName("header-dropdown-menu").style.top = "0px";
}
}
"header-dropdown-menu "is not id, but classname!

Javascript: display not changing from "block" to "none"

After clicking elements (the red square), the func function gets called and it gets the first child node, then that node changes It's children display to block. Now, I'm trying to set them back to none after clicking background_dim (the dark background) by getting background_dim's parent node, then iterating throught the children and setting their display to none. But apparently this doesn't work. It only works If I set their position to relative, but I'd have to change the other function as well.
function func(element) {
var _first_child = element.children[0];
for (var i = 0; i < _first_child.children.length; ++i)
_first_child.children[i].style.display = "block";
}
function func_t(element) {
var _parent = element.parentNode;
for (var i = 0; i < _parent.children.length; ++i)
_parent.children[i].style.display = "none";
}
.elements {
width: 40px;
height: 40px;
background-color: red;
}
.background {
display: none;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 100%;
width: 100%;
background-color: rgb(0, 0, 0, 0.7);
}
.display-container
{
display: none;
position: fixed;
top: 50%;
bottom: 30%;
left: 50%;
right: 0;
height: 100%;
width: 100%;
background-color: green;
}
<html>
<body>
<ul>
<li class="elements" onclick="func(this);">
<div class="_display_job_dim_">
<div class="background" onclick="func_t(this);"></div>
<div class="display-container"></div>
</div>
</li>
</ul>
</body>
</html>
https://jsfiddle.net/waxebm81/285/
Your problem is that if a click happens on background_dim it will by default propagate up in the DOM, so after func_t was called, the event will propagate to .elements and func(this) is called which will show the elements again.
So you ned to stop the propagation of the event:
document.querySelector('.elements').addEventListener('click', func, false)
document.querySelector('.background_dim').addEventListener('click', func_t, false)
function func(evt) {
evt.stopPropagation();
var element = evt.target;
var _first_child = element.children[0];
for (var i = 0; i < _first_child.children.length; ++i) {
_first_child.children[i].style.display = "block";
}
}
function func_t(evt) {
evt.stopPropagation();
var element = evt.target;
var _parent = element.parentNode;
for (var i = 0; i < _parent.children.length; ++i) {
_parent.children[i].style.display = "none";
}
return false;
}
.elements {
width: 40px;
height: 40px;
background-color: red;
}
.background_dim {
display: none;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 100%;
width: 100%;
background-color: rgb(0, 0, 0, 0.7);
}
.display-container {
display: none;
position: fixed;
top: 50%;
bottom: 30%;
left: 50%;
right: 0;
height: 100%;
width: 100%;
background-color: green;
}
<html>
<body>
<ul>
<li class="elements">
<div class="_display_job_dim_">
<div class="background_dim"></div>
<div class="display-container"></div>
</div>
</li>
</ul>
</body>
</html>

Maintain object visibility on height increase

How to fix object visibility on height scroll.
I have the following code below which grows height of the div based on user scroll. When you scroll down the spider image become invisible.
$(window).scroll(function() {
var bh = 100;
var height = $(window).scrollTop();
var sch = bh + height;
$('.webscroll').stop().animate({
'height': sch
}, 400)
if (height <= 19) {
$('.webscroll').stop().animate({
'height': 200
}, 600)
}
});
body {
background-color: #000;
height: 1200px;
}
.bottom_left_spider {
position: absolute;
width: 180px;
height: 200px;
left: 0;
top: 0;
z-index: 998
}
.webscroll {
height: 200px;
width: 1px;
border-right: 2px solid #2e2e2e;
position: absolute;
top: 0;
left: 101px;
z-index: 9999
}
.spidy {
position: absolute;
bottom: -51px;
left: -29px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="bottom_left_spider">
<img src="https://s17.postimg.org/cc243pkrz/spiderweb.png">
<!-- spider web lines -->
<div class="webscroll">
<!-- spider line vertical -->
<img src="https://s21.postimg.org/tbdww9hzr/spidy.png" class="spidy">
<!-- spider image -->
</div>
</div>
A woking jsfiddle sample is here: https://jsfiddle.net/ppw9z6y2/
You can use css transitions for the animation, and just change the height by javascript:
.webscroll {
...
transition: height 50ms ease-in-out
}
var $webscroll = $('.webscroll')[0];
$(window).scroll(function() {
var bh = 100;
var height = window.scrollY;
var sch = bh + height;
if (height <= 19) {
$webscroll.style.height = '200px';
} else {
$webscroll.style.height = sch + 'px';
}
});
body {
background-color: #000;
height: 1200px;
}
.bottom_left_spider {
position: absolute;
width: 180px;
height: 200px;
left: 0;
top: 0;
z-index: 998
}
.webscroll {
height: 200px;
width: 1px;
border-right: 2px solid #2e2e2e;
position: absolute;
top: 0;
left: 101px;
z-index: 9999;
transition: height 50ms ease-in-out
}
.spidy {
position: absolute;
bottom: -51px;
left: -29px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="bottom_left_spider">
<img src="https://s17.postimg.org/cc243pkrz/spiderweb.png">
<!-- spider web lines -->
<div class="webscroll">
<!-- spider line vertical -->
<img src="https://s21.postimg.org/tbdww9hzr/spidy.png" class="spidy">
<!-- spider image -->
</div>
</div>
http://caniuse.com/#feat=css-transitions
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions
By looking your example, I think you want the spider to start moving after the scroll have ended, so if that's the case, check this: jQuery scroll() detect when user stops scrolling
Try moving the spider outside of its parent div and giving it a fixed position in the bottom corner; it should stay there regardless of scrolling. (You may need to tweak the behavior of the scroll/web line to look right.)
Same as hector22x. Increasing the duration to 100ms and add a 100ms delay to make it move smoothly.
var $webscroll = $('.webscroll')[0];
$(window).scroll(function() {
var bh = 100;
var height = window.scrollY;
var sch = bh + height;
if (height <= 19) {
$webscroll.style.height = '200px';
} else {
$webscroll.style.height = sch + 'px';
}
});
body {
background-color: #000;
height: 1200px;
}
.bottom_left_spider {
position: absolute;
width: 180px;
height: 200px;
left: 0;
top: 0;
z-index: 998
}
.webscroll {
height: 200px;
width: 1px;
border-right: 2px solid #2e2e2e;
position: absolute;
top: 0;
left: 101px;
z-index: 9999;
transition: height 100ms ease-in-out 100ms
}
.spidy {
position: absolute;
bottom: -51px;
left: -29px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="bottom_left_spider">
<img src="https://s17.postimg.org/cc243pkrz/spiderweb.png">
<!-- spider web lines -->
<div class="webscroll">
<!-- spider line vertical -->
<img src="https://s21.postimg.org/tbdww9hzr/spidy.png" class="spidy">
<!-- spider image -->
</div>
</div>

JQuery replaced link not working under IE 8-10

I made a popup and I have a problem with IE 8-10 (under IE11 no problem). My code replace an image to linked image. Link is working under Firefox, Chrome and IE11, but not working under other IE versions. This is a popop window by default. Here is my code:
<div id="fadeinboxrevol">
<div id="koppbase">
<p class="kalapacs"><img src="./images/original.png" alt="Click here" /></p>
</div>
</div>
<script type="text/javascript">
var tto = jQuery.noConflict();
function get_path() {
var piclist =['./images/1.png','./images/2.png','./images/3.png','./images/4.png'];
var linklist =['1.html','2.html','3.html','4.html'];
var random = Math.floor(Math.random()*piclist.length);
var picpath = piclist[random];
var linkpath = linklist[random];
var pack = [picpath, linkpath];
return pack;
}
tto(".kalapacs").click(function () {
var mypack = get_path();
var mypic = mypack[0];
var mypath = mypack[1];
var content1 = '<p class="torp"><img class="torve" src="'+mypic+'" alt="Don't wait" /><a class="tortext" href="'+mypath+'"></a></p>';
tto("#koppbase").html(content1);
});
</script>
And here is my CSS:
#fadeinboxrevol {
position: absolute;
width: auto;
left: 301px;
top: 262.5px;
visibility: visible;
border: none;
background-color: ;
padding: 0 px;
z-index: 999;
text-align: left;
}
.kalapacs:hover {
cursor: url(http://cur.cursors-4u.net/others/oth-5/oth438.cur), progress !important;
}
.torp {
position: relative;
}
.tortext {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
display: block;
z-index: 9999;
}
#revolclosebutton {
margin-top: -40px;
right: 20px;
position: absolute;
width: 16px;
z-index: 999;
}
Here is an example in jsfiddle, I use jQuery 1.11 version for better compatibility:
http://jsfiddle.net/mykee/uDCKL/
I tried this line too:
tto("#koppbase").replaceWith(content1);
but not helped. :-(
What's my problem?
The problem is this line of code: var content1 = '<p class="torp"><img class="torve" src="'+mypic+'" alt="Don't wait" /><a class="tortext" href="'+mypath+'"></a></p>';
Change it to: var content1 = '<p class="torp"><a class="tortext" href="'+mypath+'"><img class="torve" src="'+mypic+'" alt="Don't wait" /></a></p>';
When you look at older IE the a is empty after the img tag, so its hard to click it! (Hover down the 2nd image.)
Demo: http://jsfiddle.net/uDCKL/7/
I found a solution! Changed content1 line to this:
var content = '<p class="torp"><a class="tortext" href="'+mypath+'"><img class="torve" src="'+mypic+'" alt="Dont wait" /></a></p>';
And CSS replaced with this and working:
.kalapacs:hover {
cursor: url(http://cur.cursors-4u.net/others/oth-5/oth438.cur), progress !important;
}
.torp {
position: relative;
}
.tortext {
display: block;
}
#revolclosebutton {
margin-top: -40px;
right: 20px;
position: absolute;
width: 16px;
z-index: 99999;
}

Javascript functions not working when integrating two codes together

these javascript functions are working perfectly separate, however when i try to write them in the same page they become inactive. All of the id and class names are correct. I have been fiddleing with it for a while
part 1:
<script>
$("#pic1").click(function(){
var div=$("#pic1");
div.animate({top:'-100px',opacity:'0.4'},"slow");
div.animate({height:'100%',opacity:'1'},"slow");
});
</script>
Part 2:
<script>
var mouseX = 0;
var mouseY = 0;
var offsetWidth = $('.area').width()/2;
var offsetHeight = $('.area').height()/2;
var origBoxTop = parseInt($('.box').css('top'));
var origBoxLeft = parseInt($('.box').css('left'));
$('.area').mousemove( function(e) {
mouseX = offsetWidth - e.pageX;
mouseY = offsetHeight - e.pageY;
$('.box').css('top', origBoxTop + mouseY);
$('.box').css('left', origBoxLeft + mouseX);
$('.info').attr('value', 'x: ' + mouseX + ', y: ' + mouseY);
});
</script> `
I am pretty positive my html and css is correct since both these parts work alone. I just want both to be active on the same page.
By putting them together all i've tried stacking them inside the script tag, i don't know what i don't know so its probably very simple, i'm new to javascript and jQuery. I have just posted the entire code under.
<!DOCTYPE html>
<html>
<head></head>
<script src="jquery2.js"></script>
<style>
body {
background: url("back1.gif");
}
#tree {
position: absolute;
top: 100px;
left: -20px;
}
#tree2 {
position: absolute;
top: -10px;
right: -90px;
}
.box2 {
position: absolute;
height: 200px;
width: 200px;
}
#hi {
cursor: pointer;
top: 600px;
left: 1075px;
position: absolute;
clear: all;
}
#re {
position: absolute;
top: 500px;
left: 500px;
cursor: pointer;
clear all;
}
#st {
position: absolute;
top: 500px;
left: 300px;
cursor: pointer;
clear: all;
}
.info {
position: absolute;
z-index: 99;
}
.box {
position: absolute;
top: 100%;
left: 100%;
margin-top: -50px;
margin-left: -50px;
}
.box:hover {
cursor: pointer;
}
.area {
position: absolute;
width: 100%;
height: 100%;
}
</style>
<body>
<script>
$(document).ready(function(){
$("#re").click(function(){
var div=$("#re");
div.animate({top:'-100px',opacity:'0.4'},"slow");
div.animate({height:'100%',opacity:'1'},"slow");
});
$("#st").click(function(){
var div=$("#st");
div.animate({right:'-100',opacity:'0.4'},"slow");
div.animate({width:'100%',opacity:'1'},"slow");
});
$("#hi").click(function(){
var div=$("#hi");
div.animate({left:'-400px',opacity:'0.4'},"slow");
div.animate({width:'100%',opacity:'1'},"slow");
});
var mouseX = 0;
var mouseY = 0;
var offsetWidth = $('.area').width()/2;
var offsetHeight = $('.area').height()/2;
var origBoxTop = parseInt($('.box').css('top'));
var origBoxLeft = parseInt($('.box').css('left'));
$('.area').mousemove( function(e) {
mouseX = offsetWidth - e.pageX;
mouseY = offsetHeight - e.pageY;
$('.box').css('top', origBoxTop + mouseY);
$('.box').css('left', origBoxLeft + mouseX);
$('.info').attr('value', 'x: ' + mouseX + ', y: ' + mouseY);
});
});
</script>
<div id="wrapper">
<img src="tree.gif" id="tree">
<img src="tree2.gif" id="tree2">
<img src="1.gif" class="box2" id="st">
<img src="3.gif" class="box2" id="hi">
<img src="2.gif" class="box2" id="re">
</div>
<section class="area">
<div class="box" id="what"><img src="what.png"></div>
</section>
</div>
</body>
</html>
I've tried the code in a browser, and I can tell that the script ran. Try adding this in your css, and see if it works better:
.area {
z-index: -1;
}
If it doesn't help, press F12 and F5, and see if there are any errors in the console.
Also you shouldn't put tags between </head> and <body>.

Categories