Mixing javascript with node.js and pug - node.js

I'm attempting to display multiple tabs using code from here http://www.w3schools.com/howto/howto_js_tabs.asp
Here is my code :
index.pug :
html
head
<script>
function openCity(evt, cityName) {
// Declare all variables
var i, tabcontent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
// Show the current tab, and add an "active" class to the link that opened the tab
document.getElementById(cityName).style.display = "block";
evt.currentTarget.className += " active";
}
</script>
title= title
body
h3= message
<link rel="stylesheet" type="text/css" href="style.css">
<ul class="tab">
<li>London</li>
<li>Paris</li>
<li>Tokyo</li>
</ul>
<div id="London" class="tabcontent">
<h3>London</h3>
<p>London is the capital city of England.</p>
</div>
<div id="Paris" class="tabcontent">
<h3>Paris</h3>
<p>Paris is the capital of France.</p>
</div>
<div id="Tokyo" class="tabcontent">
<h3>Tokyo</h3>
<p>Tokyo is the capital of Japan.</p>
</div>
style.css :
/* Style the list */
ul.tab {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
border: 1px solid #ccc;
background-color: #f1f1f1;
}
/* Float the list items side by side */
ul.tab li {float: left;}
/* Style the links inside the list items */
ul.tab li a {
display: inline-block;
color: black;
text-align: center;
padding: 14px 16px;
text-decoration: none;
transition: 0.3s;
font-size: 17px;
}
/* Change background color of links on hover */
ul.tab li a:hover {background-color: #ddd;}
/* Create an active/current tablink class */
ul.tab li a:focus, .active {background-color: #ccc;}
/* Style the tab content */
.tabcontent {
display: none;
padding: 6px 12px;
border: 1px solid #ccc;
border-top: none;
}
I receive this error :
9| // Get all elements with class="tabcontent" and hide them
10| tabcontent = document.getElementsByClassName("tabcontent");
> 11| for (i = 0; i < tabcontent.length; i++) {
---------------^
12| tabcontent[i].style.display = "none";
13| }
14|
malformed each
at makeError (/Users/node_modules/pug/node_modules/pug-lexer/node_modules/pug-error/index.js:32:13)
at Lexer.error (/Users/node_modules/pug/node_modules/pug-lexer/index.js:58:15)
at Lexer.each (/Users/node_modules/pug/node_modules/pug-lexer/index.js:911:12)
at Lexer.callLexerFunction (/Users/node_modules/pug/node_modules/pug-lexer/index.js:1315:23)
at Lexer.advance (/Users/node_modules/pug/node_modules/pug-lexer/index.js:1343:15)
at Lexer.callLexerFunction (/Users/node_modules/pug/node_modules/pug-lexer/index.js:1315:23)
at Lexer.getTokens (/Users/node_modules/pug/node_modules/pug-lexer/index.js:1371:12)
at lex (/Users/node_modules/pug/node_modules/pug-lexer/index.js:12:42)
at Object.load.string.lex (/Users/node_modules/pug/lib/index.js:93:27)
at Function.loadString [as string] (/Users/node_modules/pug/node_modules/pug-load/index.js:44:24)
How to mix javascript with pug ?

There is a small example with inline javascript on the pug npm page (https://www.npmjs.com/package/pug). Basically its this:
html
head
script (type="text/javascript").
/* your javascript here */
title= title
Also I'm not sure why you're using partial pug syntax and partial HTML. For example you have this:
<link rel="stylesheet" type="text/css" href="style.css">
When it should be this:
link(rel="stylesheet" type="text/css" href="style.css")
As an alternative (for the javascript) you can use the include directive, as explained here: https://pugjs.org/language/includes.html, or you could put the javascript in an external file (like you did with your css) and simply do this:
script(src='app.js')

First thing to try ( whitout more details )
if you're using strict mode change this:
for (i = 0; i < tabcontent.length; i++)
to this
for (var i = 0; i < tabcontent.length; i++)
If it works it teach you a lesson: Declare everything, everywhere. Always.
If not, we need more details

Related

Position dropdown under button in svelte

I am writing a dropdown component in svelte with tailwind css and i cannot get the dropdown menu to be under the button/anchored to it meaning it always appears under it.
I have tried using relative and other positional tailwind properties but i haven't had any succes.
I am also new to tailwind and mainly have backend experience so this is a bit hard for me if anyone can help or point me towards an example then please do so!
Dropdown example in Svelte
https://svelte.dev/repl/05d770c4baa748b2b0973afec4d59051?version=3.55.1
<script>
// Button binding
let button;
// State
let open = false;
let top = 0, left = 0;
// React to opening
$: if (open) {
setDropdownPosition();
}
function setDropdownPosition() {
const rect = button.getBoundingClientRect();
top = rect.bottom;
left = rect.left;
}
</script>
<button bind:this={button} on:click={() => open = !open}>{!open ? 'Open' : 'Close'} Dropdown!</button>
{#if open}
<ul class="dropdown" style:top={top} style:left={left}>
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
</ul>
{/if}
<style>
/* List Reset */
ul li {
padding: 0;
text-indent: 0;
list-style-type: none;
}
.dropdown {
position: absolute;
display: grid;
gap: 0.25rem;
margin: 0.5rem 0 0 0.5rem;
padding: 0;
}
</style>

animation visible in live preview brackets but not in ANY browser

i made a loading bar for my website. On the live preview with brackets, when I scroll down to my bar, the animation become visible. When I open my html page with a browser (chrome or edge), The loading bar animation does not appear... Although I think I used the right prefixes. Below you can see my code:
**CSS**
.laden100 {
animation-name: laden100;
-webkit-animation-name: laden100;
animation-duration: 4s;
-webkit-animation-duration: 4s;
visibility: visible;
width: 100%;
height: 20px;
background-image: linear-gradient(to bottom, #308355, #308355, #308355, #00cc66);
background-image: -webkit-linear-gradient(to bottom, #308355, #308355, #308355, #00cc66);
box-shadow: 5px 5px 5px grey;
border-radius: 5px 5px 5px 5px;
position: relative;
margin-top: 20px;
margin-left: 20px;
margin-right: 20px;
}
#keyframes laden100 {
0% {
opacity: 0;
width: 0%;
}
100% {
opacity: 1;
width: 100%;
}
}
#-webkit-keyframes laden100 {
0% {
opacity: 0;
width: 0%;
}
100% {
opacity: 1;
width: 50%;
}
}
**HTML**
<div class="container wit mt-5">
<h1 id="skills">Skills</h1>
<p style="color:#308355">Below you can see my skills I have. This learning process is still ongoing. I hope to achieve at least 80% for each coding language.</p>
<br>
<div class="container">
<div class="row">
<div class="vak">HTML</div>
<div class="laadbalk100"></div>
<div class="score100">%</div>
</div>
<br>
</div>
</div>
**JAVASCRIPT**
<!----------------------- only load the load bar on scroll-------------->
<script>
$(document).ready(function() {
// Add smooth scrolling to all links in navbar + footer link
$(".navbar a, footer a[href='#myPage']").on('click', function(event) {
// Make sure this.hash has a value before overriding default behavior
if (this.hash !== "") {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (900) specifies the number of milliseconds it takes to scroll to the specified area
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 900, function() {
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
});
} // End if
});
$(window).scroll(function() {
$(".laadbalk100").each(function() {
var pos = $(this).offset().top;
var winTop = $(window).scrollTop();
if (pos < winTop + 600) {
$(this).addClass("laden100");
}
});
});
})
</script>
I used prefixes because I think it has something to do with browser support. According to me, Brackets uses plugins to add the right prefixes.
OK sry Guys,
I found the answer to my own question... :D.
Because browsers have different screen resolutions, I had to increase wintop +600 to wintop +1000. See the correction below:
$(window).scroll(function() {
$(".laadbalk100").each(function() {
var pos = $(this).offset().top;
var winTop = $(window).scrollTop();
if (pos < winTop + 1000) {
$(this).addClass("laden100");
}
});
});

Vue conditional * css style loader

My vue app is shared between web page and electron app on touch device. On this touch device I want to include extra style. So in my App.vue there is:
<script>
var is_electron = process.hasOwnProperty("versions") && process.versions.hasOwnProperty("electron")
var is_embedded = is_electron && require("electron").remote.process.argv.includes("-e")
</script>
<style>
* {
transition-property: none !important;
transform: none !important;
animation: none !important;
cursor: none !important;
}
</style>
How can I conditionally include this * style ?
If the platform-specific styling is minimal, I would suggest to use some helper classes. You can even style subcomponents by scoping the css within one of these selectors.
<template>
<main :class="classes">
<!-- Hello world -->
</main>
</template>
<script>
var isElectron = process.hasOwnProperty("versions") && process.versions.hasOwnProperty("electron")
var isEmbedded = isElectron && require("electron").remote.process.argv.includes("-e")
export defualt {
name: 'App',
computed: {
classes () {
return {
electron: isElectron,
embedded: isEmbedded
}
}
}
}
</script>
<style>
.electron:not(.embedded) * {
border: 1px solid blue;
}
.embedded:not(.electron) * {
/* What kind of sorcery is this? */
}
.electron.embedded * {
border: 1px dotted red;
}
main:not(.electron):not(.embedded) * {
border: 1px dashed green;
}
</style>

Adding this infowindow navigational link code to my KML search code

I'm hoping to combine the following two codes to create a map that not only searches with a layer of KMZ on top, but also shows navigation options in the infowindow. An example of the two maps side by side can be viewed here. But I want to combine the two maps into one. I've included my attempt at this at the bottom of this post - but it doesn't work.
Firstly, I've adapted this code for searching a map with my kmz (or kml) layered onto it and it works just fine ...
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map-canvas {
height: 100%;
}
.controls {
margin-top: 10px;
border: 1px solid transparent;
border-radius: 2px 0 0 2px;
box-sizing: border-box;
-moz-box-sizing: border-box;
height: 32px;
outline: none;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}
#pac-input {
background-color: #fff;
font-family: Roboto;
font-size: 15px;
font-weight: 300;
margin-left: 12px;
padding: 0 11px 0 13px;
text-overflow: ellipsis;
width: 300px;
}
#pac-input:focus {
border-color: #4d90fe;
}
.pac-container {
font-family: Roboto;
}
#type-selector {
color: #fff;
background-color: #4d90fe;
padding: 5px 11px 0px 11px;
}
#type-selector label {
font-family: Roboto;
font-size: 13px;
font-weight: 300;
}
</style>
<title>Places Searchbox</title>
<style>
#target {
width: 345px;
}
</style>
</head>
<body>
<input id="pac-input" class="controls" type="text" placeholder="Search Box">
<div id="map-canvas"></div>
<script>
// This example adds a search box to a map, using the Google Place Autocomplete
// feature. People can enter geographical searches. The search box will return a
// pick list containing a mix of places and predicted search terms.
function initAutocomplete() {
var map = new google.maps.Map(document.getElementById('map-canvas'), {
center: {lat:53.6292604,lng:-2.9380916},
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var mapLayer = new google.maps.KmlLayer({
url: "https://www.google.com/maps/d/kml?mid=zQWA66D2AmlU.kGvUUZ4wvdYo",
suppressInfoWindows:false,
preserveViewport:true });
mapLayer.setMap(map);
// Create the search box and link it to the UI element.
var input = document.getElementById('pac-input');
var searchBox = new google.maps.places.SearchBox(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
// Bias the SearchBox results towards current map's viewport.
map.addListener('bounds_changed', function() {
searchBox.setBounds(map.getBounds());
});
var markers = [];
// [START region_getplaces] this was the first to cause problems
// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener('places_changed', function() {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
// Clear out the old markers.
markers.forEach(function(marker) {
marker.setMap(null);
});
markers = [];
// For each place, get the icon, name and location.
var bounds = new google.maps.LatLngBounds();
places.forEach(function(place) {
var icon = {
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(25, 25)
};
// Create a marker for each place.
markers.push(new google.maps.Marker({
map: map,
icon: icon,
title: place.name,
position: place.geometry.location
}));
if (place.geometry.viewport) {
// Only geocodes have viewport.
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
});
map.fitBounds(bounds);
});
// [END region_getplaces]
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=[MY-KEY]&libraries=places&callback=initAutocomplete"
async defer></script>
</body>
</html>
This second code works great with adding a direction link to the info window so you can drive there using your smartphone ...
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8"><title>Embedded Map</title>
<style>
html, body, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3"></script>
<script>
var map;
var infowindow;
function initialize() {
var mapOptions = {center: {lat:53.6292604,lng:-2.9380916},
zoom: 5}
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var mapLayer = new google.maps.KmlLayer({
url: "https://www.google.com/maps/d/kml?mid=zQWA66D2AmlU.kGvUUZ4wvdYo",
suppressInfoWindows:true,
preserveViewport:true });
mapLayer.setMap(map);
google.maps.event.addListener(mapLayer, 'click', function(kmlEvent) {
var text = kmlEvent.featureData.infoWindowHtml;
text = text + '<br>Navigate to Here';
if (infowindow) { infowindow.setContent(text);
} else {
infowindow = new google.maps.InfoWindow({content: text});
}
infowindow.setOptions({position:kmlEvent.latLng, pixelOffset:kmlEvent.pixelOffset});
infowindow.open(map);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script></head>
<body>
<div id="map-canvas"></div>
</body></html>
Putting the two scripts together here, it looks something like this, although this doesn't work. Any answers gratefully received about whats going wrong here please ...
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map-canvas {
height: 100%;
}
.controls {
margin-top: 10px;
border: 1px solid transparent;
border-radius: 2px 0 0 2px;
box-sizing: border-box;
-moz-box-sizing: border-box;
height: 32px;
outline: none;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}
#pac-input {
background-color: #fff;
font-family: Roboto;
font-size: 15px;
font-weight: 300;
margin-left: 12px;
padding: 0 11px 0 13px;
text-overflow: ellipsis;
width: 300px;
}
#pac-input:focus {
border-color: #4d90fe;
}
.pac-container {
font-family: Roboto;
}
#type-selector {
color: #fff;
background-color: #4d90fe;
padding: 5px 11px 0px 11px;
}
#type-selector label {
font-family: Roboto;
font-size: 13px;
font-weight: 300;
}
</style>
<title>Places Searchbox</title>
<style>
#target {
width: 345px;
}
</style>
</head>
<body>
<input id="pac-input" class="controls" type="text" placeholder="Search Box">
<div id="map-canvas"></div>
<script>
// This example adds a search box to a map, using the Google Place Autocomplete
// feature. People can enter geographical searches. The search box will return a
// pick list containing a mix of places and predicted search terms.
function initAutocomplete() {
var map = new google.maps.Map(document.getElementById('map-canvas'), {
center: {lat:53.6292604,lng:-2.9380916},
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var mapLayer = new google.maps.KmlLayer({
url: "https://www.google.com/maps/d/kml?mid=zQWA66D2AmlU.kGvUUZ4wvdYo",
suppressInfoWindows:false,
preserveViewport:true });
mapLayer.setMap(map);
// Create the search box and link it to the UI element.
var input = document.getElementById('pac-input');
var searchBox = new google.maps.places.SearchBox(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
// Bias the SearchBox results towards current map's viewport.
map.addListener('bounds_changed', function() {
searchBox.setBounds(map.getBounds());
});
var markers = [];
// [START region_getplaces] this was the first to cause problems
// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener('places_changed', function() {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
// Clear out the old markers.
markers.forEach(function(marker) {
marker.setMap(null);
});
markers = [];
// For each place, get the icon, name and location.
var bounds = new google.maps.LatLngBounds();
places.forEach(function(place) {
var icon = {
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(25, 25)
};
// Create a marker for each place.
markers.push(new google.maps.Marker({
map: map,
icon: icon,
title: place.name,
position: place.geometry.location
}));
if (place.geometry.viewport) {
// Only geocodes have viewport.
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
});
map.fitBounds(bounds);
});
// [END region_getplaces]
var map;
var infowindow;
mapLayer.setMap(map);
google.maps.event.addListener(mapLayer, 'click', function(kmlEvent) {
var text = kmlEvent.featureData.infoWindowHtml;
text = text + '<br>Navigate to Here';
if (infowindow) { infowindow.setContent(text);
} else {
infowindow = new google.maps.InfoWindow({content: text});
}
infowindow.setOptions({position:kmlEvent.latLng, pixelOffset:kmlEvent.pixelOffset});
infowindow.open(map);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=[MY-KEY]&libraries=places&callback=initAutocomplete"
async defer></script>
</body>
</html>
remove the final } in the javascript, it generates a syntax error: Uncaught SyntaxError: Unexpected token }.
change suppressInfoWindows: false to suppressInfoWindows: true (removes the extraneous second copy of the infowindow).
code snippet:
// This example adds a search box to a map, using the Google Place Autocomplete
// feature. People can enter geographical searches. The search box will return a
// pick list containing a mix of places and predicted search terms.
function initAutocomplete() {
var map = new google.maps.Map(document.getElementById('map-canvas'), {
center: {
lat: 53.6292604,
lng: -2.9380916
},
zoom: 5,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var mapLayer = new google.maps.KmlLayer({
url: "https://www.google.com/maps/d/kml?mid=zQWA66D2AmlU.kGvUUZ4wvdYo",
suppressInfoWindows: true,
preserveViewport: true
});
mapLayer.setMap(map);
// Create the search box and link it to the UI element.
var input = document.getElementById('pac-input');
var searchBox = new google.maps.places.SearchBox(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
// Bias the SearchBox results towards current map's viewport.
map.addListener('bounds_changed', function() {
searchBox.setBounds(map.getBounds());
});
var markers = [];
// [START region_getplaces] this was the first to cause problems
// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener('places_changed', function() {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
// Clear out the old markers.
markers.forEach(function(marker) {
marker.setMap(null);
});
markers = [];
// For each place, get the icon, name and location.
var bounds = new google.maps.LatLngBounds();
places.forEach(function(place) {
var icon = {
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(25, 25)
};
// Create a marker for each place.
markers.push(new google.maps.Marker({
map: map,
icon: icon,
title: place.name,
position: place.geometry.location
}));
if (place.geometry.viewport) {
// Only geocodes have viewport.
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
});
map.fitBounds(bounds);
});
// [END region_getplaces]
var map;
var infowindow;
mapLayer.setMap(map);
google.maps.event.addListener(mapLayer, 'click', function(kmlEvent) {
var text = kmlEvent.featureData.infoWindowHtml;
text = text + '<br>Navigate to Here';
if (infowindow && infowindow.setContent) {
infowindow.setContent(text);
} else {
infowindow = new google.maps.InfoWindow({
content: text
});
}
infowindow.setOptions({
position: kmlEvent.latLng,
pixelOffset: kmlEvent.pixelOffset
});
infowindow.open(map);
});
}
google.maps.event.addDomListener(window, 'load', initAutocomplete);
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#map-canvas {
height: 100%;
}
.controls {
margin-top: 10px;
border: 1px solid transparent;
border-radius: 2px 0 0 2px;
box-sizing: border-box;
-moz-box-sizing: border-box;
height: 32px;
outline: none;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}
#pac-input {
background-color: #fff;
font-family: Roboto;
font-size: 15px;
font-weight: 300;
margin-left: 12px;
padding: 0 11px 0 13px;
text-overflow: ellipsis;
width: 300px;
}
#pac-input:focus {
border-color: #4d90fe;
}
.pac-container {
font-family: Roboto;
}
#type-selector {
color: #fff;
background-color: #4d90fe;
padding: 5px 11px 0px 11px;
}
#type-selector label {
font-family: Roboto;
font-size: 13px;
font-weight: 300;
}
</style> <title>Places Searchbox</title> <style> #target {
width: 345px;
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
<input id="pac-input" class="controls" type="text" placeholder="Search Box">
<div id="map-canvas"></div>

How can I create a real "reveal page" slide effect

I've been searching for a way to do this effect: http://www.discovershadow.com/
Especially the iPhone reveal part at the bottom where the iPhone stays but the content inside changes at the same time as the background.
Can this be achieved with only css or is it something much more complicated?
This is the way that I found to do this... no one seemed interested in the question but I hope you like the answer:
<html>
<head>
<style>
html, body {
min-height: 100%;
margin: 0;
padding: 0;
}
#container {
height: 100%;
width: 100%;
overflow-y: scroll;
position: fixed;
}
.items {
width: 100%;
height: 102%;
background-attachment: fixed;
background-position: 50%;
background-repeat: no-repeat;
position: relative;
}
#box1 {
background-image: url(yourimage1.png);
background-color: #03F;
}
#box2 {
background-image: url(yourimage2.png);
background-color: #609;
}
#box3 {
background-image: url(yourimage3.png);
background-color: #3C0;
}
</style>
</head>
<body>
<div id="container">
<div class="items" id="box1"></div>
<div class="items" id="box2"></div>
<div class="items" id="box3"></div>
</div>
</body>
</html>
Yes can achieve that... You have not added any code or not even tried i think. Here is simple code for you to get you started.
.a
{
background-image : url('http://hdwallpaper2013.com/wp-content/uploads/2013/02/Beautiful-Nature-Images-HD-Wallpaper.jpg');
height: 200px;
width: 100%;
position: fixed;
}
p
{
color : #000;
font-size: 72px;
position: relative;
z-index: 999;
}
fiddle
This effect does require CSS + Javascript, there is no way to do it effectively without using these technologies. You could have the iPhone centred on screen and the rest of the screen move around it but it wouldn't create such as nice effect as seen on the website.
I would personally recommend looking at the source of the target website and investigate yourself how it was achieved, never hurts to have a sneek peek at source from other websites.
Looking at that sites script.js page they handle scrolling with
// handle scrolling
$window.scroll(function() {
handleScroll();
});
Which does this. You will need to look at the full code to work out exactly how its done.
// handle scroll
function handleScroll() {
scrolledWin = getPageScroll();
$body.addClass('scrolling');
// show logo
if((scrolledWin * 1.5) > winH) {
$body.addClass('content');
}
// show navigation
if(scrolledWin > 50) {
$body.addClass('scrolled');
}
// app img animation
if(topOff >= scrolledWin) {
$appImg.removeClass('sticky');
} else {
$appImg.addClass('sticky');
}
if(topOff2 >= scrolledWin) {
$appImg2.removeClass('sticky');
} else {
$appImg2.addClass('sticky');
}
// fix navigation issue on top scroll
if ((scrolledWin > -(winH - (winH * (f1 *0.8)))) && $('#hook2').hasClass('inViewport')) {
$nav.attr("class", "").addClass('a2');
} else if ($('#hook2').hasClass('inViewport')) {
$nav.attr("class", "").addClass('a1');
}
//fix navigation issue between how it works and next section
if ($s9.hasClass('inViewport')) {
if ($('#hook5').hasClass('inViewport')) {
$nav.attr("class", "").addClass('a5');
} else {
$nav.attr("class", "").addClass('a4');
}
}
//fix navigation issue between Experts and next section
if ($sExperts.hasClass('inViewport')) {
if ($('#hook6').hasClass('inViewport')) {
$nav.attr("class", "").addClass('a6');
} else {
$nav.attr("class", "").addClass('a5');
}
}
}
Ref: http://www.discovershadow.com/js/script.js?v=2.14

Resources