1

这是我到目前为止的代码,目前它根据需要使用 javascript 从 xml 文件中加载信息。我已将其设置为循环 4 次以选择 4 个图像,但这些显然只是 xml 文件中的前 4 个。

有谁知道让它从 xml 文件中随机选择 4 个不重复的图像的最佳方法。

<script>
if (window.XMLHttpRequest)
    {// code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp=new XMLHttpRequest();
    }
else
    {// code for IE6, IE5
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.open("GET","include/photoLibrary.xml",false);
    xmlhttp.send();
    xmlDoc=xmlhttp.responseXML;

var x=xmlDoc.getElementsByTagName("photo");
    for (i=0; i<4; i++)
    { 
    document.write('<a href="');
    document.write(x[i].getElementsByTagName('path')[0].childNodes[0].nodeValue);
    document.write('" class="lytebox" data-lyte-options="group:vacation" data-title="');
    document.write(x[i].getElementsByTagName('description')[0].childNodes[0].nodeValue);
    document.write('"><img src="');
    document.write(x[i].getElementsByTagName('thumb')[0].childNodes[0].nodeValue);
    document.write('" alt"');
    document.write(x[i].getElementsByTagName('title')[0].childNodes[0].nodeValue);
    document.write('"/></a>');                      
    }
</script>

如果它有任何帮助,这是 xml 的一个例子,你会看到 photo 有一个属性,它给它一个唯一的 id。

<gallery>

<photo id="p0001">
<title>Pergola</title>
<path>photos/Pergola.jpg</path>
<thumb>photos/thumbs/Pergola.jpg</thumb>
<description>Please write something here!</description>
<date>
    <day>04</day>
    <month>04</month>
    <year>2006</year>
</date>
</photo>

</gallery>

我愿意使用 php 作为 javascript 的替代品。

4

4 回答 4

3

你可以添加

x = Array.prototype.slice.call(x).sort( function () {
    return Math.random() > 0.5 ? 1 : -1 
} );

紧接着

var x = xmlDoc.getElementsByTagName("photo");

这将创建一个随机排序的元素数组,其中前四个将由 for 循环迭代。

编辑

请注意,此方法不会产生正确随机的数组洗牌,请参阅使用 JavaScript Array.sort() 方法进行洗牌是否正确?,我不推荐它。

于 2013-02-02T23:49:33.240 回答
2

第一件事。尽量不要使用document.write这种方法,因为当 DOM 准备好和仍在初始化时,这种方法的行为会反复无常。它被认为是一种不好的做法。

我还建议使用函数来分解代码的复杂性并使其更具可读性。

您应该知道 XHR 对象不是同步的。您需要等待通过readystatechange事件检索 xml 数据。

最后,您不必在浏览器中构建 html 字符串。DOM API 允许您将锚点和图像标签创建为可以附加到 DOM 树的适当节点。

希望有帮助。

(function() {

    //fetch the gallery photos
    getXML('include/photoLibrary.xml', function(xml) {
        var photos, pI, photo, anchor, image, anchors = [];

        //pick four photos at random
        photos = getRandom(makeArray(xml.getElementsByTagName('photo')), 4);

        //build out each photo thumb
        for(pI = 0; pI < photos.length; pI += 1) {
            photo = photos[pI];

            //create the anchor
            anchor = document.createElement('a');
            anchor.setAttribute('href', photo.getElementsByTagName('path')[0].childNodes[0].nodeValue);
            anchor.setAttribute('class', 'lytebox');
            anchor.setAttribute('data-lyte-options', 'group:vacation');
            anchor.setAttribute('data-title', photo.getElementsByTagName('description')[0].childNodes[0].nodeValue);

            //create the image
            image = document.createElement('img');
            image.setAttribute('src', photo.getElementsByTagName('thumb')[0].childNodes[0].nodeValue);
            image.setAttribute('alt', photo.getElementsByTagName('title')[0].childNodes[0].nodeValue);

            //insert the image into the anchor
            anchor.appendChild(image);

            //insert the anchor into the body (change this to place the anchors else were)
            anchors.push(anchor);
        }

        //when the DOM is loaded insert each photo thumb
        bind(window, 'load', function() {
            var aI;

            for(aI = 0; aI < anchors.length; aI += 1) {
                //replace document.body with whatever container you wish to use
                document.body.appendChild(anchors[aI]);
            }
        });
    });

    /**
     * Fetches an xml document via HTTP method GET. Fires a callback when the xml data
     * Arrives.
     */
    function getXML(url, callback) {
        var xhr;

        if(window.XMLHttpRequest) {
            xhr = new XMLHttpRequest();
        } else if(window.ActiveXObject) {
            xhr = new ActiveXObject("Microsoft.XMLHTTP");
        } else {
            throw new Error('Browser does not support XML HTTP Requests.');
        }

        //attach the ready state hander and send the request
        xhr.onreadystatechange = readyStateHandler;
        xhr.open("GET","photos.xml",false);
        xhr.send();

        function readyStateHandler() {

            //exit on all states except for 4 (complete)
            if(xhr.readyState !== 4) { return; }

            //fire the callback passing the response xml data
            callback(xhr.responseXML);
        }
    }

    /**
     * Takes array likes (node lists and arguments objects) and converts them
     * into proper arrays.
     */
    function makeArray(arrayLike) {
        return Array.prototype.slice.apply(arrayLike);
    }

    /**
     * Extracts a given number of items from an array at random.
     * Does not modify the orignal array.
     */
    function getRandom(array, count) {
        var index, randoms = [];

        //clone the original array to prevent side effects
        array = [].concat(array);

        //pull random items until the count is satisfied
        while(randoms.length < count) {
            index = Math.round(Math.random() * (array.length - 1));
            randoms.push(array.splice(index, 1)[0]);
        }

        return randoms;
    }

    function bind(element, eventName, callback) {
        if(typeof element.addEventListener === 'function') {
            return element.addEventListener(eventName, callback, false);
        } else if(typeof element.attachEvent === 'function') {
            return element.attachEvent('on' + eventName, callback);
        }
    }
})();

编辑:修复了三个错误。在插入节点之前需要加载 DOM。XML 节点没有 innerHTML 属性。Array.concat 不会将 DOM NodeList 对象视为数组。

于 2013-02-03T00:52:22.820 回答
0

在 PHP 中,这是解析文件的方式:

索引.php

<?php
$doc = new DOMDocument();
  $doc->load( 'book.xml' );

  $books = $doc->getElementsByTagName( "book" );
  foreach( $books as $book )
  {
  $authors = $book->getElementsByTagName( "author" );
  $author = $authors->item(0)->nodeValue;

  $publishers = $book->getElementsByTagName( "publisher" );
  $publisher = $publishers->item(0)->nodeValue;

  $titles = $book->getElementsByTagName( "title" );
  $title = $titles->item(0)->nodeValue;

  echo "$title - $author - $publisher\n";
  }?>

书本.xml

<books>
  <book>
  <author>Jack Herrington</author>
  <title>PHP Hacks</title>
  <publisher>O'Reilly</publisher>
  </book>
  <book>
  <author>Jack Herrington</author>
  <title>Podcasting Hacks</title>
  <publisher>O'Reilly</publisher>
  </book>
  </books>
于 2013-02-02T23:50:26.717 回答
0

在php中你随机选择这样的东西

<?php

$xml_string = 
'<gallery>
<photo id="p0001">
<title>t1</title>
<path>photos/Pergola.jpg</path>
</photo>
<photo id="p0002">
<title>t2</title>
<path>photos/Pergola.jpg</path>
</photo>
<photo id="p0003">
<title>t3</title>
<path>photos/Pergola.jpg</path>
</photo>
</gallery>';

$xml  = simplexml_load_string($xml_string);
$arr = (array) $xml;
shuffle($arr['photo']);
for($i =0; $i < 2; $i++){
  $picture = array_pop($arr['photo']);
  print_r($picture);
}
于 2013-02-03T00:17:10.970 回答