Этот тип вопроса макета был задан ранее довольно много раз: -)
Из быстрого прочтения ссылок в этой теме кажется, что это нелегкоdo.
Редактировать: Правильно, этот меня беспокоит.Я подумал, что это возможно с небольшим количеством очень большим количеством сложного JavaScript / jQuery и установил , создав демо .
Еще предстоит проделать определенную работу, поскольку <p>
, который содержит изображение, был оставлен неправильно (то есть заполнен <span>
элементами).Я также не даю никаких обещаний относительно производительности этого решения.Кажется, у меня работает хорошо.Да, и ссылка Font +
будет работать только один раз, так как фактический размер шрифта, к которому увеличивается текст, фиксирован.
Тем не менее, я действительно попытаюсь найти альтернативное решение для вашегопроблема или даже вопрос, почему вам нужно исправить положение изображения таким образом.Это идет вразрез с обычным повторением в браузере и правилами.
Редактировать: Улучшенная демка , которая решает проблемы в комментариях.
Правка 2: Ух ты, я не знал, насколько сложной должна быть колонка CSS3 для браузеров!Высота рассчитывается для того, чтобы сделать столбцы более или менее равными, и это означает, что когда я отсоединяю <img>
, высота регулируется.Эта скорректированная высота будет другой, если font-size
увеличивается, а <img>
составляет , а не удаляется.Просто невозможно определить высоту результата до того, как <img>
будет удален и добавлен.
Тем не менее, я заставил его работать с одним основным условием - то, что столбец имеет жестко заданную высоту.Я пытался заставить его работать с вычисленной в браузере высотой (как диктуют нормальные правила потока), но я думаю, что это может быть очень сложно без большой работы.Единственный способ, которым я думаю, что это может сработать, - это перемещение элемента <img>
вперед на один <span>
(т. Е. Слово) за раз, пока не будет достигнут правильный position().top
.Но это было бы невероятно неэффективно и, вероятно, замедлило бы рендеринг настолько, что это было бы непригодно.
Итак, вот мое последнее демо , которое работает для меня в Chrome 11.Извините, я не смог найти полное решение с переменной высотой, но, как я и другие, сказал, что это действительно нарушает все правила компоновки браузера!
Редактировать 3: Когда я сказал "final«Демо, я явно не это имел в виду.Я принимаю ваш вызов на самом деле сделать эту работу должным образом с несколькими изображениями, и я действительно надеюсь, что на этот раз, я получил это.Пожалуйста, взгляните на это новое демо (работает в Chrome12 для меня), которое работает с HTML, который вы разместили.Я должен признать, что JavaScript, который вы разместили, был очень сложным.Так что я перестроил все для работы с несколькими изображениями на основе моего исходного JavaScript.
Редактировать 4: Довольно много правок сейчас ... но я нашел ошибку.При каждом увеличении или уменьшении шрифта изображения перемещаются в потоке и, возможно, добавляются margin-top
, чтобы вернуть изображение в исходное положение.Но я не очищал этот CSS перед тем, как пересчитать позицию при последующем изменении размера шрифта.
Код ключа был добавлен:
// clear any existing marginTop added on the images
images.each(function() {
$(this).css('marginTop', 0);
});
Я также немного прибрался к JavaScriptпока я был там и исправил еще одну ошибку с удалением элементов <span>
: -)
Обновленная демоверсия jsFiddle
И на всякий случай jsFiddleкогда-нибудь исчезнет, вот полное решение в виде одного файла HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
$(function(){
var fontSize = 15;
// cannot store img.position().top or .left here because it is
// before the browser has re-flowed the columns, therefore the
// positions will be incorrect
var imageTops = new Array;
var imageLefts = new Array;
$('#fontUp').click(function() {
reflow(1);
});
$('#fontDown').click(function() {
reflow(-1);
});
function reflow(fontSizeStep) {
storeImagePositions();
var fontLimitReached = changeFont(fontSizeStep);
if (!fontLimitReached) {
moveImages();
}
return false;
}
function changeFont(step) {
fontSize += step;
var fontSizeLimitReached = true;
if (fontSize > 30) {
fontSize = 30;
} else if (fontSize < 15) {
fontSize = 15;
} else {
fontSizeLimitReached = false;
}
if (!fontSizeLimitReached) {
$('p').css({fontSize: fontSize + 'px'});
}
return fontSizeLimitReached;
}
// initialize store of img top and left positions
function storeImagePositions() {
if (imageTops.length == 0) { // only do it once
$('img').each(function() {
var imgPosition = $(this).position();
imageTops.push(imgPosition.top);
imageLefts.push(imgPosition.left);
});
}
}
function moveImages() {
// bye bye images
var images = $('img').detach();
// clear any existing marginTop added on the images
images.each(function() {
$(this).css('marginTop', 0);
});
// spanify paragraphs
$('#column > p').each(function() {
$(this).html('<span>' + $(this).html().replace(/\s\s+/g).replace(/(\s)/g,'</span>$1<span>') + '</span>');
});
var imageIndex = 0;
// iterate words, working out where we can move the img to in the flow and if
// we find a match, increment the index so that as we continue the each()
// the next image is evaluated for replacement
$('#column > p span').each(function() {
var wordPosition = $(this).position();
var wordLeft = wordPosition.left;
if (wordLeft >= imageLefts[imageIndex]) {
var wordBottom = wordPosition.top + $(this).height();
if (wordBottom > imageTops[imageIndex]) {
$(this).before(images[imageIndex]); // move img before this word
var newImgTop = $(images[imageIndex]).position().top;
$(images[imageIndex]).css({marginTop: imageTops[imageIndex] - newImgTop + 'px'});
imageIndex++; // increment index so remainder spans are being evaluated against the next image
}
}
});
// reverse the "spanification"
$('#column > p').each(function() {
$(this).html($(this).html().replace(/<\\?span>/g, '').trim());
});
}
});
//]]>
</script>
<style type="text/css">
div#column {
-moz-column-count:6;
-webkit-column-count:3;
column-count:3;
-webkit-column-width:100px;
-moz-column-width:100px;
column-width:100px;
height:500px;
}
p {
margin:0;
clear:left;
font-size:15px;
text-align:justify;
}
img {
float:left;
}
</style>
</head>
<body>
<div><a href="#" id="fontUp" style="margin-right:10px">Font +</a><a href="#" id="fontDown">Font -</a></div>
<div id="column">
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. <img src="http://www.avatarblast.com/avatars/cool/yoda.jpg" title="yoda" alt="yoda"/>It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
<p>The change of name from <img src="http://www.avatarblast.com/avatars/cool/yoda.jpg" title="yoda" alt="yoda"/> LiveScript to JavaScript roughly coincided with Netscape adding support for Java technology in its Netscape Navigator web browser. The final choice of name caused confusion, giving the impression that the language was a spin-off of the Java programming language, and the choice has been characterized by many as a marketing ploy by Netscape to give JavaScript the cachet of what was then the hot new web-programming language. It has also been claimed that the language's name is the result of a co-marketing deal between Netscape and Sun, in exchange for Netscape bundling Sun's Java runtime with their then-dominant browser. Vivamus scelerisque ipsum ut justo. Pellentesque et ligula eu massa sagittis rutrum. In urna nibh, eleifend vel, suscipit ut, sagittis id, nunc.</p>
<p>Nam ut sapien sed pede pulvinar rutrum. Nunc eu elit sed augue aliquet tincidunt. Morbi rutrum. Vestibulum dui turpis, lobortis quis, euismod sed, consectetuer sit amet, nunc. Nam mi. Fusce at nisl eu tortor bibendum eleifend. Sed ac metus. Phasellus nec elit. Morbi tortor nulla, tristique a, adipiscing at, consectetuer et, nisi. Nunc vel sapien sed risus hendrerit egestas. Vivamus turpis arcu, placerat eu, congue vel, commodo ut, nisl.</p>
<p>Java EE includes several API specifications, such as JDBC, RMI, e-mail, JMS, web services, XML, etc., and defines how to coordinate them. Java EE also features some specifications unique to Java EE for components. These include Enterprise JavaBeans, Connectors, servlets, portlets (following the Java Portlet specification), JavaServer Pages and several web service technologies.<img src="http://www.avatarblast.com/avatars/cool/yoda.jpg" title="yoda" alt="yoda"/> This allows developers to create enterprise applications that are portable and scalable, and that integrate with legacy technologies. A Java EE application server can handle transactions, security, scalability, concurrency and management of the components that are deployed to it, in order to enable developers to concentrate more on the business logic of the components rather than on infrastructure and integration tasks.</p>
<p>Java (Indonesian: Jawa) is an island of Indonesia. With a population of 136 million, it is the world's most populous island, and one of the most densely populated regions in the world. It is home to 60% of Indonesia's population. The Indonesian capital city, Jakarta, is in west Java. Much of Indonesian history took place on Java; it was the centre of powerful Hindu-Buddhist empires, Islamic sultanates, the core of the colonial Dutch East Indies, and was at the centre of Indonesia's campaign for independence. The island dominates Indonesian social, political and economic life.</p>
</div>
</body>
</html>