Does anyone have any idea how to have an image transition to another page without re-loading. There is a good example of this on http://nahelmoussi.com/ .
When you click on a case study image, the image gets bigger and stays on the page.
I know you could use CSS Transitions for the animation but what I'm confused about is how you load a whole new page (different page for SEO) and make it so the image never looks like it's reloading?
history.pushState()
The DOM window object provides access to the browser's history through the history object. It exposes useful methods and properties that let you move back and forth through the user's history, as well as -- starting with HTML5 -- manipulate the contents of the history stack.
pushState() takes three parameters: a state object, a title (which is currently ignored), and (optionally) a URL.
And AJAX
AJAX stands for Asynchronous JavaScript And XML. In a nutshell, it is the use of the XMLHttpRequest object to communicate with servers. It can send and receive information in various formats, including JSON, XML, HTML, and text files. AJAX’s most appealing characteristic is its "asynchronous" nature, which means it can communicate with the server, exchange data, and update the page without having to refresh the page.
After animating the image, we can update the browser's history by appending a new location, and use AJAX to fetch the new content.
Manipulating the history allows that the user can navigate back and forth in the same way they would if they had navigated to a new location the traditional way.
We can use AJAX to fetch new data, and optionally change parts or all of the page content to show this new data.
The effect of the combined methods is that after clicking the image:
The image expands.
The rest of the content is either hidden or overwritten.
New data is fetched.
The new data is displayed.
The history is updated.
It appears to the user that they have navigated to a new location (and their browser history will show that they did), but that the image they originally clicked remained on their screen at all times.
An unrefined and basic demo:
Although not fully functional, this will demonstrate the fundamentals of the process if served by a localhost. The scope of the question is too wide for a narrow demo, and a wide enough demo to show the full functionality would require building an entire demonstration website.
<!DOCTYPE html>
<html>
<head>
<title>Page 1</title>
<script async>
( function( W, D ) {
var handlePopstate = function( evt ) {
// handle history navigation through evt.state
console.log( evt.state );
},
getNewContentAndUpdateHistory = function( d, p ) {
// create and call ajax for new content using destination URL
console.log( d );
// update the browser's history and the history.state
history.pushState( { ps: p }, "", d );
// handle history navigation through history.state
console.log( history.state );
},
init = function() {
D.addEventListener( "click", function( evt ) {
var trg = evt.target;
if ( trg.tagName.toLowerCase() === "img" && !trg.classList.contains( "bg" ) ) {
var dest = trg.getAttribute( "data-href" ),
page = /(\d+)/.exec( dest )[ 1 ];
trg.classList.add( "bg", "_" + page );
// load, parse and display new content and update the browser's history
getNewContentAndUpdateHistory( dest, page );
}
}, false );
};
if ( /^(?:complet|interactiv)e$/.test( D.readyState ) ) {
init();
} else {
W.addEventListener( "DOMContentLoaded", init, false );
}
W.addEventListener( "popstate", handlePopstate, false );
} ( window, document ) );
</script>
<style>
html {
font-size: 10px;
}
body {
font-family: sans-serif;
font-size: 1.6rem;
margin: 0;
padding: 0;
}
img {
position: relative;
display: block;
width: 400px;
height: 200px;
cursor: pointer;
transition: width 1s, height 1s;
}
.bg {
position: absolute;
width: 100vw;
height: 100vh;
top: 0;
left: 0;
cursor: default;
}
._2 {
z-index: 2;
}
._3 {
z-index: 3;
}
._4 {
z-index: 4;
}
</style>
</head>
<body>
<h1>Foo</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.<img src="http://lorempixel.com/400/200" data-href="page/2/"></p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.<img src="http://lorempixel.com/400/200" data-href="page/3/"></p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.<img src="http://lorempixel.com/400/200" data-href="page/4/"></p>
</body>
</html>
Related
How to add text in jquery marquee dynamically?
I have tried to append the text to a marquee, it's working but when I add long text, it starts not working properly (The text marquee didn't finish in the middle of animation marquee will be started again even the last text hasn't arrived yet).
my code like this :
$(document).ready(function(){
$('.marquee').marquee({
//speed in milliseconds of the marquee
duration: 15000,
//gap in pixels between the tickers
gap: 50,
//time in milliseconds before the marquee will start animating
delayBeforeStart: 0,
//'left' or 'right'
direction: 'left',
//true or false - should the marquee be duplicated to show an effect of continues flow
duplicated: true
});
});
function AppendData(){
document.getElementById("line").innerHTML += '| MARK | ------------------------------------ THIS IS LONG TEXT I APPEND -------------------------------------------------------------------';
}
.marquee {
width: auto;
overflow: hidden;
}
.marquee span.line{
padding-top: 6px;
color: rgba(0,0,0, 0.6);
font-size: 9pt;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/jquery.marquee#1.5.0/jquery.marquee.min.js" type="text/javascript"></script>
<div class="marquee" id="tambah">
<span class="line" id="line"><span class="title">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</span>
</div>
<button onclick="AppendData()">Add Text</button>
Marquee.js seems to be really futsy. This should get you close to where you'd like to be. I can't keep working on it, but I wanted to at least put you in the right direction. Before its invocation, you can .bind() an event called finished that will destroy the old marquee, reset data, and resume the marquee. However, there doesn't seem to be any looping options that don't make it restart from the right of the screen, so it jumps. I'm sure there's something you can do with this. Please look at the event part of Marquee.js' documentation for more info.
https://github.com/aamirafridi/jQuery.Marquee#events
$(document).ready(function() {
const options = {
//speed in milliseconds of the marquee
duration: 2000,
//gap in pixels between the tickers
gap: 50,
//time in milliseconds before the marquee will start animating
delayBeforeStart: 0,
//'left' or 'right'
direction: 'left',
//true or false - should the marquee be duplicated to show an effect of continues flow
duplicated: true
};
const textToAdd = '| MARK | ------------------------------------ THIS IS LONG TEXT I APPEND -------------------------------------------------------------------';
var addLine = false;
const line = $("#line");
const btn = $("#btn");
$('.marquee').bind('finished', function() {
if (addLine == true) {
var newLine = $("#line").innerHTML += textToAdd;
$(this).marquee('destroy').append(newLine);
$('.marquee').marquee(options);
}
}).marquee(options);
btn.on("click", function appendData() {
addLine = true;
});
});
.marquee {
width: auto;
overflow: hidden;
}
.marquee span.line {
padding-top: 6px;
color: rgba(0, 0, 0, 0.6);
font-size: 9pt;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/jquery.marquee#1.5.0/jquery.marquee.min.js" type="text/javascript"></script>
<div class="marquee" id="tambah">
<span class="line" id="line">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</span>
</div>
<button id="btn">Add Text</button>
I'm trying to add a dropdown effect to my website but I can't seem to get it right.
I'd like to click on the '+' and let the shape expand to show text, so after I clicked '+', some sort of animation should begin?
I'm new to javascript and I'd like if someone could help me out
http://severinereard.be/test/
Here's the website, I only finished the mobile version so it's best viewed in a thin browser window.
In the first section 'Pelvi-périnéologie' I added a paragraph which I hid with display none.
I hope this is enough information
UPDATE:
I added the javascript and it works for the first section but not for the rest. I'd also like for the dropdown to not go so fast but smooth?
Thanks in advance!
Here's an example of a possible solution. Layout is different, but you'll get the idea.
UPDATE: included javascript to handle the click
const sections = [...document.getElementsByTagName("section")];
sections.map((section) => {
section.addEventListener("click", function() {
const paragraph = this.querySelector("p");
paragraph.style.maxHeight = "100px";
})
})
section {
display: inline-block;
}
section img,
section h3,
section h5 {
display: inline;
}
section p {
max-height: 0;
overflow-y: scroll;
transition: max-height 1s;
width: 300px;
/* for demo purpose */
}
section:hover p {
/*max-height: 100px; to force scrollbar */
}
<section>
<img src="https://via.placeholder.com/40">
<h3>Pelvi-périnéologie</h3>
<h5>+</h5>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</section>
I have multiple items in a div with paragraphs and I would like to truncate them to 2 lines. I have tried to truncate using the height but it results in cut off words. I can't use characters because in some cases the words are long and get pushed to a new line.
I am trying to work with getClientRects() as you'll see in the fiddle below.
Also note that I can't use any plugins for the project I am working on.
I found this example on another post: Working Truncate from stackoverflow post
My Fiddle:
JS Fiddle
var lines = $(".truncate")[0].getClientRects();
var divHeight = 0;
for (var i=0, max = 2; i < max; i++)
divHeight += lines[i].bottom - lines[i].top;
divHeight += i;
$(".truncate").height(divHeight);
There's a number of issues.
The code you're trying to work from takes advantage of a quirk related to display: inline but you don't set display: inline, instead leaving .truncate at the browser default of display: block.
ready isn't a real event and jQuery no longer fakes it when using .on('ready', ...) so your code never runs.
jQuery's .height() requires that the argument be in the form of a CSS height value. This means you need to use something that results in, for example, '50px' rather than just 50.
height is ignored on inline elements so it'll have to be set on the outer element. The code you were working from did this but you didn't follow it.
Your code assumes that the number of lines will always be two or more.
overflow: hidden isn't set so the text itself will push outside its container even if the container was shortened.
All together, your code should look something like this instead:
.item {
width: 400px;
margin: 20px;
display: inline-block;
overflow: hidden;
box-sizing: content-box;
}
.truncate {
display:inline;
}
$(document).ready( function(){
var lines = $(".truncate")[0].getClientRects();
var divHeight = 0;
var max = lines.length >= 2 ? 2 : lines.length;
for (var i=0; i < max; i++) {
divHeight += lines[i].bottom - lines[i].top;
}
divHeight += i;
$(".item").height(divHeight + 'px');
});
JSFiddle
Using the css answer from css-tricks (https://css-tricks.com/line-clampin/) assuming you know the line-height.
.item {
width: 400px;
margin: 20px;
overflow: hidden;
}
.fade {
position: relative;
height: 2.4em; /* exactly two lines */
}
<div class="item fade">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
<div class="item fade">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
My goal is to have a button that onclick will call a function to change the styling of the html tag and the text (or innerHTML) of the button itself. Shouldn't be that hard, right? Well...
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>New look for my site!</title>
<link rel="stylesheet" type="text/css" href="main.css">
<script src="change-template.js"></script>
</head>
<body>
<aside>
<button type="button" id="template-button" onclick="changeTemplate()">Nightmode: On</button>
</aside>
<main>
<h1>New page look for my site</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</main>
</body>
</html>
CSS (main.css):
html{
background: "#111";
color: "#0F0";
}
JS (change-template.js):
var html = document.getElementsByTagName('html')[0];
var button = document.getElementById('template-button');
var nightmode = true;
function changeTemplate(){
//change to lighter color if black and vice versa
if(nightmode){
html.style.background = "#EEE";
html.style.color = "#000";
button.innerHTML = "Nightmode: OFF";
}else{
html.style.background = "#111";
html.style.color = "#0F0";
button.innerHTML = "Nightmode: ON";
}
nightmode = !nightmode;
}
And I'm getting this error
Uncaught TypeError: Cannot set property 'innerHTML' of null
at changeTemplate (change-template.js:10)
at HTMLButtonElement.onclick (new-look.html:11)
So please help me it's 90 degrees and I'm sitting here on the verge of hunger stressed about this simple issue and can barely think.
That is because, your script is parsed, event before the elements are available in the DOM.
When the parser encounters var button = document.getElementById('template-button'); the element is not yet available in the DOM.
Because of which your code is technically doing this.
undefined.innerHTML
Move the script tag to just above the closing body tag. This will fix the issue since the elements are available in the DOM, when they get stored in the variables.
</main>
<script src="change-template.js"></script>
</body>
if you still want to include your script in the head, the other way around is wrap the code in document.onload which triggers, when the DOM is ready.
document.onload = function(e) {
// your code goes here
};
I'm looking to create a ruled page effect in CSS or Javascript/JQuery, for example. I know this can be achieved with CSS by setting a fixed line height and create a background image to suit.
I would, however, prefer to create a vector solution (ie no images) much like this, but I need it to work in IE.
Is it possible to generate this effect without use of images that works across all modern browsers?
The ideal solution would be to detect the top and bottom of a line in paragraph and draw a line in between with javascript - so it'll work with undefined line heights (but I'm happy to define them if necessary).
I forgot to mention that the text is dynamic.
Try heading in this direction: http://jsfiddle.net/Jw8pw/
It's very basic but You can get more in depth, if you consider the line border height, the text position.
Basically everything needs to be based on em height. Use a transparent div for the margin with a border and divs for hole punches via border radius.
Just added some more: to it http://jsfiddle.net/julienetienne/Jw8pw/6/
//jquery
var lineHeight = $('#content p').css('line-height') ;
$('.line').css({height: lineHeight },0);
var x = $('#content').height();
$('#paper').css('height', x + 40 +"px");
You will need to write a script to manually add the line divs so they fill the paper past the overflow but not too much.
Estimate how many pixels to em you use in the max case, (lets say 40px),
You will do something like "height of text #content div" divided by custom (40px)ratio, add 10 (to be on the safe side), and that's how many lines you need to "write"
The #paper has no overflow so more div lines are welcomed but too much over (as in hundreds) is a bit lazy
You can use a Canvas in all modern browsers (incl. IE9). The following example won't work in IE7 and IE8, but I haven't tested there.
<!DOCTYPE html>
<html>
<head>
<title>Line Test</title>
<style type="text/css">
#ruled {
border: 1px solid red;
}
#textContainer {
position: absolute;
left: 0;
top: 0;
width: 580px;
height: 1200px;
font-size: 12px;
margin: 10px;
padding: 5px 10px;
line-height: 20px;
}
</style>
<script type="text/javascript">
function drawLines(){
// get the canvas element using the DOM
var canvas = document.getElementById('ruled');
var currentLineY = 0;
// Make sure we don't execute when canvas isn't supported
if (canvas.getContext){
// use getContext to use the canvas for drawing
var ctx = canvas.getContext('2d');
ctx.strokeStyle = "#CCC";
ctx.beginPath();
// draw some lines (the +1.5 offsets the text baseline
// and we use the .5 for crisp lines because the stroke()
// method requires floats, not ints
for (var i=1, imax=30; i<imax; i++) {
currentLineY = i*20 + 1.5;
ctx.moveTo(0,currentLineY);
ctx.lineTo(600,currentLineY);
}
ctx.stroke();
} else {
alert('You need a modern browser to see the lines.');
}
}
</script>
</head>
<body onload="drawLines()">
<canvas id="ruled" width="600" height="602"></canvas>
<div id="textContainer">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
<br><br>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
</body>
</html>