【问题标题】:Modify elements position and rotation before appending在追加之前修改元素的位置和旋转
【发布时间】:2012-07-27 05:35:39
【问题描述】:

我是一个绝望的 javascript 新手,我正在尝试将动态创建的图像元素插入到 DOM 中,同时随机定位和旋转它们。

目前我基本上是这样做的:

  1. 创建一个包含所有图像文件路径的数组
  2. 使用动态创建的名称创建一个 div 并插入到 DOM 中
  3. 生成 20 个不同的图像实例并插入 DOM 到相应的 div 中
  4. 随机旋转每个图像并随机定位每个图像。对于旋转,我使用 jQuery 旋转插件。

我觉得我做这一切的方式非常愚蠢,因为我首先将元素插入 DOM,然后操纵它们的位置和旋转。

有没有办法先在虚拟内存中做所有事情,最后在所有操作都完成后将元素插入到 DOM 中?

这是我当前的代码(对于菜鸟的质量感到抱歉):

$(document).ready(function(){

var wrapper = $('#wrapper'),


function movieCreator(movieName, generateAmount){

var contents=new Array (

'<img class="film '+movieName+'" src="images/'+movieName+'01.png" alt="'+movieName+'" />',

'<img class="film '+movieName+'" src="images/'+movieName+'02.png" alt="'+movieName+'" />',

'<img class="film '+movieName+'" src="images/'+movieName+'03.png" alt="'+movieName+'" />',

'<img class="film '+movieName+'" src="images/'+movieName+'04.png" alt="'+movieName+'" />',

'<img class="film '+movieName+'" src="images/'+movieName+'05.png" alt="'+movieName+'" />',

'<img class="film '+movieName+'" src="images/'+movieName+'06.png" alt="'+movieName+'" />',

'<img class="film '+movieName+'" src="images/'+movieName+'07.png" alt="'+movieName+'" />'   

);

var tmp='';
var dynamicIdName = 'box'+movieName;
var dynamicIdCall = '#box'+movieName;
wrapper.append("<div id='"+dynamicIdName+"' class='moviebox'></div>");


var random
for (i=0; i < generateAmount;){
random = Math.floor(Math.random()*contents.length);
tmp += contents[random];
i++
};

$(dynamicIdCall).append(tmp);

$(".film").each(function(){ 
    randomrot = Math.floor(Math.random()*360); 
    randomposX = Math.floor(Math.random()*200); 
    randomposY = Math.floor(Math.random()*200); 
    $(this).rotate(randomrot);
    $(this).css({'top': randomposY -40});
    $(this).css({'left': randomposX -40});

});


    wrapper.on('click','.film',function(){
    imageControl(this);
    });



} //end movieCreator

    movieCreator('terminator', 20);
    movieCreator('rambo', 20);
    movieCreator('godfather', 20);
    movieCreator('matrix', 20);
    movieCreator('kingkong', 20);


}); //dom ready

【问题讨论】:

  • JavaScript 已经在使用内存客户端,但是在元素以一种或另一种方式出现在页面上之前,无论是在加载时还是在通过 JavaScript 呈现之后,您才能操作它们,直到它们存在以某种形状或形式的 DOM。也就是说,您的实际问题是什么,这不是加载吗?打破?走很长的路?冻结浏览器?其他的?
  • 它不是虚拟内存,但是你可以创建一个与 DOM 分离的 DOM 元素,然后在上面做任何你喜欢的事情。如果您使用 jQuery 创建元素,您可以获得包裹在 jQuery 中的元素,您可以在其中应用 jQuery 函数。但是无法完成需要元素在布局中的功能,例如获取元素的高度。应用 CSS 会起作用,不确定是否可以旋转,如果只是设置 CSS 应该也可以。
  • @chris 我想问题是我当前的代码花费了太长时间。客户可以清楚地看到正在创建和操作的元素。我试图应用这些 $(this).rotate(randomrot); $(this).css({'top': randomposY -40}); $(this).css({'left': randomposX -40});到“tmp”变量而不是获取 $('.film') 类,但这导致控制台错误,告诉图像元素没有旋转方法。
  • 好吧,我不会说您没有太多事情要做,您是否考虑过使用您需要的属性在服务器端渲染图像,类似于您现在仅使用 javascript 的方式。也许通过首先将图像加载到 DOM 中然后对它们调用旋转可能会加快速度。

标签: javascript jquery


【解决方案1】:

我试图在这里涵盖很多东西......

你有一个意想不到的,

var wrapper = $('#wrapper'),
                        ---^

您可以使用[] 代替new Array()

var contents = [ ... ]

小心,i 是全局的,请使用 var。此外,您可以将i++ 移动到for 循环:

for (var i = 0; i < generateAmount; i++){
   ---^---                       ---^---

这些是初学者常见的错误。尝试首先掌握这些概念,然后如果您想要最佳性能,最后添加所有内容。然后您可以将所有内容重构为此,我评论了几件事:

var $wrap = $('#wrapper')

var movieCreator = function (name, ammount) {

  // Utility function to keep it DRY
  var rand = function (len) {
    return ~~(Math.random() * len) // ~~ trick Math.floor
  }

  // Cache your container in a variable
  var $container = $('<div/>', {
    id: 'box' + name,
    'class': 'moviebox'
  })

  // Generate iamges with an array
  // to keep it DRY
  var imgs = []
  for (var i = 0; i < 7; i++) {
    imgs.push(
      '<img ' +
      'class="film '+ name +'"'+
      'src="images/'+ name +'0'+ i + '.png"'+ // If no with more than 10...
      'alt="'+ name +'"'+
      '/>'
    )
  }

  var randImgs = []
  for (var i = 0; i < ammount; i++)
    randImgs.push(imgs[rand(imgs.length)])

  // Attach events before inserting in DOM
  // that way you don't need delegation with on()
  var $imgs = $(randImgs.join(''))
  $imgs
  .click(function(){
    imageControl(this)
  })
  .each(function(){
    var rot = rand(360),
        posX = rand(200),
        posY = rand(200)
    $(this)
      .css({
        top: posY - 40 + 'px', // use units (px, em)
        left: posX - 40 + 'px'
      })
      .rotate(rot)
  })

  // Finally insert in DOM. It already has
  // all events attached and position changed
  $wrap.append($container.append($imgs))
}

【讨论】:

  • 非常感谢您的热心帮助!并花时间解释这些事情。我现在就去尝试插入改进后的代码,看看它是否有效!
  • 我改变了一些东西,但我建议不要复制/粘贴,而是自己编写并尝试每一段代码,看看它做了什么。那里可能有很多新概念。
  • 完成测试,它可以工作了!这是一个很大的进步,感谢您对我的教育!我从代码中不明白一件事:为什么要使用美元符号 var $container 创建容器变量? just var container 有什么区别?
  • 顺便说一句,我只是觉得我必须对你的回答表示敬畏。你到底怎么能接受一个新手写的这么复杂的代码,并这么快理解它的逻辑呢?这对我来说真的很棒!您已经编写了多少年的代码才能做到这一点? :D
  • 我也是新手,犯过这些错误。当您了解该语言的真正工作原理时,就很容易像这样重构代码。对于您的问题,美元符号只是提醒您该变量是一个 jQuery 对象。在实践中没有区别。
猜你喜欢
  • 2015-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-12
  • 1970-01-01
  • 2018-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多