How to get textContent including childNodes? - javascript

I have some plain text content in paragraphs inside a <main> HTML element.
the paragraphs are separated by new lines (\n), not in <p> tags, and I would like to automatically wrap them in <p> tags using JavaScript.
Example content:
<main>
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. 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="img/testimg.jpg"> 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.
</main>
Inside of <main> there may be <img> elements.
I want the script to watch for these and leave them untouched. It breaks the HTML (no image is rendered, and dev tools show overflow) if the script tries to wrap them like: <p><img src="img/testimg.jpg"></p> (assuming that is what it is doing).
My script so far:
var maintext = document.getElementsByTagName('main')[0]; // get the first (0th) <main> element
var arr = maintext.textContent.split(/[\r?\n]+/); // split the text inside into an array by newline
// regex matches one OR MORE consecutive newlines, which prevents empty <p></p> being captured
arr.forEach(function(part, index) {
if (!this[index].includes("<img ")) {
this[index] = "<p>" + this[index] + "</p>"; // wrap each paragraph with <p> tags
}
}, arr);
var rejoined = arr.join("\r\n"); // join the array to remove commas, with newlines as separators
maintext.innerHTML = rejoined; // replace contents of our <main> element with the new text
I believe the problem may be that <img> is not captured as text along with the textContent of <main>, but instead remains recognized as a child node and it's messing up the array.
You can see my attempt to only wrap in <p> if that array element does not (!) contain "<img " ...however, this is not working. It seems the enclosed HTML elements do not get matched as string data by includes.
What's the best way to go about this?

To retain non-text content like images, you'll need to process the text nodes of the main element rather than using textContent, since that's just the text content of the element.
Assuming you only want to do this with the text nodes, you can loop through the element's nodes, split text nodes on line breaks, and if you get more than one segment, insert paragraphs for them. Something like this (see inline comments):
function convertLineBreaksToParagraphs(element) {
// Get a snapshot of the child nodes of the element; we want
// a snapshot because we may change the element's contents
const nodes = [...element.childNodes];
// Loop through the snapshot
for (const node of nodes) {
// Is this a text node?
if (node.nodeType === Node.TEXT_NODE) {
// Yes, split it on line breaks
const parts = node.nodeValue.split(/\r\n|\r|\n/);
// Did we find any?
if (parts.length > 1) {
// Yes, loop through the "paragraphs"
for (const part of parts) {
// Create an actual paragraph for it
const p = document.createElement("p");
p.textContent = part;
// Insert in in front of the text node it came from
element.insertBefore(p, node)
}
// Remove the text node we've replaced with paragraphs
element.removeChild(node);
}
}
}
}
convertLineBreaksToParagraphs(document.querySelector("main"));
<main>
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. 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="img/testimg.jpg"> 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.
</main>
You may need to tweak that a bit, depending on how you want to handle that image just before the fifth paragraph. The above leaves the image outside the paragraph. But if you wanted it to be inside the paragraph, you could add some logic to do that.
function convertLineBreaksToParagraphs(element) {
let img = null;
// Get a snapshot of the child nodes of the element; we want
// a snapshot because we may change the element's contents
const nodes = [...element.childNodes];
// Loop through the snapshot
for (const node of nodes) {
// Is this a text node?
if (node.nodeType === Node.TEXT_NODE) {
// Yes, split it on line breaks
const parts = node.nodeValue.split(/\r\n|\r|\n/);
// Did we find any?
if (parts.length > 1) {
// Yes, loop through the "paragraphs"
for (const part of parts) {
// Create an actual paragraph for it
const p = document.createElement("p");
p.textContent = part;
// If we *just* saw an image before this text node,
// move it into the paragraph
if (img) {
p.insertBefore(img, element.firstChild);
img = null;
}
// Insert in in front of the text node it came from
element.insertBefore(p, node)
}
// Remove the text node we've replaced with paragraphs
element.removeChild(node);
}
} else if (node.nodeName === "IMG") {
img = node;
} else {
img = null;
}
}
}
convertLineBreaksToParagraphs(document.querySelector("main"));
<main>
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. 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="img/testimg.jpg"> 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.
</main>
You may have people telling you to do this by manipulating the HTML from innerHTML, but the problem with doing that is you run the risk of introducing tags in the middle of a tag (and you will remove any event handlers when you set innerHTML on main). For instance, if you have:
<img
src="/path/to/something">
you'd end up with
<img
<p> src="/path/to/something"></p>
...which is obviously not good.

Related

Iterate through a nodelist and on-click toggle the its content

I have created a set of questions and answers, using a function to loop through an array of objects, this part is working fine, the issue is that I only want the answers to show once a question is clicked, but my addEventListner is not working. Can anyone help please?
$(document).ready(function() {
$(renderReturns()).appendTo('#Returns');
})
let renderReturns = () => {
let returnsCard = "";
for (let i = 0; i < returnContent.length; i++) {
returnsCard += `<div class="question-container"> <div class="questions"> <a onclick=""><h3>${returnContent[i].question}</h3></a><img src="${returnContent[i].icon}" class="toggle-icon"> </div> <div class="answer" hidden><p>${returnContent[i].answer}</p></div></div>`
}
return `<div class="returnsWrapper">${returnsCard}</div>`
}
let questions = document.querySelectorAll('.questions');
let answers = document.querySelectorAll('.answer');
questions.forEach(question => {
question.addEventListener('click', (e) => {
console.log("It's alive, it's ALIVE!")
})
})
let returnContent = [{
question: "How do I return an item?",
icon: "https://via.placeholder.com/50x50",
answer: "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.",
},
{
question: "NEW! Instant Returns with InPost Lockers",
icon: "https://via.placeholder.com/50x50",
answer: "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.",
},
{
question: "What happens if I miss my delivery?",
icon: "https://via.placeholder.com/50x50",
answer: "Our carrier delivers between 9am and 10pm, which may vary depending on the service selected and a signature is required. <br> There are a number of options available if you think you won't be in to sign for your order. We'll pass your e-mail address and mobile number (if provided) to Hermes or DPD and they'll provide you with information about your delivery by e-mail or text message the evening before. <br> Please note deliveries outside of the UK can take anything up to 10 days. Follow your order using the tracking link in your despatch email to check if any delivery attempt has been made.",
},
{
question: "Can I track my delivery?",
icon: "https://via.placeholder.com/50x50",
answer: "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.",
},
{
question: "Do I pay customs or import charges?",
icon: "https://via.placeholder.com/50x50",
answer: "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.",
},
{
question: "Can I change my address after ordering?",
icon: "https://via.placeholder.com/50x50",
answer: "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.",
},
{
question: "Is the site secure?",
icon: "https://via.placeholder.com/50x50",
answer: "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.",
},
]
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="tab-content" id="Returns">
<div class="title-container">
<p>Returns</p>
</div>
</div>
To achieve this you need to relate the .question element which was clicked on to its child .answer. To do that you can use jQuery's next() method.
In addition the logic which creates the HTML from the array of objects and also that which attaches the event handlers can be simplified greatly by using jQuery more effectively; if you've already included it in the page you may as well use it.
Try this:
jQuery($ => {
let questionHtml = returnContent.map(obj => `<div class="question-container"><div class="questions"> <a onclick=""><h3>${obj.question}</h3></a><img src="${obj.icon}" class="toggle-icon"></div><div class="answer" hidden><p>${obj.answer}</p></div></div>`).join('');
$('#Returns').append(`<div class="returnsWrapper">${questionHtml}</div>`);
$('.questions').on('click', e => $(e.currentTarget).next('.answer').toggle());
})
let returnContent = [{
question: "How do I return an item?",
icon: "https://via.placeholder.com/50x50",
answer: "Lorem ipsum dolor sit amet...",
}, {
question: "NEW! Instant Returns with InPost Lockers",
icon: "https://via.placeholder.com/50x50",
answer: "Lorem ipsum dolor sit amet...",
}, {
question: "What happens if I miss my delivery?",
icon: "https://via.placeholder.com/50x50",
answer: "Our carrier delivers between 9am and 10pm, which may vary depending on the service selected and a signature is required....",
}
// truncated for brevity...
]
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="tab-content" id="Returns">
<div class="title-container">
<p>Returns</p>
</div>
</div>

having a problem with setting up parallax scroll

Trying to do my first parallax work, but I'm having an abnormal problem
when I write this code
window.addEventListener("scroll", function(e) {
const target = document.querySelector(".kalagh");
let scrolled = window.pageYOffset;
let rate = scrolled * 5;
target.style.transform = "translate3d(0px,'+rate+'px,0px)";
});
It doesn't do anything, but when I change rate variable to hard size like 500px it works fine, I've checked the code like billion times and can't understand where I am doing it wrong, BTW it is being done on a ul which has 3 lis, 1 of them has the class "kalagh".
Eh, you have a typo of mismatched quotation marks: in "...'...'..." the '...' part is still "inside" the string, you need "..." to "bail out" to JS code. Then it works:
window.addEventListener("scroll", function(e) {
const target = document.querySelector(".kalagh");
let scrolled = window.pageYOffset;
target.innerText=scrolled;
let rate = scrolled * 5;
target.style.transform = "translate3d(0px,"+rate+"px,0px)";
});
.kalagh {
background-color: red;
position:absolute;
}
<div class="kalagh">...</div>
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. 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. 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. 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. 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.

JavaScript; highlight all occurrences of a particular string in a textarea

Let's say I have this code:
<textarea style="width:300px;height:200px">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do ipsum eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ipsum ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in ipsum reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur ipsum sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit ipsum anim id est laborum.</textarea>
I want to highlight all occurrences of the string ipsum. I already googled but only found scripts that highlight a single occurrence only.
Does anybody have a hint for me?
You need to get a plugin that tokenize your textarea content into balise;
See http://codersblock.com/blog/highlight-text-inside-a-textarea/

Javascript word highlighting in a text

I have a variable called output in Javascript, which has the following content.
var output = "something."
I want to search and highlight the words "word1" and "word2" in them when I display the content of output. The above content is dynamic. Assuming I have a variable output which has the text and an array called arr1 which has the elements to be searched and highlighted, how can I display the entire content with words highlighted in javascript?Please let me know. Thanks in advance.
Assuming you want literal phrases that are generally just words (no special characters or punctuation), you could use a regular expression similar to this (I've also added case insensitivity):
var output = "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. 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.";
var arr1 = ['eiusmod tempor', 'consectetur'];
var regex = new RegExp('('+arr1.join('|')+')', 'gi');
output = output.replace(regex, "<b>$1</b>");
// the following line is for debug purposes only. I've added it
// to better display what's happening just for the Stackoverflow
// code snippet editor.
document.body.innerHTML = output;
b {
background: yellow;
font-weight: normal;
}
Edit:
Quick edit to include logic that ensures "consectrtur" is matched, but "consecteturs" is not. It just needs a simple look ahead of (?!\\w) and a "look behind" (not a real look behind because javascript doesn't support it) of (\\W+|^) ensuring the matched term is not surrounded by word characters, and thus not part of a different word.
var output = "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. 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 consecteturs cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum";
var arr1 = ['eiusmod tempor', 'consectetur', 'orem', 'laborum'];
var regex = new RegExp('(\\W+|^)('+arr1.join('|')+')(?!\\w)', 'gi');
output = output.replace(regex, "$1<b>$2</b>");
// the following line is for debug purposes only. I've added it
// to better display what's happening just for the Stackoverflow
// code snippet editor.
document.body.innerHTML = output;
b {
background: yellow;
font-weight: normal;
}
You can wrap the words you want highlighted with a <span> tag then add a class or inline styling to the tag for your highlight color. This would require that you identify the words you want highlighted and add the opening tag before and closing tag after with a String.replace(word, tag + word + closing_tag) or something similar.
To wrap something in HTML using Javascript, you should be looking at Regex. For example:
str = str.replace(/(neoplasm)/ig, "<b>$1</b>");
To replace from an array, you could do something like connecting your strings with a join using the regex OR: | to generate a custom regex string, matching those words.
EDIT: Like Joseph just suggested, just one minut before me.

console returning different heights in ie, ff and chrome for the same element?

I have set .outerHeight(true) on the element #inner but at the moment it returns height values
ie: 304
ff: 317
chrome: 289
can anyone explain where I might be going wrong with this?
JS
var wH = $(window).height(),
wrapper = $('#wrapper'),
inner = $('#inner'),
innerH = inner.outerHeight(true),
more = inner.find('.more'),
close = inner.find('.close'),
titleH = $('#title').outerHeight(true),
excerpt = $('.excerpt'),
excerptH = excerpt.outerHeight(true),
lowerH = $('.lower').outerHeight(true),
upper = inner.find('.upper'),
footerH = $('#footer').height()
body = $('body');
// Set #wrapper off page
wrapper.css('bottom', -innerH);
// Store tier1 calculation as data attribute
wrapper.data('tier1', -innerH+titleH+footerH);
console.log(innerH);
//console.log(-innerH+titleH+footerH);
// Animate #wrapper above #footer
wrapper.delay(500).animate({ bottom: wrapper.data('tier1') }, 400);
CSS
body{font-family:Arial,Helvetica,sans-serif;overflow: hidden;}
h1{text-align:center;width:600px;margin:0 auto;padding:20px 0 45px;font-size:28px;font-weight:bold;line-height:26px;}
p{margin-bottom:20px;}
#tiers{background:#f2f2f2;height:100%;}
#wrapper{width:100%;position:absolute;bottom:0;left:0;background:#dedede;}
#inner{width:840px;margin:0 auto;}
.upper{display:none;}
.upper p{margin-bottom:0;}
.col{width:410px;}
.btn{background: #000000;color: #FFFFFF;display: block;font-size: 20px;font-weight: bold;width:30px;height:30px;text-align:center;line-height:30px;position: absolute;text-decoration: none;}
.more{top:20px;right:20px;}
.close{display:none;top:60px;right:20px;}
.excerpt{display: block;}
HTML
<body class="tier1">
<div id="tiers">
<div id="wrapper">
<div id="inner" class="clearfix">
-
+
<div class="lower">
<h1 id="title">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</h1>
<p class="excerpt">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>
</div>
<div class="upper">
<div class="col left"><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></div>
<div class="col right"><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></div>
</div>
</div>
</div>
</div>
<div id="footer"></div>
</body>
Link to page: http://bit.ly/IA65Mb
Kyle
There are a few differences I was able to spot:
p has a 20px margin-bottom which propagates to #inner in chrome. I don't remember the details of this feature but I think I heard once that it's actually correct behavior. I think only chrome has it. See example
for some reason #excerpt has different heights in ff and chrome - maybe there are slight differences in text rendering?
I think fixing the first issue would solve the problem you're having though. Getting exact same result cross-browser is an overkill.

Categories

Resources