How to wrap a class around the first half of a headline?
I'm trying to wrap a cl开发者_JS百科ass around the first or the second half of a headline so that I could create more dynamic and cool headlines with jQuery.
In theory I want to find all of the spaces in the sentence and divide it into two. If the headline contains an uneven number of words the script should detect that and also add the class to the nearest word.
This is an interesting problem. I would approach with the handy javascript splice method. Splice can be used to insert and delete items of an array. I'd recommend opening up an inspector and trying out some of the examples I've written below.
First we'll use jQuery to select the header then manipulate the html content string. I'm assuming that the specific header you want to manipulate will have a class and I've substituted 'dynamic':
var header = $("h1.dynamic").text();
=> "Header with some other stuff"
var header_as_array = header.split(" ")
=> ["Header", "with", "some", "other", "stuff"]
var first_half = header_as_array.splice(0, header_as_array.length/2)
Keep in mind that splice changes the original array, so at this point:
first_half = ["Header", "with"]
header_as_array = ["some", "other", "stuff"]
Now, you can join them back together and wrap them with spans like so:
var first = '<span class="first_half">'+first_half.join(" ")+'</span>';
var second = '<span class="second_half">'+header_as_array.join(" ")+'</span>';
var finished = first+" "+second;
Finally, we'll put our finished string back into the header with jQuery:
$("h1.dynamic").html(finished);
The way I've written it a header with an odd number of words will always have the second half as the longer half. If you would prefer it the other way around you could do this:
var splice_location = Math.ceil(test_as_array.length/2);
var first_half = header_as_array.splice(0, splice_location);
By default a non-integer value will be truncated, but here we are using the ceiling function to round things up instead of down.
Nice one @lashleigh. You can have a look at a working example here:
http://jsfiddle.net/johnhunter/KRJdm/
@Tony, I've implemented what you are after as a jquery plugin. You call it on the header you want formatted:
$(function() {
$('h1').splitWords();
});
...and it will produce html output like this:
Before:
<h1>This is a long headline</h1>
After:
<h1>
<span class="wrap-1">This is </span>
<span class="wrap-2">a long headline </span>
</h1>
UPDATED:
Not part of the original question but I have updated the example to allow you to specify at which word the wrapping occurs. If you provide an index argument it will use that offset on the list of words (minus values count back from the end). e.g:
$('h1.a').splitWords(); // Split these words equally
$('h1.b').splitWords(1); // Split these after the first word
$('h1.c').splitWords(-2); // Split these after the second last word
http://jsfiddle.net/johnhunter/KRJdm/
Try the following
<html>
<head>
<title>Test</title>
<script type="text/javascript" src="jquery-1.5.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var headlineText = $('h1.mainHeader').text();
var headlineWords = headlineText.split(' ');
var headlineLength = headlineWords.length;
var headlineMidPoint = (headlineLength / 2) + 1;
var headlineFirstHalfText = headlineWords.slice(0, headlineMidPoint).join(' ') + ' ';
var headlineSecondHalfText = headlineWords.slice(headlineMidPoint).join(' ');
var d = document;
var headlineFirstHalf = $(d.createElement('span')).addClass('headlineHead').text(headlineFirstHalfText);
var headlineSecondHalf = $(d.createElement('span')).addClass('headlineTail').text(headlineSecondHalfText);
var headline = $(d.createElement('h1')).addClass('mainHeader').append(headlineFirstHalf).append(headlineSecondHalf);
$('h1.mainheader').replaceWith(headline);
});
</script>
<style type="text/css">
h1 { font-size:18px;}
span.headlineTail {font-size:1.2em;}
</style>
</head>
<body>
<h1 class="mainHeader">This is a dynamic headline</h1>
<p>Lorem ipsum dolor sit amet, consectetur...</p>
</body>
</html>
lashleigh's answer is great, however, I would challenge the premise that jQuery is the best choice of technology for achieving this effect. I would be inclined to suggest doing the same server-side. Phrasing the markup using PHP, Python or whatever language you are using and then caching the output with the inserted class. Saves on page weight and means the user's browser doesn't have to calculate everything when each a page is loaded. A significant benefit on light clients such as mobile devices.
Here is an example in PHP.
<?php
$headline = "This is a headline of epic proportions";
$split = explode(' ', $headline);
$a = array_slice($split, 0, (count($split)/2));
$b = array_slice($split, (count($split)/2));
$headline = '<span class="whatever">'. join(' ', $a) . '</span>' . join(' ', $b);
print $headline;
?>
精彩评论