如何针对特定屏幕尺寸使用 knockout 和 i18next?
How to use knockout and i18next for a specfic screen size?
我有一个 HTML:
<div class="inter">
<!-- ko if:emprel_id -->
<!-- ko i18n:'dependents.editDependent' --><!-- /ko -->
<!-- /ko -->
<!-- ko if:emprel_id -->
<!-- ko i18n:'dependents.DependentInformation' --><!-- /ko -->
<!-- /ko -->
</div>
JS文件的片段"en-CA"是:
"dependents.editDependent": "Edit",
"dependents.DependentInformation": "Dependent Information",
此刻,在 front-end 我可以在桌面视图中看到以下内容:
我的任务是:
767 像素屏幕尺寸后,我只想显示 "Edit" 代替 "Edit Dependent Information"
此外,在320像素和767像素之间(这是移动视图),我只想要"Dependent Information"
我可以通过 HTML 和 CSS 实现,但我想知道如何通过 JS(knockout) 实现它。
响应式布局最好通过 CSS 实现。
如果绝对必要,您可以将其硬塞进淘汰赛,但我不确定是否值得麻烦。
在最简单的形式中,您可以订阅 resize
事件并将 window 宽度写入可观察对象:
function Demo() {
var self = this;
self.windowWidth = ko.observable(window.innerWidth);
self.isWideLayout = ko.computed(function () {
return self.windowWidth() >= 767;
});
}
var vm = new Demo();
ko.utils.registerEventHandler(window, 'resize', function () {
vm.windowWidth(window.innerWidth); // or whatever value you want to use
})
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="text: windowWidth"></div>
<div>wide layout? <span data-bind="text: isWideLayout"></span></div>
下一步可能是做这样的事情:
<div class="inter">
<!-- ko if:emprel_id -->
<!-- ko i18n: $root.isWideLayout() ? 'string1' : 'string2' --><!-- /ko -->
<!-- /ko -->
</div>
您可以使用 matchMedia
使 observable
状态保持最新。然后,您可以在计算的 属性 中使用此状态,该状态要么翻译文本,要么隐藏 DOM.
中的元素
在这个例子中,我做了两件事:(要测试,按整页并调整大小)
- 通过 observables
isSmall
、isMedium
和 isLarge
跟踪 "width state"
- 在视图模型中创建一组计算属性,将此状态考虑在内并进行相应更新
在代码中,可以看到两种做法:
- 根据宽度状态在视图模型中进行翻译
- 在视图中平移,根据宽度状态隐藏
在这两种情况下,视图模型都包含从特定状态转换为特定字符串组合的逻辑。
// Keep track of state
var small = window.matchMedia("(max-width: 320px)");
var medium = window.matchMedia("(min-width: 321px) and (max-width: 768px)");
var large = window.matchMedia("(min-width: 769px)");
var isSmall = ko.observable(small.matches);
var isMedium = ko.observable(medium.matches);
var isLarge = ko.observable(large.matches);
var onChange = function() {
isSmall(small.matches);
isMedium(medium.matches);
isLarge(large.matches);
}
small.addListener(onChange);
medium.addListener(onChange);
large.addListener(onChange);
// VM
function ViewModel() {
// For option 1
this.translatedLabel = ko.pureComputed(function() {
if (isSmall()) return i18nextko.t("dependents.editDependent");
if (isMedium()) return i18nextko.t("dependents.DependentInformation");
if (isLarge()) return i18nextko.t("dependents.editDependent") +
" " + i18nextko.t("dependents.DependentInformation");
}, this);
// For option 2
this.showLeft = ko.pureComputed(function() {
return !isMedium();
}, this);
this.showRight = ko.pureComputed(function() {
return !isSmall();
}, this);
}
// Mock
var i18nextko = {
t: function(key) {
switch (key) {
case "dependents.editDependent":
return "Edit";
case "dependents.DependentInformation":
return "Dependent Information";
}
}
};
ko.bindingHandlers.i18n = {
init: function(e, valueAccessor) {
e.innerText = i18nextko.t(valueAccessor());
},
}
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<h2>Via computed</h2>
<div data-bind="text: translatedLabel"></div>
<h2>Via visible binding</h2>
<span data-bind="i18n: 'dependents.editDependent', visible: showLeft"></span>
<span data-bind="i18n: 'dependents.DependentInformation', visible: showRight"></span>
我很想知道为什么你宁愿在 javascript 中而不是在 HTML + CSS 中这样做...
我有一个 HTML:
<div class="inter">
<!-- ko if:emprel_id -->
<!-- ko i18n:'dependents.editDependent' --><!-- /ko -->
<!-- /ko -->
<!-- ko if:emprel_id -->
<!-- ko i18n:'dependents.DependentInformation' --><!-- /ko -->
<!-- /ko -->
</div>
JS文件的片段"en-CA"是:
"dependents.editDependent": "Edit",
"dependents.DependentInformation": "Dependent Information",
此刻,在 front-end 我可以在桌面视图中看到以下内容:
我的任务是:
767 像素屏幕尺寸后,我只想显示 "Edit" 代替 "Edit Dependent Information"
此外,在320像素和767像素之间(这是移动视图),我只想要"Dependent Information"
我可以通过 HTML 和 CSS 实现,但我想知道如何通过 JS(knockout) 实现它。
响应式布局最好通过 CSS 实现。
如果绝对必要,您可以将其硬塞进淘汰赛,但我不确定是否值得麻烦。
在最简单的形式中,您可以订阅 resize
事件并将 window 宽度写入可观察对象:
function Demo() {
var self = this;
self.windowWidth = ko.observable(window.innerWidth);
self.isWideLayout = ko.computed(function () {
return self.windowWidth() >= 767;
});
}
var vm = new Demo();
ko.utils.registerEventHandler(window, 'resize', function () {
vm.windowWidth(window.innerWidth); // or whatever value you want to use
})
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="text: windowWidth"></div>
<div>wide layout? <span data-bind="text: isWideLayout"></span></div>
下一步可能是做这样的事情:
<div class="inter">
<!-- ko if:emprel_id -->
<!-- ko i18n: $root.isWideLayout() ? 'string1' : 'string2' --><!-- /ko -->
<!-- /ko -->
</div>
您可以使用 matchMedia
使 observable
状态保持最新。然后,您可以在计算的 属性 中使用此状态,该状态要么翻译文本,要么隐藏 DOM.
在这个例子中,我做了两件事:(要测试,按整页并调整大小)
- 通过 observables
isSmall
、isMedium
和isLarge
跟踪 "width state"
- 在视图模型中创建一组计算属性,将此状态考虑在内并进行相应更新
在代码中,可以看到两种做法:
- 根据宽度状态在视图模型中进行翻译
- 在视图中平移,根据宽度状态隐藏
在这两种情况下,视图模型都包含从特定状态转换为特定字符串组合的逻辑。
// Keep track of state
var small = window.matchMedia("(max-width: 320px)");
var medium = window.matchMedia("(min-width: 321px) and (max-width: 768px)");
var large = window.matchMedia("(min-width: 769px)");
var isSmall = ko.observable(small.matches);
var isMedium = ko.observable(medium.matches);
var isLarge = ko.observable(large.matches);
var onChange = function() {
isSmall(small.matches);
isMedium(medium.matches);
isLarge(large.matches);
}
small.addListener(onChange);
medium.addListener(onChange);
large.addListener(onChange);
// VM
function ViewModel() {
// For option 1
this.translatedLabel = ko.pureComputed(function() {
if (isSmall()) return i18nextko.t("dependents.editDependent");
if (isMedium()) return i18nextko.t("dependents.DependentInformation");
if (isLarge()) return i18nextko.t("dependents.editDependent") +
" " + i18nextko.t("dependents.DependentInformation");
}, this);
// For option 2
this.showLeft = ko.pureComputed(function() {
return !isMedium();
}, this);
this.showRight = ko.pureComputed(function() {
return !isSmall();
}, this);
}
// Mock
var i18nextko = {
t: function(key) {
switch (key) {
case "dependents.editDependent":
return "Edit";
case "dependents.DependentInformation":
return "Dependent Information";
}
}
};
ko.bindingHandlers.i18n = {
init: function(e, valueAccessor) {
e.innerText = i18nextko.t(valueAccessor());
},
}
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<h2>Via computed</h2>
<div data-bind="text: translatedLabel"></div>
<h2>Via visible binding</h2>
<span data-bind="i18n: 'dependents.editDependent', visible: showLeft"></span>
<span data-bind="i18n: 'dependents.DependentInformation', visible: showRight"></span>
我很想知道为什么你宁愿在 javascript 中而不是在 HTML + CSS 中这样做...