为什么这个JavaScript函数在首次加载时没有正确计算,但之后工作正常?

时间:2014-07-31 20:00:20

标签: javascript php jquery html ajax

我正在开发一个网站,根据一些用户选择的参数为随机音乐节奏生成符号。它通过使用ajax调用来执行此操作,该调用返回表示不同注释的随机<img>元素集。我有一个功能,旨在缩放节奏以适应屏幕,无论它的实际大小。

在成功的ajax调用之后触发该函数,该调用由按钮上的单击事件触发。

我的问题是,在第一次加载页面时运行时,该功能无法正常工作。

首次运行该函数后,所有height元素的<img>属性都会以某种方式设置为0

但是,如果再次运行它(通过单击按钮),该功能可以正常工作。页面刷新后它也可以正常工作。

另外,我在IE11中没有这个问题,只有Chrome(我还没有测试过其他浏览器)。

我尝试在$(window).load()$(document).ready()事件处理程序中包装代码,但这没有帮助。

可以在http://www.rhythmrandomizer.com

找到可以使用的网站

非常感谢任何帮助!

以下是相关代码:

按钮的事件处理程序:

$("#randomize").click(function(){
    //get general options from form
    var timeSignature = $("#timeSignature").val();
    var phraseLength = $("#phraseLength").val();

    //get note options from form
    var checked = [];
    $("#noteOptions :checked").each(function() {
        checked.push($(this).val());
    });

    //alert user and exit function if nothing is selected
    if (checked.length < 1) {
        alert("Please select at least one note value");
        return;
    }


    //format note option ids into a delimited string
    var noteOptions = "";
    for (var i=0; i < checked.length; i++) {
        noteOptions += checked[i] + "a";
    }

    //remove the final comma and space
    noteOptions = noteOptions.substr(0, noteOptions.length - 1);

    //ajax call
    $.ajax("randomize.php", {
        data : {
            timeSignature : timeSignature,
            phraseLength : phraseLength,
            noteOptions : noteOptions
        },
        type : "GET",
        success : function(response) {
            $("#rhythm").html(response);
            scaleRhythm();
        },
        error : function(xhr, status, errorThrown) {
            console.log(status + " | " + errorThrown);
        }
    }); 
});

返回节奏符号的php文件:

<?php
//MySQL connection variables
$hostname = 'localhost';
$user = ini_get('mysqli.default_user');
$pw = ini_get('mysqli.default_pw');
$database = 'rhytxfpd_rhythmrandomizer';

//Connect to database
try {
    $db = new PDO('mysql:host=' . $hostname . ';dbname=' . $database,$user,$pw);
} catch(PDOException $e) {
    echo $e->getMessage();
    die();
}

//Get values from GET
$timeSignature = $_GET['timeSignature'];
$phraseLength = $_GET['phraseLength'];
$noteOptString = $_GET['noteOptions'];

//Split up note options string
$noteOptions = explode('a', $noteOptString);

//Create sql query
$sql = 'SELECT
            noteName,
            noteValue,
            noteGraphic
        FROM
            notes
        WHERE';

//append noteOptions as WHERE clauses
foreach ($noteOptions as $opt) {
    $sql = $sql . ' noteGroupID = ' . $opt . ' OR';
}

//remove final " OR"
$sql = substr($sql, 0, strlen($sql) - 3);

//query the database and get all results as an array
/* This will return a table with the name, graphic, and value of 
 * the notes that the user selected prior to submitting the form
 */
$stmt = $db->query($sql);
$result = $stmt->fetchAll();

//Get the total number of options selected
$numOpts = count($result);

/***************************/
/** BEGIN PRINTING RHYTHM **/
/***************************/

//div to begin the first measure
echo '<div class="measure" id="m1' . $measure . '">';

//Print time signature
echo '<img class="note" src="notes/' . $timeSignature . '.png" title="time signature ' . 
        $timeSignature . '/4" alt="time signature ' . $timeSignature . '/4"/>';

//Prints as many measures as indicated by the phrase length selection
$measure = 1;
while ($measure <= $phraseLength) {

    //begin a new div for other measures.
    if ($measure != 1) {
        echo '<div class="measure" id="m' . $measure . '">';
    }

    //Prints random measure according to time signature
    $beats = 0;
    while ($beats < $timeSignature) {
        //Generate a random number
        $random = rand(0, $numOpts - 1);

        //Get the random note from results
        $note = $result[$random];

        //Continues if chosen note will not fit in the measure
        if ($beats + $note['noteValue'] > $timeSignature) {
            continue;
        }

        //Prints random note
        echo '<img class="note" src="notes/' . $note['noteGraphic'] . '.png" title="' .
                $note['noteName'] . '" alt="' . $note['noteName'] . '"/>';

        //Adds random note's value to total number of beats
        $beats += $note['noteValue'];
        //$beats++;
    }

    //If last measure
    if ($measure == $phraseLength) {
        echo '<img class="note" src="notes/1.png" title="double barline" alt="double barline"/>';
        echo '</div>';
    } else {
        echo '<img class="note" src=notes/b.png title="barline" alt="barline"/>';
        echo '</div>';
    }

    //Increment to next measure
    $measure++;
}

scaleRhythm()函数:

function scaleRhythm() {
    //Get width of rhythm at full resolution
    var rhythmWidth = $("#rhythm").width();

    //Get current screen/window width
    var screenWidth = window.innerWidth;

    //Compute ratio between curren screen and window widths
    var ratio =   screenWidth / rhythmWidth;

    //Multiply img note height by ratio, then by 90% to provide some
    //breathing room on either side of the rhythm
    var newHeight = (400 * ratio) * .9;

    //Set img note height to new height or 300px, whichever is smaller
    if (newHeight < 300) {
        $(".note").css("height",newHeight);
        //code to center rhythm horizontally
        $("#rhythm").css("margin-top",(300-newHeight)/2);
    } else {
        $(".note").css("height",300);
        $("#rhythm").css("margin-top",0);
    }
}

3 个答案:

答案 0 :(得分:1)

将此javascript添加到<script></script>

$(function(){ $("#randomize").click(); });

这将导致您的页面运行填充随机元素的函数,然后(在该函数的末尾)运行缩放函数。

我通过在Chrome控制台的页面上运行它来测试它,它运行良好。

答案 1 :(得分:1)

如果您在scaleRhythm功能中放置了一个断点,您在页面加载时会注意到它没有被运行。您已定义了该功能,但未在页面加载时调用该功能。实际上,在第一次单击发生之前,不会调用您想要运行的代码(即:ajax调用)。所以你需要做的是触发按钮上的click事件,就像JRulle所说的那样。

$("#randomize").click();

答案 2 :(得分:0)

好的,这是你的问题。 第一次单击该按钮时,var rhythmWidth = $("#rhythm").width();的计算结果为“0”,因为它为空。

这导致这些后续功能也为“0”:

var ratio =   screenWidth / rhythmWidth;
var newHeight = (400 * ratio) * .9;

我会将你的功能编辑为:

var rhythmWidth = $("#rhythm").width();
if (rhythmWidth == 0) { rhythmWidth = 10; } //assign some reasonable value here

因为你的函数不支持rhythmWidth为“0”