【问题标题】:How to correctly handle a call function in a function with javascript如何使用javascript正确处理函数中的调用函数
【发布时间】:2016-09-10 15:28:09
【问题描述】:

我试图了解如何使用 javascript 处理一些事件,特别是如果触发了特定事件,则当前函数会调用另一个函数。在 onLoad 时,javascript 创建第一个从第一个对象中选择数据。然后,如果我选择值为“Iphone”的声音,则调用另一个函数来创建具有某些价格的第二个菜单。我的主要问题是我的解决方案看起来很丑陋,而且当我在按钮上单击多次时,它每次都会创建相同的第二次选择。

//global objects
var product = [
  {name: "Samsung"},
  {name: "Iphone"},
  {name: "Alcatel"},
  {name: "Sony"}
]

var productPrice = [
  {name: "Samsung", price: 190},
  {name: "Iphone", price: 290},
  {name: "Alcatel", price: 65},
  {name: "Sony", price: 330}
]

var main = function() {
  var sel = $('<select>').appendTo('#select-1');
  
  $(product).each(function() {
    sel.append($("<option>").attr('value', this.name).text(this.name));
  });
  
  $('.press').click(function() {
    if ($("#select-1 option:selected").text() == "Iphone") {
      handleEvent();
    }
    
    if ($("#select-1 option:selected").text() != "Iphone") {
      $("#risposta").remove();
    }
  });
}

function handleEvent() {
  var sel = $('<select>').appendTo('#select-2');
  
  $(productPrice).each(function() {
    sel.append($("<option>").attr('value', this.name).text(this.price));
  });
}

$(document).ready(function() {
  main();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="select-1">
</div>
<div id="select-2">
</div>
<button class="press">Click</button>

fiddle

有什么建议吗?

【问题讨论】:

  • 它创建另一个元素的原因是handleEvent()函数正在创建一个元素。
  • 并继续@JericCruz 的观点,您基本上有两个选择:1)始终在附加之前删除列表 2)切换可见性(例如 css 类)而不是附加
  • @Jeric Cruz 我知道,因为我声明的函数在每次第二次选择时都会创建。我已经想象过类似这段代码来处理这个事件,但它似乎不值得。如何更好地组织我的功能以避免这些事件问题?我的意思是只调用一次创建第二个选择的函数,当然当我点击其他选择值时删除它。
  • $("#select-1 option:selected") 可能需要是$("#select-1").find("select option:selected")
  • 这样的? jsfiddle.net/qu9zs2h1 ,只需确保尚未创建选择,只需使用类或 id 以确保尚未附加它

标签: javascript jquery object


【解决方案1】:

你的问题对我来说不是 100% 清楚,但是我想你想在 dom 准备好的事件上生成一个 select 标签,你已经有了。当您选择选项 iPhone 并点击 Click 按钮时,您希望使用变量中的新选项生成另一个 select 标记。

第一个选项

是我在下面提供的。它基本上是您的代码,但带有额外的 if 语句

jsFiddle 链接:https://jsfiddle.net/qu9zs2h1/2/

Javascript

//global objects
var product = [{
  name: "Samsung"
}, {
  name: "Iphone"
}, {
  name: "Alcatel"
}, {
  name: "Sony"
}]

var productPrice = [{
  name: "Samsung",
  price: 190
}, {
  name: "Iphone",
  price: 290
}, {
  name: "Alcatel",
  price: 65
}, {
  name: "Sony",
  price: 330
}]

var main = function() {
  var sel = $('<select>').appendTo('#select-1');

  $(product).each(function() {
    sel.append($("<option>").attr('value', this.name).text(this.name));
  });

  $('.press').click(function() {
    if ($("#select-1 option:selected").text() == "Iphone") {
      handleEvent();
    }

    if ($("#select-1 option:selected").text() != "Iphone") {
      $("#risposta").remove();
    }
  });
}

function handleEvent() {
  // We still run the handleEvent function however, if check to see
  // if the second select option has been generated by checking a 
  // class
  if (!$('.prices').length) {
    var sel = $('<select class="prices">').appendTo('#select-2');
    $(productPrice).each(function() {
      sel.append($("<option>").attr('value', this.name).text(this.price));
    });
  }
}

$(document).ready(function() {
  main();
});

HTML

<div id="select-1">
</div>
<div id="select-2">
</div>
<button class="press">Click</button>

我必须将 prices 类添加到您的第二个 select 中,但这只是一个您可以重命名的类,用于查看该元素是否已经存在。

第二种选择(可能是更好的方法)

您是否准备好在dom 上生成所有内容并在开始时隐藏您想要的内容,然后在需要时简单地show 元素,就像这样

jsFiddle:https://jsfiddle.net/qu9zs2h1/5/

Javascript

//global objects
var product = [{
  name: "Samsung"
}, {
  name: "Iphone"
}, {
  name: "Alcatel"
}, {
  name: "Sony"
}]

var productPrice = [{
  name: "Samsung",
  price: 190
}, {
  name: "Iphone",
  price: 290
}, {
  name: "Alcatel",
  price: 65
}, {
  name: "Sony",
  price: 330
}]

// On document ready run this script
$(function() {
    $('.jshidden').removeClass('jshidden').hide();

  var $select1 = $('#select-1');
  var $select2 = $('#select-2');
  var $sel1 = $('<select>').appendTo($select1);
  var $sel2 = $('<select>').appendTo($select2);

  $(product).each(function() {
    $sel1.append($("<option>").attr('value', this.name).text(this.name));
  });

  $(productPrice).each(function() {
    $sel2.append($("<option>").attr('value', this.price).text(this.price));
  });

  $('.press').click(function() {
    if ($select1.find(":selected").text() == "Iphone") {
      $select2.show();
    }

    if ($select1.find(":selected").text() != "Iphone") {
      $select2.hide();
    }
  });
});

HTML

<div id="select-1">
</div>
<div id="select-2" class="jshidden">
</div>
<button class="press">Click</button>

附:只是一点点,任何引用变量的东西都是 jQuery 元素应该以 $ 开头,它只是有助于阅读代码。

只是一个快速更新,你也可以用这个代码减少.press代码

$('.press').click(function() {
  var iPhoneCheck = $select1.find(":selected").text() == "Iphone";
    $select2.toggle(iPhoneCheck);
  });

jQuery.toggle 接受一个布尔值来显示目标或隐藏目标

【讨论】:

  • 谢谢@Canvas,这两种解决方案都很好!因此,在第二个版本中,您已经简化并用更具体的 if 语句替换了 call 函数。您认为哪个是代码结构的最佳选择?
  • 第二个选项是最好的选项,因为您不再修改dom。此外,如果提供的任何答案是正确的,请务必勾选答案
【解决方案2】:

//global objects
var product = [
  {name: "Samsung"},
  {name: "Iphone"},
  {name: "Alcatel"},
  {name: "Sony"}
];

var productPrice = [
  {name: "Samsung", price: 190},
  {name: "Iphone", price: 290},
  {name: "Alcatel", price: 65},
  {name: "Sony", price: 330}
];

var main = function() {
  var sel = $('<select>').appendTo('#select-1');
  $(product).each(function() {
    sel.append($("<option>").attr('value', this.name).text(this.name));
  });
  
  $('.press').click(function() {
    var sel2 = document.getElementById('select-2');
    var selectedOption = $("#select-1 option:selected").text();
    if (selectedOption == "Iphone") {
      // check if the select was already added
      if(sel2.children.length == 0)
        handleEvent();
    }
    else {
      // I think here you wanted to remove the second select that was added for iphone option
      sel2.innerHTML = '';
    }
  });
}

function handleEvent() {
  var sel = $('<select>').appendTo('#select-2');
  $(productPrice).each(function() {
    sel.append($("<option>").attr('value', this.name).text(this.price));
  });
}

// if you already have a declared function, there is no need to an anonymous function
// just call the main function directly
$(document).ready(main);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="select-1">
</div>
<div id="select-2">
</div>
<button class="press">Click</button>

【讨论】:

  • 您缺少 javascript 和 jquery dom 选择器有什么原因吗?你可以只使用$,同时删除选择并重新附加它是愚蠢的,你应该检查长度,如果它存在则什么都不做
  • 我只是没有意识到我正在混合两个选择器,只是没有注意,没有特殊原因。我删除了附加的选择,因为我假设在第一个选择(三星,acatel,索尼)中选择了另一个选项时,应该删除附加的选择,因为在问题的 sn-p 中有一行代码试图做类似的东西。 ($("#risposta").remove();)
  • 好的,我已经意识到我错过的逻辑:我忘记为添加/删除第二个选择做出正确的 if 语句。所以你已经声明了 sel2 并且你已经用他的 children.length 控制了 #se​​lect-2 是否为空。那很好!对于改进和最小化当前代码有什么建议吗?再次感谢你们!
  • 有些东西我不明白。当我选择“Iphone”(190、290、65、330)时附加的所有价格。他们真的应该被添加吗?或者只是 290 这就是 Iphone 的价格?一个建议是您不需要这两个对象:product 和 productPrice。 “productPrice”已经拥有你所需要的一切。如果您真的需要按照我的要求附加所有价格,您只需在 productPrice 对象的 price 属性中使用一个数组。
  • 感谢@jplobianco 的建议,我将只使用一个对象。
猜你喜欢
  • 2020-09-27
  • 2018-05-02
  • 1970-01-01
  • 2020-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多