如何将 JavaScript 的范围设置为部分视图?

Posted

技术标签:

【中文标题】如何将 JavaScript 的范围设置为部分视图?【英文标题】:How do I set JavaScript's scope to partial view? 【发布时间】:2020-08-30 06:42:09 【问题描述】:

我有一个 ASP.NET 部分视图

<div class="wrapper">
    <div class="remove-item"></div>        
    <input name="Account" class="currency" />
     ...some more html input elements removed for brevity
</div>

局部视图有自己的 javascript

<script type="text/javascript">
    $(function()
       $(".remove-item").click(function()
          var i =  $("input.currency");
          // do something
       )   


    )
</script> 

在一个页面上,这个局部视图会出现多次。每个input 元素都有唯一的名称。然而 JavaScript 使用类名选择元素。

问题是当局部视图的第二个实例呈现时,$(".remove-item") 也会从第一个局部视图中选择元素。因为它会扫描整个 DOM。

在这里设置 JavaScript 范围的最佳方法是什么,以便它只选择具有自己范围的元素?


只选择元素

【问题讨论】:

仅供参考,将 JavaScript 放在每个局部视图中会减慢您的初始渲染速度。 HTML解析器必须切换到JS引擎,加载&解析&运行JS,然后每次遇到&lt;script&gt;标签时切换回HTML解析器。如果代码始终相同(即,您不会将服务器端代码写入每个脚本),只需将其放入外部文件并加载一次即可。 【参考方案1】:

当处理未知数量的重复元素时,您可以使用事件委托。与其多次输出 JS 并在每个部分上都有一个事件侦听器,不如输出一次,并且整个部分集只有一个事件。无论页面上最终有多少元素,即使动态显示更多元素,您的事件仍然会触发:

    仅输出此 JavaScript 一次:
<script type="text/javascript">
    $(".containing-parent").on('click', '.remove-item', function() 
        var i = $(this).closest('.wrapper').find('input.currency');
    );
</script>
    使用可以附加一个事件的 div 包装您的部分:
<div class="containing-parent">
    ...partials go here
</div>

您需要确保您的 javascript 在执行时可以找到 div.containing-parent

示例:

$(".containing-parent").on('click', '.remove-item', function() 
  var i = $(this).closest('.wrapper').find('input.currency').val();
  console.log(i);
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="containing-parent">
  <div class="wrapper">
    <div class="remove-item">X</div>
    <input name="Account1" class="currency" value="1" />
  </div>
  <div class="wrapper">
    <div class="remove-item">X</div>
    <input name="Account2" class="currency" value="2" />
  </div>
  <div class="wrapper">
    <div class="remove-item">X</div>
    <input name="Account3" class="currency" value="3" />
  </div>
</div>

【讨论】:

很好,我不使用 jquery,但它看起来很干净。【参考方案2】:

最好的方法是创建一个模块。

// Module

function PartialView(root) 
  var button = root.querySelector('button');
  
  button.addEventListener('click', remove);
  
  
  function remove() 
    button.removeEventListener('click', remove);
    root.remove();
  
  


// Attaching listeners

Array.from(document.querySelectorAll('.partial-view'))
  .forEach(PartialView);
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <div class="partial-view">
    <button>remove</button>
    <input type="text" />
  </div>
  <div class="partial-view">
    <button>remove</button>
    <input type="text" />
  </div>
  <div class="partial-view">
    <button>remove</button>
    <input type="text" />
  </div>
  <div class="partial-view">
    <button>remove</button>
    <input type="text" />
  </div>
  <div class="partial-view">
    <button>remove</button>
    <input type="text" />
  </div>
</body>
</html>

【讨论】:

那不是模块;那是一个闭包,或者一个对象。 Modules 是 JavaScript 中的特定事物。 root 是如何传递的,root 参数的值是多少? @HereticMonkey 我明白你的意思了,我实现的是一种设计模式,称为显示模块模式 @LP13 forEach 使用 PartialView 作为回调,它负责注入它。 实际上,RMP 会返回在外部函数中构建的对象,但可以肯定。【参考方案3】:

你可以给包含局部视图的 div 一个唯一 ID

<div class="wrapper" id="partialViewHandler">

然后在您的 Javascript 上首先找到 ContainerDiv 并将值存储在一个参数中并在您的 JQuery 选择器中使用它。

<script type="text/javascript">
    var x = $("#partialViewHandler");
    $(function () 
        $(".remove-item", x).click(function () 
            var i = $("input.currency", x);
            // do something
        )
    )
</script>

【讨论】:

以上是关于如何将 JavaScript 的范围设置为部分视图?的主要内容,如果未能解决你的问题,请参考以下文章

如何在其父视图范围之外启用视图的触摸?

如何将整个标题视图设置为 UICollectionView?

如何根据javascript中的系统范围主题将道具发送到变量?

(iphone)将子视图的框架设置在超视图的范围之外?

UITableViewCell未选中时如何将其背景视图设置为选中的背景?

如何正确渲染部分视图,并使用 Express/Jade 在 AJAX 中加载 JavaScript 文件?