Overflow:hidden on iOS Safari not working in combination with scrollLeft - javascript

I have a question that was half answered by other posts like this:
Overflow-x:hidden doesn't prevent content from overflowing in mobile browsers
or that:
Does overflow:hidden applied to <body> work on iPhone Safari?
The Question is about that overflow:hidden in iOS Safari and mobile Chrome is not working like I expected it.
overflow:hidden on the body works for Firefox. And if you try the code below that way in Firefox it is exactly how it should work.
So I already see, overflow:hidden is not working on the body for iOS Safari and the mobile Chrome – you have to wrap everything in a div below the body and give that an overflow:hidden. But this way unfortunately is not doing what I want, because it will ignore the JavaScript function scrollLeft.
Here is a quick description of what is supposed to happen:
You open the site. The body or wrapper will be seen half, cause it has a width:180%.
A jQuery code is scrolling the whole thing to {scrollLeft:(right)} where it supposed to stay. (at least on the x-axis)
Clicking the button should move the site to the left where also the site should stay. (on the x-axis / y-axis should be possible to scroll)
Maybe it is a bit complicated; feel free to copy the code if you want to try it yourself.
What I think the problem might be is that overflow:hidden gets overwritten or overwrites the JavaScript function.
Do anyone have an idea how to solve this problem?
Maybe another way to tell the browser to not scroll in the x-axis...
Here is my code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="de">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Scroll test</title>
<style>
#charset "UTF-8";
:root {
--blue: #127296;
}
html {
height: 100%;
font-size: 20px
}
body {
margin: 0px;
overflow-x: hidden;
}
.wrapper {
/* overflow-x: hidden; */
}
.textfeld {
color: var(--blue);
padding: 30px 35px 150vh 35px;
}
.white {
color: white;
}
button {
border: none;
background: none;
font-size: 1em;
padding: 2px 5px 15px 5px;
align-self: center;
}
.eins {
grid-column: 1/ span 6;
}
.zwei {
grid-column: 7 / -1;
background-color: var(--blue);
}
#content {
width: 180%;
grid-template-columns: repeat(12, 1fr);
margin: 0px;
height: auto;
display: grid;
grid-template-columns: repeat(12, 1fr);
}
</style>
</head>
<body>
<div class="wrapper">
<div id="content">
<div class="spalte eins fr">
<div class="textfeld content">
<button type="button" name="button" class="button_2">Click</button>
</div>
</div>
<div class="spalte zwei">
<div class="textfeld content de white">
<button type="button" name="button" class="button">Click</button>
</div>
</div>
</div>
</div>
</body>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script>
$(document).ready(function() {
var left = $(document).outerWidth() - $(window).width();
var right = $(window).width() - $(document).outerWidth();
$('body, html').scrollLeft(left);
$(".button").click(function() {
$('body, html').animate({
scrollLeft: (right)
}, 200);
console.log("click");
});
$(".button_2").click(function() {
$('body, html').animate({
scrollLeft: (left)
}, 200);
});
});
</script>
</html>

Related

How to detecting a click under an overlapping element?

I have two HTML documents, b.html contains c.html using an iframe.
On b.html I need to draw some DIV (in my example id=selector), which partially cover content of c.html visualized in the iframe.
I need to get the ID of a DOM element corresponding to the mouse coordinate under the DIV selector.
At the moment Using document.elementFromPoint() directly in in c.html works partially, as when the mouse it is on DIV selector I cannot identify the underling DOM element in c.html (in this example DIV c).
I would need to know:
Is it possible to select element under another, using document.elementFromPoint() or any other means?
What could be a possible alternatively solution possibly using DOM and native API?
Example here (Please look at the console in Chrome):
http://jsfiddle.net/s94cnckm/5/
----------------------------------------------- b.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>B</title>
<script type="text/javascript">
window.app = {
start: function () {
}
};
</script>
<style>
#selector {
position: absolute;
top: 150px;
left: 150px;
width: 250px;
height: 250px;
-webkit-box-shadow: 0px 0px 0px 5px yellow;
-moz-box-shadow: 0px 0px 0px 5px yellow;
box-shadow: 0px 0px 0px 5px yellow;
}
#iframe {
width: 500px;
height: 500px;
border: none;
}
</style>
</head>
<body onload="app.start();">
<div id="selector">SELECTOR</div>
<iframe id="iframe" src="c.html"></iframe>
</body>
</html>
----------------------------------------------- c.html
<html lang="en">
<head>
<meta charset="utf-8" />
<title>C</title>
<script type="text/javascript">
window.app = {
start: function () {
document.querySelector('body').addEventListener('mousemove', function (event) {
//console.log(event.pageX, event.pageY, event.target.id);
var item = document.elementFromPoint(event.pageX, event.pageY);
console.log(item.id);
}.bind(this));
}
};
</script>
<style>
body {
background-color: lightslategray;
}
#a {
position: absolute;
top: 50px;
left: 50px;
width: 100px;
height: 100px;
background-color: green;
z-index: 2;
}
#b {
position: absolute;
top: 100px;
left: 100px;
width: 100px;
height: 100px;
background-color: #ffd800;
z-index: 1;
}
</style>
</head>
<body onload="app.start();">
<h1>Content</h1>
<div id="a">a</div>
<div id="b">b</div>
</body>
</html>
A possible soltion is the usage of pointer-events.
The CSS property pointer-events allows authors to control under what
circumstances (if any) a particular graphic element can become the
target of mouse events. When this property is unspecified, the same
characteristics of the visiblePainted value apply to SVG content.
When you apply
#selector {
/* ... */
pointer-events: none;
}
All content of #selector and the element itself are no more interactive. Content may not be selected and events like :hover or click are not applicable.
Here is the demo with the above css: http://jsfiddle.net/s94cnckm/6/
Another possible solution, is to capture the document coordinates of a mouse event fired on the masking item(DIV.selector), momentarily hide that masking item, and then ask the document what is under that coordinate position (using document.elementFromPoint(x,y)) before showing the masking item again.
The support for document.elementFromPoint() cover also old version of IE.
Unfortunately pointer-events has limited support for older version of IE.
Here a working example:
http://jsfiddle.net/s94cnckm/14/
document.getElementById('iframe').contentDocument.addEventListener('click', function (event) {
alert(event.target.id);
}.bind(this));
document.getElementById('selector').addEventListener('click', function (event) {
var selector = document.getElementById('selector');
selector.style.display = 'none';
var item = document.getElementById('iframe').contentDocument.elementFromPoint(event.pageX, event.pageY);
selector.style.display = '';
alert(item.id);
}.bind(this));
Regarding the use of pointer-events I link to mention some related article, included a work around for older version of IE.
How to make Internet Explorer emulate pointer-events:none?
https://css-tricks.com/almanac/properties/p/pointer-events/
http://davidwalsh.name/pointer-events
http://robertnyman.com/2010/03/22/css-pointer-events-to-allow-clicks-on-underlying-elements/
This solution was inspired by this article:
http://www.vinylfox.com/forwarding-mouse-events-through-layers/

JQuery hasClass - why does it always return false in this case?

I have a span with a background image that I want to alternate between a background image of a plus and minus on click. I want to add and remove the class 'open' to do this. My span looks like this...
<span class="expand open"></span>
And my JQuery looks like this...
$(function() {
$('.expand').click(function() {
if ($(this).hasClass('open')) {
$(this).removeClass('open');
} else {
$(this).addClass('open');
}
});
});
The behaviour I'm getting is that it will add the class 'open' but then after repeated clicks will not remove it again. Logging to the console has shown that my if statement is always evaluating false.
I've considered using toggleClass but haven't done so because once this is working I intend to use the same if statement to show / hide content blocks.
http://jsfiddle.net/Vz7YL/
EDIT
Since people are focussing on my css, I'll provide that too. (SASS/SCSS):
.expand {
background: url(/images/plus-minus-orange.gif) top center no-repeat;
display: block;
height: 21px;
margin: 0 auto;
width: 22px;
&.open {
background: url(/images/plus-minus-orange.gif) bottom center no-repeat;
}
}
Can I also add that the span IS displaying correctly and IS clickable, and I cannot recreate the problem with a simplified version of the code.
Your fiddle works fine for me. Just add some text in span So you can actually click on span.
<span class="expand open">Some Text Here</span>
Fiddile Works fine. You need to add some text in span.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="Scripts/jquery.min.js" type="text/javascript"></script>
<style type="text/css">
.expand {
background: url('/Images/Icons/greenplus.png') top center no-repeat;
display: block;
height: 21px;
margin: 0 auto;
width: 22px;
}
.open {
background: url('/Images/Icons/redminus.png') bottom center no-repeat;
}
</style>
<script type="text/javascript">
$(function () {
$('.expand').click(function () {
if ($(this).hasClass('open')) {
$(this).removeClass('open');
} else {
$(this).addClass('open');
}
});
});
</script>
</head>
<body>
<span class="expand open"></span>
</body>
</html>
This works for me.
Fiddle works fine. So the issue is the click don't work for the background image. Try to add some width and height for the span element and try.
Like this
.expand {
background: url(http://upload.wikimedia.org/wikipedia/commons/a/a6/Plus_orange.gif) top center no-repeat;
display: block;
height: 21px;
margin: 0 auto;
width: 22px;
}
.open {
background: url(http://www.ilsc.com/course-resource/images/sign-minus-orange.gif) bottom center no-repeat;
}
}
http://jsfiddle.net/Vz7YL/4/
While none of the answers here provide me with a solution, one of the comments on my question did. Substituting the class 'open' for and alternative such as 'expanded' resolved the problem. Thanks #Doorknob

scrollTop offset() not animating/working correctly with divs inside of container

Im trying to use simple jquery offset() and animate to make my div scroll to the desired div when the user clicks on a link.
Basically, when the user clicks blog it will go to test1
user clicks Contact it will move to test2
user clicks Work it will move to test3.
I implemented some code I had used in a previous project (it had worked before) but the scrolls are not working correctly this time and I really don't know the reason why. I tried searching for a solution but web development has been an on and off thing for me and I don't understand some of the explanations :/ Any help would be appreciated.
EditOne: had to update the html, still not working.
The HTML:
<html>
<head>
<meta name="description" content="" />
<meta name="keywords" content="" />
<meta name="author" content="" />
<script type="text/javascript" src="jquery.js"></script>
<link rel="stylesheet" type="text/css" href="index.css" />
<link rel="stylesheet" type="text/css" href="reset.css" />
<title>Bryan the Lion</title>
</head>
<body>
<script type="text/javascript">
function go_One(){
var divPosition = $('.test1').offset();
$('#main_wrapper #main').animate({scrollTop: divPosition.top}, "fast");
}
</script>
<script type="text/javascript">
function go_Two(){
var divPosition = $('.test2').offset();
$('#main_wrapper #main').animate({scrollTop: divPosition.top}, "fast");
}
</script>
<script type="text/javascript">
function go_Three(){
var divPosition = $('.test3').offset();
$('#main_wrapper #main').animate({scrollTop: divPosition.top}, "fast");
}
</script>
<div id = "header">
<h1>Title</h1>
</div>
<div id = "main_box">
<div id = "designHex">
</div>
<div id ="nav">
<ul>
<li id = "Blog"></li>
<li id = "Contact"></li>
<li id = "Work"></li>
</ul>
</div>
<div id = "main_wrapper">
<div id ="main">
<div class = "test1">
<p>some div</p>
</div>
<div class = "test2" >
<p>some div2</p>
</div>
<div class = "test3" >
<p>some div3</p>
</div>
</div>
</div>
</div>
</body>
</html>
The CSS: Of most importance here I think are main_wrapper, main, and test(1)(2)(3)
body{
height: 100% ;
background: url(images/gplaypattern.png);
}
#font-face {
font-family: "AlexBrush";
src: url(fonts/AlexBrush-Regular.ttf) format("truetype");
}
#header{
height: 100px ;
margin-bottom: 20px ;
}
#main_box{
margin: 0 auto ;
width: 80% ;
height: 52 0px ;
}
#main_wrapper{
margin-left: 45% ;
width: 67%;
overflow: hidden;
}
#main_wrapper #main{
width: 103%;
height: 500px ;
overflow-y:scroll;
}
.test1{
height: 500px ;
background: yellow;
}
.test2{
height: 500px ;
background: blue;
}
.test3{
height: 500px ;
background: gray;
}
#nav{
float: left;
width: 275px ;
height: 450px ;
margin-left: 3% ;
}
#nav ul li a{
display: block;
width: 100% ;
height: 150px ;
}
#nav ul li a:hover{
cursor: pointer;
}
#nav #Blog{
background: url(images/Blog.png);
}
#nav #Blog:hover{
background: url(images/Blog_hover.png);
}
#nav #Contact{
background: url(images/Contact.png);
}
#nav #Contact:hover{
background: url(images/Contact_hover.png);
}
#nav #Work{
background: url(images/Work.png);
}
#nav #Work:hover{
background: url(images/Work_hover.png);
}
#designHex{
background: rgba(255,255,255, 0.3);
height: 150px ;
width: 150px ;
position: absolute;
top: 50px ;
left: 5% ;
}
You need to take into account the scrollTop AND offset of the parent div:
JSFiddle: http://jsfiddle.net/TrueBlueAussie/Uafxz/2/
function scrollTo(selector) {
var offset = $(selector).offset();
var $main = $('#main');
$main.animate({
scrollTop: offset.top - ($main.offset().top - $main.scrollTop())
}, "fast");
}
I changed your code to use a single function (passing the target selector). I removed the second id selector as ids are unique and id lookup is the fastest type of lookup anyway (no point slowing it down with a second search).
Note: I had to hide your designHex element for the JSFiddle as it overlapped the first link.
You actually don't target the good element to animate scrollTop :
$('html,body').animate({scrollTop: divPosition.top}, "fast"); // instead of #main_wrapper #main
And as said in comment, your code contains a lot of errors or non-standard notation. For example, you use 3 script tag and 3 function that do the same job. That could be done with only one.

How to fix this jquery function to work in IE?

I am relatively new with Javascript but managed to somehow get this code to work on chrome, firefox, safari but it doesn't properly on IE. First look at this code and then after that I will explain what seems to be not working:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="http://www.domain.com/test/wtf.css" />
<script type="text/javascript" src="/js/jquery-1.7.2.min.js"></script>
<script type="text/javascript">
$(function () {
var transition = 'slow';
var target1 = $('#flash1');
var target2 = $('#flash2');
var target3 = $('#box2');
var target4 = $('#tble');
var target5 = $('.links');
var target6 = $('#wording');
target1.delay(1000).fadeIn();
target2.delay(2000).fadeIn();
target3.delay(3000).fadeIn();
target4.delay(4000).fadeIn();
target5.delay(5000).fadeIn();
target6.delay(6000).fadeIn();
});
</script>
<script type="text/javascript">
$(document).ready(function () {
$("#this_is_button").click(function () {
$("#box2").hide();
$("#tble").hide();
$(".links").hide();
$("#second_pls").show();
$("#box2").css("background", "black");
})
});
</script>
<script type="text/javascript">
$(document).ready(function () {
$("#what_close").click(function () {
$("#second_pls").hide();
$("#tble").show();
$(".snap").show();
$(".links").show();
$("#box").css({
backgroundImage: "url('/test/img.jpg')",
backgroundSize: "800px"});
});
});
</script>
</head>
<body>
<div id="box">
<div id="box2" style="display:none"></div>
<div id="wording" style="display:none">
<label id="flash1" style="display:none">Hello</label>
<label id="flash2" style="display:none">World</label>
</div>
<div id="tble" style="display:none">This is a table</div>
<div id="second_pls" style="display:none">Hello Hello Hello, is this working? come on already?!!
<input type="button" id="what_close" value="Close">
</div>
<div class="links" style="display:none">
<input type="button" id="this_is_button" value="Sample">
</div>
</div>
</body>
</html>
CSS:
#box {
background-color: #000000;
height: 350px;
margin-left: auto;
margin-right: auto;
width: 800px;
}
#box2 {
background-image: url("/test/img.jpg");
background-size: 800px;
height: 550px;
margin-left: auto;
margin-right: auto;
width: 800px;
position: absolute;
}
#wording {
position: relative;
color: #999999;
font-size: 15px;
letter-spacing: 5px;
margin-left: 20px;
padding-top: 30px;
}
#tble {
margin-top: 180px;
position: absolute;
}
#second_pls {
margin-left: 10px;
margin-top: 310px;
position: absolute;
}
.links {
margin-left: 10px;
margin-top: 310px;
position: absolute;
}
So what is the part that doesn't seem to function when the page is rendered in IE? It seems that the fadeIn, fadeOut, hide and show parts are not rendering in IE except #flash1, and #flash2 work, the rest of the fade in, fade out don't work. I am ripping my hair out not understanding why those two would work but not the rest.
I used BrowserStack and it seems that on Windows XP using IE 8 it renders properly with the exception of properly rendering the background image. But on Windows 7 using IE 8, it works the same way as it does on Windows XP but when using IE 9 it gives me the current issue.
What am I doing wrong?
It seems the problem arise from incorrect syntax:
$("#box").css({
backgroundImage: "url('/test/img.jpg')",
backgroundSize: "800px", //<-- extra comma
});
http://jsfiddle.net/bfcZd/3/
vs.
http://jsfiddle.net/bfcZd/4/
You should look at the CSS declarations for the two divs that are working. I suspect they may be position:relative or have some other property that is causing them to render differently (properly) while the other ones fail. Could you provide the CSS that you have set for the divs in your example. It will help us troubleshoot a little better, but without seeing it, this is my hunch.
add this meta tag inside your <head></head>
<meta http-equiv="X-UA-Compatible" content="IE=8">
should work then.
i have it here in this jsfiddle: http://jsfiddle.net/Morlock0821/XtyWC/

Flexible/responsive boxes weird browser behavior in jQuery

Safari: Works
Firefox: Weird floating issue on initial page load, works after browser resize
Chrome: End boxes jump around quickly when making window smaller
(have not tested other browsers)
Video displaying browser issues: http://tinypic.com/r/2gxo8w3/6
Full script:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
</head>
<style>
.box {
height: 250px;
background-color: #999;
float: left;
margin-right: 10px;
margin-top: 10px;
}
#boxes {
width: 100%;
overflow: auto;
}
.end-box {
margin-right: 0;
}
.top-box {
margin-top: 0;
}
</style>
<body>
<div id='boxes'>
<div class='box'>1</div>
<div class='box'>2</div>
<div class='box'>3</div>
<div class='box'>4</div>
<div class='box'>5</div>
<div class='box'>6</div>
<div class='box'>7</div>
<div class='box'>8</div>
</div>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
columns = Math.floor($('#boxes').width()/225); //min box/column size (before spacing)
var spacing = ((columns - 1) * 10/$('#boxes').width())*100; //10px spacing between boxes
$('.box').width(100/columns-spacing/columns+'%');
$('.box:nth-child('+columns+'n+0)').addClass('end-box');//removes margins
$('.box:nth-child(-n'+columns+')').addClass('top-box');
$(window).resize(function() {
columnsCheck = Math.floor($('#boxes').width()/225);
if(columns != columnsCheck) {
$('.end-box').removeClass('end-box');
$('.top-box').removeClass('top-box');
$('.box:nth-child('+columnsCheck+'n+0)').addClass('end-box');
}
columns = columnsCheck;
var spacing = ((columns - 1) * 10/$('#boxes').width())*100;
$('.box').width(100/columns-spacing/columns+'%');
$('.box:nth-child('+columns+'n+0)').addClass('end-box');
$('.box:nth-child(-n'+columns+')').addClass('top-box');
});
</script>
</body>
</html>
How can I solve this issue (while maintaining 10px margins). I am also open to alternative methods of creating this effects via JavaScript/jQuery (trying to avoid pure CSS3).

Categories