Динамически добавлять теги <img>с помощью цикла PHP, вызывая функцию JavaScript в каждом цикле - PullRequest
0 голосов
/ 10 января 2019

У меня есть функция PHP, которая просматривает результаты изображений в базе данных, форматирует их с помощью HTML, а затем возвращает переменную, содержащую макет HTML, в мой page.php. Это все работает нормально, но в цикле у меня есть несколько тегов script, которые вызывают функцию в моем файле script.js. Требуется два параметра (url и count). Я пытаюсь передать URL результата из базы данных в функцию, создать новый элемент img и добавить переданный URL в атрибут src вновь созданного тега img. Похоже, это работает до сих пор - когда я console.log результат, я получаю загрузку <img> тегов, все с соответствующим src, прикрепленным к ним.

У меня проблемы с тем, чтобы на самом деле вернуть их на передний конец.

В моем коде ниже показана часть php, которая проходит через цикл, за которой следует функция Javascript, которую он вызывает в каждом цикле.

    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);

    }

В данный момент я не получаю никаких результатов на переднем крае. В исходном коде страницы видно, что внутри каждого тега привязки есть теги сценария, которые показывают функцию, предварительно загруженную параметрами (loadImage(http://www.com, image22)), но на самом деле она не получает отдачу от функции.

Решение для этого с помощью jQuery приведено ниже, но я действительно не хочу использовать jQuery!

            function loadImage(src, className) {

                var image = $("<img>");

                image.on("load", function() {
                    $("." + className + " a").append(image);
                });

                image.on("error", function() {

                });

                image.attr("src", src);

            }

Я знаю, что есть некоторые проблемы с динамическим написанием тегов <script> с .innerHTML, но я не думаю, что это проблема, поскольку теги сценария пишутся до вызова функции.

Я думаю, что у меня что-то срабатывает в неправильном порядке, или мне не хватает чего-то, что jQuery обрабатывает автоматически с помощью функции .append.

Я также пробовал aTag.appendChild(image);, что также не дает результатов.

Я использую jQuery в течение нескольких месяцев, но я стараюсь тщательно изучить Vanilla JS - я пытаюсь понять, как на самом деле работают функции jQuery, а не просто слепо полагаться на них.

Любая помощь очень ценится!

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Проблема в том, что вы используете querySelectorAll, который возвращает NodeList вместо одного узла DOM. Это означает, что вам нужно перебрать NodeList и добавить изображение ко всем узлам внутри. Для этого у вас есть возможность либо создавать новые копии для каждого места, куда вы хотите вставить изображение, либо использовать cloneNode несколько раз.

var each = function (xs, func) {
  for (var i = 0; i < xs.length; i += 1) {
    func(xs[i]);
  }
  return xs;
}


var loadImage = function(src, className){

    var image = document.createElement("img");
    var aTag = document.querySelectorAll("." + className + " a");

    image.onload = function(){
      each(aTag, function (a) {
        a.appendChild(image.cloneNode());
      });
    };
    image.onerror = function(){};
    image.alt = '';
    image.src = src;

}



loadImage('http://www.fillmurray.com/500/300', 'wrap')
<div class="wrap">
  <a href="#"></a>
  <a href="#"></a>
  <a href="#"></a>
</div>
0 голосов
/ 10 января 2019

Остерегайтесь этого querySelectorAll() возвращает массив-подобный NodeList (https://developer.mozilla.org/en-US/docs/Web/API/NodeList),, поэтому должно быть так:

(Если вам нужен только один элемент, возвращаемый пользователем querySelector(), то цикл вам не нужен)

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>
...