I have a PHP function that loops through image results in a database, formats them with HTML, then returns the variable containing the HTML layout to my page.php. This is all working okay, but in the loop I have some script tags that call a function in my script.js file. It takes two parameters (url and count). I am trying to pass the url of the result from the database to the function, create a new img
element, and append the passed url to the src attribute of the newly created img tag.
This appears to be working so far - when I console.log the result, I get a load of <img>
tags, all with corresponding src attached to them.
I am having trouble with actually getting these back to the front end, though.
My code below shows the part of the php that gets looped through, followed be the Javascript function it calls on each loop.
public function getResultsHtml($page, $pageSize, $term) {
$fromLimit = ($page - 1) * $pageSize;
$query = $this->con->prepare("SELECT * FROM images
WHERE (title LIKE :term
OR alt LIKE :term) AND broken=0
ORDER BY clicks DESC
LIMIT :fromLimit, :pageSize");
$searchTerm = "%" . $term . "%";
$query->bindParam(":term", $searchTerm);
$query->bindParam(":fromLimit", $fromLimit, PDO::PARAM_INT);
$query->bindParam(":pageSize", $pageSize, PDO::PARAM_INT);
$query->execute();
$resultsHtml = "<div class='image-results'>";
$count = 0;
while($row = $query->fetch(PDO::FETCH_ASSOC)) {
$count++;
$id = $row["id"];
$imgUrl = $row["imgUrl"];
$siteUrl = $row["siteUrl"];
$title = $row["title"];
$alt = $row["alt"];
if($title){
$displayText = $title;
} else if ($alt) {
$displayText = $alt;
} else {
$displayText = $imgUrl;
}
$resultsHtml .= "<div class='grid-item image$count'>
<a href='$imgUrl'>
<script>
document.addEventListener('DOMContentLoaded', function() {
loadImage(\"$imgUrl\", \"image$count\");
});
</script>
<span class='details'>$displayText</span>
</a>
</div>";
}
$resultsHtml .= "</div>";
return $resultsHtml;
}
var loadImage = function(src, className){
var image = document.createElement("img");
var aTag = document.querySelectorAll("." + className + " a");
image.onload = function(){
aTag.innerHTML = image;
};
image.onerror = function(){
};
image.setAttribute("src", src);
}
At the moment I'm not geting any results at the front end. In the page source, I can see that inside each anchor tag are script tags, which show the function preloaded with the parameters (loadImage(http://www.com, image22)
), but it isn't actually getting a return from the function.
The solution for this with jQuery is below, but I really don't want to use jQuery!
function loadImage(src, className) {
var image = $("<img>");
image.on("load", function() {
$("." + className + " a").append(image);
});
image.on("error", function() {
});
image.attr("src", src);
}
I know that there is some trouble with dynamically writing <script>
tags with .innerHTML
, but I don't think this is the problem as the script tags are written before the function is called.
I think I have something firing in the wrong order, or I'm missing something that jQuery handles automatically with the .append function.
I have also tried aTag.appendChild(image);
, which also gives no results.
I have been using jQuery for a few months, but I am trying to learn Vanilla JS thoroughly - I'm trying to grasp how the jQuery functions actually work, rather than just relying on them blindly.
Any help is massively appreciated!
Beware of that querySelectorAll()
returns an array-like NodeList (https://developer.mozilla.org/en-US/docs/Web/API/NodeList), so it should be like this:
(If you only want one element returned user querySelector()
, then you don't need the loop)
function loadImage(src, className) {
var image = document.createElement("img");
image.src = src;
image.onload = function() {
var tags = document.querySelectorAll("." + className + " a");
for (var i = 0; i < tags.length; i++) {
tags[i].appendChild(image);
}
}
}
<div class='grid-item image2'>
<a href='https://cdn.pixabay.com/photo/2015/08/21/21/55/star-wars-899693_960_720.jpg'>
<script>
document.addEventListener('DOMContentLoaded', function() { loadImage("https://cdn.pixabay.com/photo/2015/08/21/21/55/star-wars-899693_960_720.jpg", "image2");
});
</script>
<span class='details'>Star Wars 1</span>
</a>
</div>