我正在读取服务器上的短文本文件到PHP变量($data
),并首先访问数组中的前2项以显示它们。
然后当用户单击其中一个项目(也发送表单数据)时,我想增加指定数组项目($counter
)的PHP变量。
从文件中读取似乎是最容易的PHP,但增量在点击似乎更容易与Javascript -我不能找出一个好方法来锻造两者。解决这个问题的最好方法是什么?我对这两种语言都很陌生。
从文件中读取的php/html代码(工作):
<?php
function getData($subtest_nr) {
$data = file("subtests/$subtest_nr.txt");
return $data;
}
$subtest_nr = "7";
$counter = 0;
$data = getData($subtest_nr); ?>
<form id="myform" method="post">
<div class="four_images">
<div class="flex-item">
<input type="radio" name="image" value="7.11" id="alt1" class="hidden">
<label for="alt1"><img src="images/<?php echo $data[$counter]; ?>"></label>
</div>
<div class="flex-item">
<input type="radio" name="image" value="7.12" id="alt2" class="hidden">
<label for="alt2"><img src="images/<?php echo $data[$counter+1] ?>"></label>
</div>
</div>
</form>
jQuery中变量递增的快速尝试:
jQuery(function($) {
var counter = 0;
$("img").click(function(){
counter++;
$("p").text(counter);
});
});
所以我的问题是,如果我应该瞄准要么只有PHP或Javascript/jQuery的两个功能,或者如果有一种方法让我合并两者?
除了这些注释之外,这里还有一种将字体前端和后端合并到一个文件中的方法。
文件使用$_SERVER['PHP_SELF']变量来查找正在执行的文件的名称。我们使用它来将请求的后端php文件的正确名称写入javascript中——这使得我们可以为单文件解决方案命名任何我们想要的名称,而不必担心在源代码的某个地方更新硬编码的url。头疼吗?: p)
index . php
<?php
if ( isset($_GET['firstItem']) && isset($_GET['numItems']) )
{
$firstItem = $_GET['firstItem'];
$numItems = $_GET['numItems'];
// should do error checking here
$subtestNumber = 7;
$filename = sprintf("subtests/%d.txt", $subtestNumber);
// dummy, used for testing
$filename = 'sampleInput.txt';
$fileHandle = fopen($filename, "rt");
for ($numLinesToSkip=0; $numLinesToSkip<$firstItem; $numLinesToSkip++)
fgets($fileHandle);
$results = array();
for ($itemCount=0; $itemCount<$numItems; $itemCount++)
{
$curLine = fgets($fileHandle);
//
// you may wish to remove the trailing new-line character here
//
array_push($results, $curLine);
}
fclose($fileHandle);
echo json_encode($results);
die; // stop execution now - dont output the html below
}
?><!doctype html>
<html>
<head>
<script>
"use strict";
function newEl(tag){return document.createElement(tag)}
function byId(id){return document.getElementById(id)}
// useful for HtmlCollection, NodeList, String types
function forEach(array, callback, scope){for (var i=0,n=array.length; i<n; i++)callback.call(scope, array[i], i, array);} // passes back stuff we need
function ajaxGet(url, onLoad, onError)
{
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function(){if (this.readyState==4 && this.status==200) onLoad(this);}
ajax.onerror = function() {error.log("ajax request failed to: "+url);onError(this);}
ajax.open("GET", url, true);
ajax.send();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
byId('goBtn').addEventListener('click', onGoBtnClicked);
}
function onGoBtnClicked(evt)
{
var firstIndex = byId('firstRecordInput').value;
var numItems = byId('numRecordsInput').value;
// we want to request data from this same file, so get php to print it into the javascript source
var filename = '<?php echo $_SERVER['PHP_SELF'];?>';
// construct the url from the filename and the (GET) parameters we'd like to pass to the php
var url = filename + '?firstItem=' + firstIndex + '&numItems=' + numItems;
// ask for it, fire the onDataReceived function with the XMLHttpRequest object as the only input
ajaxGet(url, onDataReceived, function(){alert('ajax failed! :(');} )
}
/*
------------------------------------------------------------
format of html the onDataReceived function needs to create
- .four_images div just once for the whole response
- .flex-item once for each item returned
------------------------------------------------------------
<div class="four_images">
<div class="flex-item">
<input type="radio" name="image" value="7.11" id="alt1" class="hidden">
<label for="alt1"><img src="images/<?php echo $data[$counter]; ?>"></label>
</div>
<div class="flex-item">
<input type="radio" name="image" value="7.12" id="alt2" class="hidden">
<label for="alt2"><img src="images/<?php echo $data[$counter+1] ?>"></label>
</div>
</div>
*/
function onDataReceived(ajax)
{
// get the raw data - it'll be a string something like `["file1.txt'n","file2.swf'n"]`
var rawData = ajax.response;
// parse it and turn it from a string into some javascript objects.
// this has same the effect as typing the following into your source-code
//
// var parsedData = [ "file1.txt'n", "file2.swf'n" ];
//
// except, you can do it with unknown data. BUT: we must know the *format*
// of the data so we know what to do with it. We happen to know that
// the data will be an array
var parsedData = JSON.parse(rawData);
// make the outer wrapper - refer above for the structure of the created HTML
// this wrapper needs to exist so the makeItem function can append content
// to it in the forEach call
var div = newEl('div');
div.className = 'four_images';
// for each of the items in the parsedData array, call the makeItem function - once this forEach call is done,
// we have the contents of the form all sitting in the [div] element - the makeItem function is inside this onDataReceived function
// so that it can 'see' the [div] variable in order to append each item to it.
forEach(parsedData, makeItem);
// show the results
byId('myForm').innerHTML = '';
byId('myForm').appendChild(div);
// this function has now finished executing. the makeItem function exists here (unfortunately) so that
// the [div] element remains in scope.
// called with the current element in the collection as dataItem, it's index in the collection as index and the collection itself as arrayOfItems
// we're making use of the item's index to correctly set the id of the radio-button and then to make the label refer to it (which it doesn't actually
// need to do in this case, since the label element contains the input)
// another use of index is to place a comma between items i.e "1,2,3,4,5,6" - there are two approaches. The naive one is to place a comma after each
// item except the last one. To do this - we need to know how many items there are in total - sometimes this is very expensive to compute.
// the other approach, is to put a comma _before_ all items except the first one.
function makeItem(dataItem, index, arrayOfItems)
{
var itemDiv = newEl('div');
itemDiv.className = 'flex-item';
var input = newEl('input');
input.type = 'radio';
input.name = 'image';
input.value = 'putSomethingUsefulHere'; // **** the example had 7.11 and 7.12 here - I've no idea how they were determined ***
input.id = "alt" + (index+1);
input.className = 'hidden';
var label = newEl('label');
label.for = 'alt' + (index+1);
var img = newEl('img');
img.src = 'images/' + dataItem;
label.appendChild(img);
itemDiv.appendChild(input);
itemDiv.appendChild(label);
div.appendChild(itemDiv);
}
}
</script>
<style>
.panel
{
border: solid 1px black;
border-radius: 8px;
padding: 8px;
background-color: #eef;
display:inline-block;
}
</style>
</head>
<body>
<div class='panel'>
<label>Index of first record: <input type='number' id='firstRecordInput' value='0'/></label><br>
<label>Number of records: <input type='number' id='numRecordsInput' value='2'/></label>
<hr>
<div style='text-align: center'><button id='goBtn'>Retrieve records</button></div>
<hr>
<form id='myForm'>
</form>
</div>
</body>
</html>
这里有一个粗略的示例,没有错误检查。我不使用jQuery,所以您需要将其转换为使用jQuery的ajax方法。不能告诉你想要达到的每一张图片点击,所以你可以编辑回来。
我的主要目的是展示一种方法,通过这种方法,前端可以维护状态信息,并可以使用它从(哑)后端请求所需的信息。
sampleInput.txt
file1.txt
file2.swf
file1.pdf
file1.exe
file1.asm
getItems.php
<?php
$firstItem = $_GET['firstItem'];
$numItems = $_GET['numItems'];
// should do error checking here
$subtestNumber = 7;
$filename = sprintf("subtests/%d.txt", $subtestNumber);
// dummy, used for testing
$filename = 'sampleInput.txt';
$fileHandle = fopen($filename, "rt");
for ($numLinesToSkip=0; $numLinesToSkip<$firstItem; $numLinesToSkip++)
fgets($fileHandle);
$results = array();
for ($itemCount=0; $itemCount<$numItems; $itemCount++)
{
$curLine = fgets($fileHandle);
//
// you may wish to remove the trailing new-line character here
//
array_push($results, $curLine);
}
fclose($fileHandle);
echo json_encode($results);
?>
getStuff.html
<!doctype html>
<html>
<head>
<script>
"use strict";
function newEl(tag){return document.createElement(tag)}
function byId(id){return document.getElementById(id)}
// useful for HtmlCollection, NodeList, String types
function forEach(array, callback, scope){for (var i=0,n=array.length; i<n; i++)callback.call(scope, array[i], i, array);} // passes back stuff we need
function ajaxGet(url, onLoad, onError)
{
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function(){if (this.readyState==4 && this.status==200) onLoad(this);}
ajax.onerror = function() {error.log("ajax request failed to: "+url);onError(this);}
ajax.open("GET", url, true);
ajax.send();
}
/////////////////////
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
byId('goBtn').addEventListener('click', onGoBtnClicked);
}
function onGoBtnClicked(evt)
{
var firstIndex = byId('firstRecordInput').value;
var numItems = byId('numRecordsInput').value;
var url = 'getItems.php?firstItem=' + firstIndex + '&numItems=' + numItems;
ajaxGet(url, onDataReceived, function(){alert('ajax failed! :(');} )
}
/*
<div class="four_images">
<div class="flex-item">
<input type="radio" name="image" value="7.11" id="alt1" class="hidden">
<label for="alt1"><img src="images/<?php echo $data[$counter]; ?>"></label>
</div>
<div class="flex-item">
<input type="radio" name="image" value="7.12" id="alt2" class="hidden">
<label for="alt2"><img src="images/<?php echo $data[$counter+1] ?>"></label>
</div>
</div>
*/
function onDataReceived(ajax)
{
var rawData = ajax.response;
var parsedData = JSON.parse(rawData);
var div = newEl('div');
div.className = 'four_images';
forEach(parsedData, makeItem);
byId('myForm').innerHTML = '';
byId('myForm').appendChild(div);
function makeItem(dataItem, index, arrayOfItems)
{
var itemDiv = newEl('div');
itemDiv.className = 'flex-item';
var input = newEl('input');
input.type = 'radio';
input.name = 'image';
input.value = 'putSomethingUsefulHere';
input.id = "alt" + (index+1);
input.className = 'hidden';
var label = newEl('label');
label.for = 'alt' + (index+1);
var img = newEl('img');
img.src = 'images/' + dataItem;
label.appendChild(img);
itemDiv.appendChild(input);
itemDiv.appendChild(label);
div.appendChild(itemDiv);
}
}
</script>
<style>
.panel
{
border: solid 1px black;
border-radius: 8px;
padding: 8px;
background-color: #eef;
display:inline-block;
}
</style>
</head>
<body>
<div class='panel'>
<label>Index of first record: <input type='number' id='firstRecordInput' value='0'/></label><br>
<label>Number of records: <input type='number' id='numRecordsInput' value='2'/></label>
<hr>
<div style='text-align: center'><button id='goBtn'>Submit</button></div>
<hr>
<form id='myForm'>
</form>
</div>
</body>
</html>
我猜你得到的数据是ajax数据。所以需要输入$(document).on(…
var counter = 0;
$(document).on('click','img', function(){
counter++;
$("p").text(counter);
});