My goal is to strip the images and iframes out of WordPress posts (they are in .para divs) and move them to a <ul>
above the post, just inside the local wrapper (.wrapper940).
The jQuery below works, but moves ALL image and iframes from all posts to a single new <ul>
above the first post. Instead of this, I am trying to move the images and iframes PER POST to a new <ul>
just inside the wrapper of each post.
Here's the jQuery:
jQuery("document").ready (function($){
var matchesEl = $(".para img, .para iframe");
if ( matchesEl.length > 0) {
var newUl = $("<ul></ul>");
newUl.prependTo(matchesEl.parents(".wrapper940"));
matchesEl.each(function() {
var newLi = $("<li></li>").append($(this)).appendTo(newUl);
});
}
});
The html is:
<div class="news-item-wrap">
<div class="date">the date</div>
<div class="wrapper940">
<div class="title">the title</div>
<div class="para">
<p>The main content of the post.</p>
<p>Which could be several paragraphs</p>
<p>And include iframes...</p>
<p><iframe src="//www.youtube.com/embed/uGMbZNTym-g" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen">...</iframe>
</p>
<p>Followed by more text... and maybe some images....</p>
<p><a href="http://www.joujouka.org/wp-content/uploads/2014/05/festival-interculture.jpg"><img class="alignnone size-medium wp-image-404" alt="festival intercultural" src="http://www.joujouka.org/wp-content/uploads/2014/05/festival-interculture-213x300.jpg" width="213" height="300"/></a>
</p>
</div>
</div>
<div class="news-item-wrap">
<div class="date">the date</div>
<div class="wrapper940">
<div class="title">the title</div>
<div class="para">
<p>A second post would follow like this.</p>
<p>Which could also be several paragraphs</p>
<p>And include iframes...</p>
<p><iframe src="//www.youtube.com/embed/uGMbZNTym-g" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen">...</iframe>
</p>
<p>Followed by more text... and maybe some images....</p>
<p><a href="http://www.joujouka.org/wp-content/uploads/2014/05/festival-interculture.jpg"><img class="alignnone size-medium wp-image-404" alt="festival intercultural" src="http://www.joujouka.org/wp-content/uploads/2014/05/festival-interculture-213x300.jpg" width="213" height="300"/></a>
</p>
</div>
</div>
This would continue for as many posts as there were. So I need to be able to move the images and iframes FOR EACH POST to appear just inside the .wrapper940 that wraps EACH POST. (i.e. above the title of each post.)
I think that using .parents()
is sending all images and iframes from all posts to the first .wrapper940
; .closest()
seems like it should work, but doesn't, maybe because it breaks the loop?
Any help very much appreciated!
Check this:
jQuery("document").ready (function($){
var matchesEl = ".para a:has(img), .para iframe"
$('.wrapper940').each(function(index){
if ($(this).find(matchesEl).length > 0) {
$('<ul>').insertBefore($(this).children('.title'));
$(this).find(matchesEl).each(function() {
//The line code under will only works if all your .wrappers940 always have at least one matched element.
//$("<li>").append($(this)).appendTo($('.wrapper940 ul').eq(index));
//So the right code is:
$("<li>").append($(this)).appendTo($('.wrapper940').eq(index).children('ul'));
});
}
$('p').filter(function () { return $.trim(this.innerHTML) == "" }).remove();
});
});
Commenting code:
1) If you want only to move the image, you use .para img
, but I think you want to move the element <a>
with the <img>
, so you can use: .para a:has(img)
.
2) The index
var here $('.wrapper940').each(function(index){
is important to match the right ul in this line: $("<li>").append($(this)).appendTo($('.wrapper940 ul').eq(index));
3) This line will remove blank <p>
tags: $('p').filter(function () { return $.trim(this.innerHTML) == "" }).remove();
after you move their content into <li>
s
Codepen: http://codepen.io/anon/pen/wDmsi
Answering your questions in comments:
1) The index
is the index number of your element matched in each()
. The base number is 0. So if you have 10 .wrapper940 in your page, the first one will have index = 0, the second will have index = 1, til the last and 10th will have index = 9. We use it here to force code not send the img and iframes to the wrong .wrapper940. It says img and iframes from .wrapper940 index 6 belongs to .wrapper940 index 6. Writing this I just discovered a fail in my code. Check the code above to see the changes.
2) I always used this
for pure javascript and $(this)
for jquery. It seems like $(this)
have more properties, like we see here: Difference between $(this) and this in jquery but using the $(...)
consume more processing. So you can always test if both works on each case and use just this
.
3) You can simplify:
var newUl = $("<ul></ul>");
newUl.insertBefore($(this).children('.title'));
To
$('<ul></ul>').insertBefore($(this).children('.title'));
And from this to
$('<ul>').insertBefore($(this).children('.title'));
4) The funcion appendTo()
, insertBefore()
and similars are already a kind of echo. I believe that if the element exist, the jQuery will move it. If it won't exist, jQuery will create it, but I can't confirm conclusively.
5) This trick of clear <p>
tags is kind magic to me too. I don't know exactly how it works. I got the code from here: Remove "empty" paragraphs with jQuery
来源:https://stackoverflow.com/questions/25174429/use-jquery-to-move-wordpress-post-attachments-to-per-post-dynamically-created-li